Advertisement
Jobjob

ITR - Examen 01/2014 Q3 - "MiniOs"

Jan 20th, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.05 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/ipc.h>
  4. #include <sys/shm.h>
  5.  
  6. #include <pthread.h>
  7.  
  8. #define STATE_FREE 0
  9. #define STATE_WAITING 1
  10. #define STATE_DOING 2
  11. #define STATE_FINISHED 3
  12. #define SHARED_MEM_KEY 4242
  13.  
  14. void clean();
  15. void *thread_behavior();
  16. void *thread_cmd_behavior();
  17.  
  18. typedef struct{
  19.     int id;
  20.     int duration;
  21.     int state; // 0 - free, 1 - waiting, 2 - doing, 3 - finished
  22. }process_t;
  23.  
  24. int current_id;
  25. int slots_number;
  26. process_t *slots = NULL;
  27. pthread_t *threads = NULL;
  28. pthread_t cmd_thread = NULL;
  29. pthread_mutex_t *threads_mutex = NULL;
  30. pthread_mutex_t *state_mutex = NULL;
  31. int shmid = -1;
  32.  
  33. int main(int argc, char *argv[]){
  34.     if(argc < 3){
  35.         printf("Usage: %s threads slots\n", argv[0]);
  36.         exit(-1);
  37.     }
  38.     // Get args from cmd
  39.     int threads_number = atoi(argv[1]);
  40.     slots_number = atoi(argv[2]);
  41.     printf("threads=%d,  slots=%d\n", threads_number, slots_number);
  42.  
  43.     // Create the slots array (shared memory)
  44.     shmid = shmget(SHARED_MEM_KEY, slots_number * sizeof(process_t), IPC_CREAT|0660);
  45.     current_id = 0;
  46.     slots = (process_t *)shmat(shmid, NULL, SHM_R|SHM_W); //malloc(slots_number * sizeof(process_t));
  47.     if(slots == NULL){
  48.         perror("Error while malloc.\n");
  49.         clean();
  50.         exit(-1);
  51.     }
  52.     int j;
  53.     for(j=0; j<slots_number; j++){
  54.         slots[j].state = STATE_FREE;
  55.     }
  56.  
  57.     // Initialize mutex
  58.     threads_mutex = (pthread_mutex_t *)malloc(slots_number * sizeof(pthread_mutex_t));
  59.     if(threads_mutex == NULL){
  60.         perror("Error while malloc.\n");
  61.         clean();
  62.         exit(-1);
  63.     }
  64.     for(j=0; j<slots_number; j++){
  65.         if(pthread_mutex_init(&threads_mutex[j], NULL) == -1){
  66.             perror("Error while creating mutex.\n");
  67.             clean();
  68.             exit(-1);
  69.         }
  70.     }
  71.     state_mutex = (pthread_mutex_t *)malloc(slots_number * sizeof(pthread_mutex_t));
  72.     if(threads_mutex == NULL){
  73.         perror("Error while malloc.\n");
  74.         clean();
  75.         exit(-1);
  76.     }
  77.     for(j=0; j<slots_number; j++){
  78.         if(pthread_mutex_init(&state_mutex[j], NULL) == -1){
  79.             perror("Error while creating mutex.\n");
  80.             clean();
  81.             exit(-1);
  82.         }
  83.     }
  84.     printf("Mutex created.\n");
  85.  
  86.     // Fork
  87.     pid_t son_pid = fork();
  88.  
  89.     if(son_pid == -1){
  90.         perror("Error while forking\n");
  91.         clean();
  92.         exit(-1);
  93.     } else if(son_pid == 0){ // son
  94.         int i;
  95.         int memid = shmget(SHARED_MEM_KEY, slots_number * sizeof(process_t), 0660);
  96.         process_t *slots_to_read = (process_t *)shmat(memid, NULL, SHM_R);
  97.         while(1){
  98.             for(i=0; i<slots_number; i++){
  99.                 printf("Slot %d in state %d\n", i, slots_to_read[i].state);
  100.             }
  101.             sleep(3);
  102.         }
  103.     } else{ // father
  104.         // Create and start slots checker threads
  105.         int k;
  106.         threads = (pthread_t *)malloc(threads_number*sizeof(pthread_t));
  107.         if(threads == NULL){
  108.             perror("Error while malloc.\n");
  109.             clean();
  110.             exit(-1);
  111.         }
  112.         for(k=0; k<threads_number; k++){
  113.             pthread_create(&threads[k], NULL, thread_behavior, NULL);
  114.         }
  115.         printf("Threads created: %d\n", threads_number);
  116.  
  117.         // Create and start cmd thread
  118.         pthread_create(&cmd_thread, NULL, thread_cmd_behavior, NULL);
  119.  
  120.         pause();
  121.     }
  122.  
  123. }
  124.  
  125. void clean(){
  126.     if(shmid != -1)
  127.         shmctl(shmid, IPC_RMID, NULL);
  128.         // free(slots);
  129.     if(threads != NULL)
  130.         free(threads);
  131.     if(threads_mutex != NULL)
  132.         free(threads_mutex);
  133.     if(state_mutex != NULL)
  134.         free(threads_mutex);
  135. }
  136.  
  137. void *thread_behavior(){
  138.     int i;
  139.     while(1){
  140.         for(i=0; i<slots_number; i++){
  141.             int locked = 0;
  142.             if(pthread_mutex_lock(&state_mutex[i]) != 0){
  143.                 perror("Error while locking.\n");
  144.             }
  145.             locked = 1;
  146.             if(slots[i].state == STATE_WAITING){
  147.                 if(pthread_mutex_lock(&threads_mutex[i]) != 0){
  148.                     perror("Error while locking.\n");
  149.                 }
  150.                 // printf("Founded a task to execute slot=%d, id=%d.\n", i, slots[i].id);
  151.                 slots[i].state = STATE_DOING;
  152.                 if(pthread_mutex_unlock(&state_mutex[i]) != 0){
  153.                     perror("Error while unlocking.\n");
  154.                 }
  155.                 locked = 0;
  156.                 sleep(slots[i].duration);
  157.                 // printf("Task %d finished.\n", slots[i].id);
  158.                 slots[i].state = STATE_FINISHED;
  159.                 if(pthread_mutex_unlock(&threads_mutex[i]) != 0){
  160.                     perror("Error while unlocking.\n");
  161.                 }
  162.             }
  163.             if(locked == 1){
  164.                 if(pthread_mutex_unlock(&state_mutex[i]) != 0){
  165.                     perror("Error while unlocking.\n");
  166.                 }
  167.             }
  168.         }
  169.     }
  170. }
  171.  
  172. void *thread_cmd_behavior(){
  173.     while(1){
  174.         int duration;
  175.         printf("Enter the duration of a task (-1 to quit): ");
  176.         scanf("%d", &duration);
  177.         if(duration == -1){
  178.             clean();
  179.             exit(0);
  180.         } else{
  181.             int i;
  182.             int slot_founded = 0;
  183.             do{
  184.                 for(i=0; i<slots_number; i++){
  185.                     if(slots[i].state == STATE_FREE || slots[i].state == STATE_FINISHED){
  186.                         current_id++;
  187.                         slots[i].id = current_id;
  188.                         slots[i].duration = duration;
  189.                         slots[i].state = STATE_WAITING;
  190.                         printf("Task created in slot %d with id=%d and duration=%d.\n", i, slots[i].id, slots[i].duration);
  191.                         slot_founded = 1;
  192.                         break;
  193.                     }
  194.                 }
  195.                 if(!slot_founded){
  196.                     printf("Slot not founded, retrying in 1 sec.\n");
  197.                     sleep(1);
  198.                 }
  199.             }while(!slot_founded);
  200.         }
  201.     }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement