Advertisement
GeeckoDev

moins degueu

Oct 1st, 2014
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.48 KB | None | 0 0
  1. #define _XOPEN_SOURCE 700
  2. #include <setjmp.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <signal.h>
  8.  
  9. //#define USE_ALARM
  10.  
  11. int sauvegarderProcessus(int idx);
  12. void commut();
  13.  
  14. /****************************************/
  15. /* Pour la commutation avec les signaux */
  16. /*          2eme partie du TP           */
  17. /****************************************/
  18.  
  19. #ifdef USE_ALARM
  20. #define MASK_ALARM()    sigprocmask(SIG_BLOCK, &mask_alarm, 0)
  21. #define UNMASK_ALARM()  sigprocmask(SIG_UNBLOCK, &mask_alarm, 0)
  22. #define delay 400000
  23.  
  24. sigset_t mask_alarm;
  25.  
  26. void handler_clock(int n) {
  27.     commut();
  28. }
  29.  
  30. void initSig() {
  31.     struct sigaction sa;
  32.  
  33.     sigemptyset(&mask_alarm);
  34.     sigaddset(&mask_alarm, SIGALRM);
  35.  
  36.     sigaction(SIGALRM, 0, &sa);
  37.     sa.sa_handler = handler_clock;
  38.     sa.sa_flags |= SA_RESTART;
  39.     sigaction(SIGALRM, &sa, 0);
  40.     ualarm(delay, delay);
  41. }
  42. #endif
  43.  
  44. /*************************/
  45. /* Gestion des processus */
  46. /*************************/
  47.  
  48. // On utilisera cette variable "globale" pour retenir l'adresse du haut de la pile
  49. char *top_stack;
  50.  
  51. // la dernière entrée du tableau (NPROC) est utilisée pour sauvegarder le main
  52. #define SNONE  0
  53. #define SSLEEP 1
  54. #define SRUN   2
  55. #define MAX_STACK_SIZE 2048
  56. #define NPROC 10
  57.  
  58. // Cette structure contient tous ce qui necessaire a la gestion d'un processus
  59. struct proc_s {
  60.     int       flag;
  61.     jmp_buf   buf;
  62.     char      stack[MAX_STACK_SIZE];
  63.     int       size;
  64. } ;
  65.  
  66. // La derniere entree du tableau (NPROC) est utilisee pour sauvegarder le main
  67. struct proc_s tproc[NPROC+1];
  68.  
  69. // Identifiant du processus courant
  70. int cur = -1;
  71.  
  72. int election(int old) {
  73.     // Cette fonction implemente un simple round robin :
  74.     // => les taches accedent au CPU les une après les autres sans se doubler
  75.     // => on cherche (circulairement) dans le tableau le prochain processus pret (SRUN)
  76.     // Valeur de retour :
  77.     // - index du processus elu qui doit etre a l'etat SRUN
  78.     // - NPROC (id du main) s'il n'y a plus de processus
  79.     //
  80.     // Attention : cette fonction de modifie pas la variable "cur".
  81.     // Elle ne fait que retourner l'index d'un processus.
  82.  
  83.     for (int i = (old + 1) % NPROC; i != old; i = (i + 1) % NPROC)
  84.         if (tproc[i].flag == SRUN)
  85.             return i;
  86.  
  87.     return NPROC;
  88. }
  89.  
  90. int new_proc(int (*nomFonction)(int), int argFonction) {
  91.  
  92.     // #####################################
  93.     // ############ A COMPLETER ############
  94.     // #####################################
  95.    
  96.     // Au demarrage :
  97.     // 1) chercher une entree libre dans la table proc
  98.     // 2) initialiser la structure
  99.     // 3) sauvegarder le processus
  100.     // 4) retourner 0
  101.     // Apres le retour :
  102.     // 1) demarrer la fonction
  103.     // Apres la fin de la foncton (fin du processus)
  104.     // 2) liberer l'entree (etat et desallocation pile)
  105.     // 3) forcer le commut pour laisser la place a un autre processus.
  106.  
  107.     int i;
  108.  
  109.     for (i = 0; i < NPROC; i++) {
  110.         if (tproc[i].flag == SNONE)
  111.             break;
  112.     }
  113.  
  114.     // pas d'entree libre dans la table
  115.     if (i >= NPROC) {
  116.         return -1;
  117.     }
  118.  
  119.     tproc[i].flag = SRUN; // FIXME
  120.  
  121.     if (sauvegarderProcessus(i) != 0) {
  122.         printf("launching %d\n", i);
  123.         nomFonction(argFonction);
  124.         tproc[i].flag = SNONE;
  125.         commut();
  126.     }
  127.  
  128.     return 0;
  129. }
  130.  
  131. /***************************************/
  132. /* Fonctions permettant la commutation */
  133. /***************************************/
  134.  
  135. int sauvegarderProcessus(int idx) {
  136.     printf("sauvegarderProcessus(%d)\n", idx);
  137.     // Lors de l'appel a la fonction :
  138.     // 1) sauvegarder la pile
  139.     // 2) sauvegarder de la taille de pile. Pourquoi la variable locale ne suffit pas ?
  140.     // 3) sauvegarder les registres
  141.     // 4) retourner 0
  142.    
  143.     // En cas de restauration :
  144.     // 1) restaurer la pile
  145.     // 2) UNMASK_ALARM() dans la deuxieme partie (avec les signaux)
  146.     // 3) retourne la valeur fournie par le longjmp
  147.    
  148.     char bs;
  149.     register int res;
  150.  
  151.     tproc[idx].size = top_stack - &bs;
  152.     memcpy(tproc[idx].stack, top_stack - tproc[idx].size, tproc[idx].size);
  153.  
  154.     if ((res = setjmp(tproc[idx].buf)) == 0)
  155.         return 0;
  156.     else {
  157. #ifdef USE_ALARM
  158.         UNMASK_ALARM();
  159. #endif
  160.         return res;
  161.     }
  162. }
  163.  
  164. int restaurerProcessus(int idx) {
  165.     printf("restaurerProcessus(%d)\n", idx);
  166.  
  167.     // 1) enregistre l'index du nouveau processus (idx) comme processus courant
  168.     // 2) lance la restauration des pointeurs
  169.     // ?) la restauration de la pile peut elle avoir lieu dans cette fonction ?
  170.     cur = idx;
  171.  
  172.     // force inlined memcpy to restore stack
  173.     // memcpy(top_stack - tproc[idx].size, tproc[idx].stack, tproc[idx].size);
  174.     for (register int i = 0; i < tproc[idx].size; i++)
  175.         ((char*)(top_stack - tproc[idx].size))[i] = ((char*)(tproc[idx].stack))[i];
  176.  
  177.     longjmp(tproc[idx].buf, 1);
  178. }
  179.  
  180. void commut() {
  181.     printf("commut()\n");
  182.  
  183. #ifdef USE_ALARM
  184.     MASK_ALARM();
  185. #endif
  186.  
  187.     if(sauvegarderProcessus(cur) == 0)
  188.         restaurerProcessus(election(cur));
  189. }
  190.  
  191. int f(int p) {
  192.     int n = 0;
  193.     int j;
  194.     for(j=0; j<15; j++) { // 20
  195.         printf("f(%d) -> %d\n", p, n++);
  196.         usleep(500000);
  197.  
  198. #ifndef USE_ALARM
  199.         commut();
  200. #endif
  201.     }
  202.     return 0;
  203. }
  204.  
  205. int g(int p) {
  206.     int n = 0;
  207.     int j;
  208.     for(j=0; j<12; j++) {// 50
  209.         printf("g(%d) -> %d\n", p, n++);
  210.         usleep(300000);
  211.  
  212. #ifndef USE_ALARM
  213.         if(j%2 == 0) commut();
  214. #endif
  215.     }
  216.     return 0;
  217. }
  218.  
  219. int main() {
  220.     char bs;
  221.     //  sauvegarder l'adresse du sommet de la pile dans la variable globale "top_stack"
  222.     top_stack = &bs;
  223.  
  224.     new_proc(g, 0);
  225.     new_proc(f, 4);
  226.  
  227.     // Comme explique plus haut le main a pour id NPROC (derniere case du
  228.     // tableau)
  229.     cur = NPROC;
  230.  
  231. #ifdef USE_ALARM
  232.     initSig();
  233. #endif
  234.     commut();
  235.  
  236.     printf("exit!!!\n");
  237.     return 0;
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement