diff --git a/cours/signaux.pdf b/cours/signaux.pdf new file mode 100644 index 0000000..48c5ed0 Binary files /dev/null and b/cours/signaux.pdf differ diff --git a/td/td4/td4.pdf b/td/td4/td4.pdf new file mode 100644 index 0000000..cd23cb3 Binary files /dev/null and b/td/td4/td4.pdf differ diff --git a/tp/tp1/src/ex3/buf b/tp/tp1/src/ex3/buf new file mode 100755 index 0000000..f04eb2a Binary files /dev/null and b/tp/tp1/src/ex3/buf differ diff --git a/tp/tp1/src/ex3/buf.c b/tp/tp1/src/ex3/buf.c index 3530209..04c17f0 100644 --- a/tp/tp1/src/ex3/buf.c +++ b/tp/tp1/src/ex3/buf.c @@ -1,9 +1,15 @@ #include "helpers.h" - +#include static char buf[16 MB] = {0}; int main(int argc, char **argv) { - randomize(buf, 16 MB); + buf[0] = 12; + long int ad; + printf("buf = %p\n",buf); + ad = (long int)buf; + ad = (ad & 0xfffffffff000) + 0x1000 - ad ; + buf[ad - 1] = 13; + //randomize(buf, 16 MB); return interlude(); } diff --git a/tp/tp1/src/ex3/heap b/tp/tp1/src/ex3/heap new file mode 100755 index 0000000..d442645 Binary files /dev/null and b/tp/tp1/src/ex3/heap differ diff --git a/tp/tp1/src/ex3/huge b/tp/tp1/src/ex3/huge new file mode 100755 index 0000000..982f3fd Binary files /dev/null and b/tp/tp1/src/ex3/huge differ diff --git a/tp/tp1/src/ex3/mmap b/tp/tp1/src/ex3/mmap new file mode 100755 index 0000000..7846767 Binary files /dev/null and b/tp/tp1/src/ex3/mmap differ diff --git a/tp/tp1/src/ex3/null b/tp/tp1/src/ex3/null new file mode 100755 index 0000000..223efc1 Binary files /dev/null and b/tp/tp1/src/ex3/null differ diff --git a/tp/tp1/src/ex3/stack b/tp/tp1/src/ex3/stack new file mode 100755 index 0000000..1dc804a Binary files /dev/null and b/tp/tp1/src/ex3/stack differ diff --git a/tp/tp4/README.md b/tp/tp4/README.md new file mode 100644 index 0000000..342f633 --- /dev/null +++ b/tp/tp4/README.md @@ -0,0 +1,167 @@ +# Signaux + +>sources à compléter dans le repertoire [src](./src) + +#### Ex1 +Pour calculer le nombre \\(\pi\\), on utilise la méthode de Monte-Carlo. +On tire aléatoirement des couples \\((x,y)\\) de nombres de +\\([0,1]\times[0,1]\\). La probabilité qu'il tombe dans le disque de +rayon 1 est exactement de \\(\frac{\pi}{4}\\). On procède à plusieurs +tirages pour estimer la probabilité correspondante. + +```c +uint64_t shots_in=0,shots=0; +double x,y; + +int main(int argc, char **argv) +{ + shots_in = 0; + shots = 0; + for (;;){ + x = rand()/(RAND_MAX*1.0); + y = rand()/(RAND_MAX*1.0); + shots ++; + if ((x*x+y*y)<=1){ + shots_in ++; + } + } + /* la probabilité vaut tirsIn/tirs, + Elle converge lentement vers pi/4*/ +} +``` + +En utilisant les signaux, mettre en place : + + - avec `SIGALRM`, toutes les 5 secondes, l'affichage de la valeur + de pi en cours et le nombre de tirs effectués. + - avec `SIGINT` l'arrêt du programme (après la demande d'une + confirmation), avec l'affichage du temps écoulé depuis son + lancement, quand on fait `ctrl+C` au terminal. + - avec `SIGQUIT` la réinitialisation du calcul avec `ctrl+\` + depuis le terminal. (faites en sorte que toutes les valeurs restent cohérentes) + +Dans chaque handler, les 2 autres signaux seront bloqués. + + +#### Ex2 +Écrire un programme `mytimeout.c` dont l'usage est + +```bash +$mytimeout nbsec com [arg ...] +``` + + - Il lance la commande `com [arg ...]` (fork-and-exec). + - Il attend `nbsec` secondes, ou la fin de son fils. + - Si la commande n'est pas encore terminée au bout de du temps, il lui envoie le signal + `SIGTERM`. + +En cas de terminaison de la commande, il renvoie son code de retour, sinon renvoie le code +124. + + +#### Ex3 + +Le but est de protéger un morceau de code (**section critique**) d'un éventuellement +déroutement à cause de la prise en compte d'un signal. + +```c +int x=2,y=3; +int swap(int *x,int *y){ + int tmp=*x; + *x=*y; + *y=tmp; +} + +void sig_handler(int signo){ + switch(signo){ + case SIGQUIT : + printf("x=%d y=%d\n",x,y); + break; + } +} + +int main(int argc,char * argv[]){ + + assert(set_signal_handler(SIGQUIT,sig_handler)==0); + while(1){ + swap(&x,&y); + } +} +``` + +1. Lancez le programme, et envoyez (depuis le terminal) le signal SIGQUIT souvent. La fonction + `swap` est-elle interrompue ? comment le voyez-vous ? +2. Ajoutez le code nécessaire pour assurer que `swap` ne soit jamais interrompue par `SIGQUIT`. + +#### Ex4 +On va simuler un match de **ping-pong** entre un père et son fils, en utilisant le signal `SIGUSR1`. + - Le père commence à jouer. + - On simule 10 échanges. À chaque coup, le père affiche Ping, le fils Pong. L'envoie de la balle + consiste à envoyer le signal `SIGUSR1` à son adversaire. + +La difficulté consiste à synchroniser correctement les échanges. + +Voici un premier code naïf : +```c +#include +#include +#include +#include +#include +#include +#include + +#define N 10 +void sig_hand(int sig) {} + +sigset_t saveMask, blockMask; + +void player_wait(){ + pause(); +} +void child_process() +{ + int x = 0; + while(x < N) + { + player_wait(); + printf("\tPong %d!\n", ++x); + kill(getppid(), SIGUSR1); + } + return ; +} + +void parent_process(pid_t pid) +{ + int y = 0; + while (y < N) + { + printf("Ping %d!\n", ++y); + kill(pid, SIGUSR1); + player_wait(); + } + return ; +} + +int main(int argc, char* argv[]) +{ + //set up signal handler for parent & child + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = sig_hand; + + assert (sigaction(SIGUSR1, &sa, NULL) != -1); + + pid_t pid = fork(); + + if (pid == 0) + child_process(); + else + parent_process(pid); + return 0; +} +``` + +1. Expliquez pourquoi ce code n'est pas correct (Faites varier `N`). +2. Proposez une solution. diff --git a/tp/tp4/src/helpers.c b/tp/tp4/src/helpers.c new file mode 100644 index 0000000..718fe40 --- /dev/null +++ b/tp/tp4/src/helpers.c @@ -0,0 +1,19 @@ +#include "helpers.h" +#include +#include + +int set_signal_handler(int signo, void (*handler)(int)) { + struct sigaction sa; + sa.sa_handler = handler; // call `handler` on signal + sigemptyset(&sa.sa_mask); // don't block other signals in handler + sa.sa_flags = SA_RESTART; // restart system calls + return sigaction(signo, &sa, NULL); +} + +double tstamp(void) { + struct timespec tv; + clock_gettime(CLOCK_REALTIME, &tv); + return tv.tv_sec + tv.tv_nsec * 1.0e-9; +} + + diff --git a/tp/tp4/src/helpers.h b/tp/tp4/src/helpers.h new file mode 100644 index 0000000..2084c6a --- /dev/null +++ b/tp/tp4/src/helpers.h @@ -0,0 +1,7 @@ +#ifndef _HELPERS_H +#define _HELPERS_H + +int set_signal_handler(int signo, void (*handler)(int)); +double tstamp(void); + +#endif diff --git a/tp/tp4/src/pi.c b/tp/tp4/src/pi.c new file mode 100644 index 0000000..08856a5 --- /dev/null +++ b/tp/tp4/src/pi.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include +#include "helpers.h" + + +uint64_t shots = 0, + shots_in = 0; + +double pi = 0, + t1; + +int main(int argc,char * argv[]) +{ + double x,y; + t1 = tstamp(); + + alarm(5); + + while(1){ + x = ((double)rand())/(double)RAND_MAX; + y = ((double)rand())/(double)RAND_MAX; + shots ++; + + if ((x*x+y*y) <= 1) + shots_in ++; + } +} diff --git a/tp/tp4/src/ping_pong.c b/tp/tp4/src/ping_pong.c new file mode 100644 index 0000000..2ae839a --- /dev/null +++ b/tp/tp4/src/ping_pong.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include + +#define N 10000 +void sig_hand(int sig) {} + +sigset_t saveMask, blockMask; + +void player_wait(){ + pause(); +} +void child_process() +{ + int x = 0; + while(x < N) + { + player_wait(); + printf("\tPong %d!\n", ++x); + kill(getppid(), SIGUSR1); + } + return ; +} + +void parent_process(pid_t pid) +{ + int y = 0; + while (y < N) + { + printf("Ping %d!\n", ++y); + kill(pid, SIGUSR1); + player_wait(); + } + return ; +} + +int main(int argc, char* argv[]) +{ + //set up signal handler for parent & child + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = sig_hand; + + assert (sigaction(SIGUSR1, &sa, NULL) != -1); + + pid_t pid = fork(); + + if (pid == 0) + child_process(); + else + parent_process(pid); + return 0; +} diff --git a/tp/tp4/src/section_critique.c b/tp/tp4/src/section_critique.c new file mode 100644 index 0000000..04725f4 --- /dev/null +++ b/tp/tp4/src/section_critique.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include "helpers.h" + + +int x=2,y=3; + +int swap(int *x,int *y) +{ + int tmp=*x; + *x=*y; + *y=tmp; +} + +void sig_handler(int signo) +{ + switch(signo){ + case SIGQUIT : + printf("x=%d y=%d\n",x,y); + break; + } +} + +int main(int argc,char * argv[]) +{ + assert(set_signal_handler(SIGQUIT,sig_handler)==0); + while(1){ + swap(&x,&y); + } +}