Advertisement
davidbejenariu2

Untitled

Jan 9th, 2022
696
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.58 KB | None | 0 0
  1. // Structuri proiect
  2. struct Thread {
  3.     pid_t thread_id;
  4.     LIST_ENTRY(Thread) link;
  5. };
  6.  
  7. struct Mutex {
  8.     int descriptor;
  9.     bool is_locked;
  10.     bool is_threads_list_init;
  11.     LIST_HEAD(, Thread) waiting_threads_list;
  12.     LIST_ENTRY(Mutex) link;
  13.     pid_t wakeup_tid;
  14. };
  15.  
  16. struct Process {
  17.     pid_t process_id;
  18.     bool is_mutex_list_init;
  19.     LIST_HEAD(, Mutex) mutex_list;
  20.     LIST_ENTRY(Process) link;
  21. };
  22.  
  23. // Variabile proiect
  24. LIST_HEAD(, Process) process_list;
  25. bool is_process_list_init;
  26. int resource;
  27.  
  28. // 333  STD     { int sys_mtxlock(int d); }
  29. int sys_mtxlock(struct proc *p, void *v, register_t *retval) {
  30.     // Preluam argumentul d (descriptorul mutexului de blocat)
  31.     struct sys_mtxlock_args *uap = v;
  32.     int descriptor = SCARG(uap, d);
  33.  
  34.     // Lista de procese nu a fost initializata, facem ERRNO -1, deoarece
  35.     // s-a incercat un mtxlock() fara sa se fi facut vreun mtxopen()
  36.     if (!is_process_list_init) {
  37.         printf("Eroare mtxlock(): Nu s-a apelat niciun mtxopen() pentru a face mtxlock()!\n");
  38.  
  39.         *retval = -1;
  40.         return 0;
  41.     };
  42.  
  43.     // Cautam procesul curent in lista de procese
  44.     struct Process *process = NULL, *process_iterator;
  45.     LIST_FOREACH(process_iterator, &process_list, link) {
  46.         // p->p_p->ps_pid = pid-ul procesului
  47.         if (process_iterator->process_id == p->p_p->ps_pid) {
  48.             process = process_iterator;
  49.             break;
  50.         }
  51.     }
  52.  
  53.     // Nu exista niciun proces in lista de procese cu pid-ul procesului ce a
  54.     // apelat mtxlock => se incearca mtxlock() pe un proces ce nu are niciun mutex
  55.     if (process == NULL) {
  56.         printf("Eroare mtxlock(): Nu exista niciun mutex pentru acest proces!\n");
  57.  
  58.         *retval = -1;
  59.         return 0;
  60.     }
  61.  
  62.     // Cautam mutex-ul al carui descriptor l-am primit in lista de mutecsi a procesului
  63.     if (!(process->is_mutex_list_init)) {
  64.         printf("Eroare mtxlock(): Nu exista niciun mutex pentru acest proces!\n");
  65.  
  66.         *retval = -1;
  67.         return 0;
  68.     }
  69.  
  70.     struct Mutex *mutex = NULL, *mutex_iterator;
  71.     LIST_FOREACH(mutex_iterator, &(process->mutex_list), link) {
  72.         if (mutex_iterator->descriptor == descriptor) {
  73.             mutex = mutex_iterator;
  74.             break;
  75.         }
  76.     }
  77.  
  78.     // Nu am gasit mutex-ul cu descriptorul dat => procesul nu are niciun mutex
  79.     // cu descriptorul respectiv
  80.     if (mutex == NULL){
  81.         printf("Eroare mtxlock(): Nu s-a gasit mutex-ul cu descriptorul %d pentru procesul curent!\n", descriptor);
  82.  
  83.         *retval = -1;
  84.         return 0;
  85.     }
  86.  
  87.     // Adaugam thread-ul curent in lista de thread-uri in asteptare a mutexului
  88.     if (!(mutex->is_threads_list_init)) {
  89.         printf("Eroare mtxlock(): Nu exista niciun thread pentru acest proces!\n");
  90.  
  91.         *retval = -1;
  92.         return 0;
  93.     }
  94.  
  95.     struct Thread *thread = malloc(sizeof(struct Thread), M_TEMP, M_WAITOK);
  96.     thread->thread_id = p->p_tid;
  97.     LIST_INSERT_HEAD(&(mutex->waiting_threads_list), thread, link);
  98.     int error;
  99.  
  100.     // Punem thread-ul pe sleep pana cand primeste grant
  101.     while (true) {
  102.         error = tsleep(&resource, PSOCK | PCATCH, "awaiting lock", 0);
  103.  
  104.         if (error) {
  105.             LIST_REMOVE(thread, link);
  106.  
  107.             *retval = -1;
  108.             return error;
  109.         }
  110.  
  111.         if (mutex->wakeup_tid == p->p_tid) {
  112.             break;
  113.         }
  114.     }
  115.  
  116.     LIST_REMOVE(thread, link);
  117.  
  118.     *retval = 0;
  119.     return 0;
  120. }
  121.  
  122. // 334  STD     { int sys_mtxunlock(int d); }
  123. int sys_mtxunlock(struct proc *p, void *v, register_t *retval) {
  124.     // Preluam argumentul d (descriptorul mutexului de deblocat)
  125.     struct sys_mtxunlock_args *uap = v;
  126.     int descriptor = SCARG(uap, d);
  127.  
  128.     // Lista de procese nu a fost initializata, facem ERRNO -1, deoarece
  129.     // s-a incercat un mtxunlock() fara sa se fi facut vreun mtxopen()
  130.     if (!is_process_list_init) {
  131.         printf("Eroare mtxunlock(): Nu s-a apelat niciun mtxopen() pentru a face mtxunlock()!\n");
  132.  
  133.         *retval = -1;
  134.         return 0;
  135.     };
  136.  
  137.     // Cautam procesul curent in lista de procese
  138.     struct Process *process = NULL, *process_iterator;
  139.     LIST_FOREACH(process_iterator, &process_list, link) {
  140.         // p->p_p->ps_pid = pid-ul procesului
  141.         if (process_iterator->process_id == p->p_p->ps_pid) {
  142.             process = process_iterator;
  143.             break;
  144.         }
  145.     }
  146.  
  147.     // Nu exista niciun proces in lista de procese cu pid-ul procesului ce a
  148.     // apelat mtxunlock => se incearca mtxunlock() pe un proces ce nu are niciun mutex
  149.     if (process == NULL) {
  150.         printf("Eroare mtxunlock(): Nu exista niciun mutex pentru acest proces!\n");
  151.  
  152.         *retval = -1;
  153.         return 0;
  154.     }
  155.  
  156.     // Cautam mutex-ul al carui descriptor l-am primit in lista de mutecsi a procesului
  157.     if (!(process->is_mutex_list_init)) {
  158.         printf("Eroare mtxunlock(): Nu exista niciun mutex pentru acest proces!\n");
  159.  
  160.         *retval = -1;
  161.         return 0;
  162.     }
  163.  
  164.     struct Mutex *mutex = NULL, *mutex_iterator;
  165.     LIST_FOREACH(mutex_iterator, &(process->mutex_list), link) {
  166.         if (mutex_iterator->descriptor == descriptor) {
  167.             mutex = mutex_iterator;
  168.             break;
  169.         }
  170.     }
  171.  
  172.     // Nu am gasit mutex-ul cu descriptorul dat => procesul nu are niciun mutex
  173.     // cu descriptorul respectiv
  174.     if (mutex == NULL){
  175.         printf("Eroare mtxunlock(): Nu s-a gasit mutex-ul cu descriptorul %d pentru procesul curent!\n", descriptor);
  176.  
  177.         *retval = -1;
  178.         return 0;
  179.     }
  180.  
  181.     mutex->is_locked = false;
  182.  
  183.     *retval = 0;
  184.     return 0;
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement