Advertisement
GeeckoDev

degueu

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