Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Structuri proiect
- struct Thread {
- pid_t thread_id;
- LIST_ENTRY(Thread) link;
- };
- struct Mutex {
- int descriptor;
- bool is_locked;
- bool is_threads_list_init;
- LIST_HEAD(, Thread) waiting_threads_list;
- LIST_ENTRY(Mutex) link;
- pid_t wakeup_tid;
- };
- struct Process {
- pid_t process_id;
- bool is_mutex_list_init;
- LIST_HEAD(, Mutex) mutex_list;
- LIST_ENTRY(Process) link;
- };
- // Variabile proiect
- LIST_HEAD(, Process) process_list;
- bool is_process_list_init;
- int resource;
- // 333 STD { int sys_mtxlock(int d); }
- int sys_mtxlock(struct proc *p, void *v, register_t *retval) {
- // Preluam argumentul d (descriptorul mutexului de blocat)
- struct sys_mtxlock_args *uap = v;
- int descriptor = SCARG(uap, d);
- // Lista de procese nu a fost initializata, facem ERRNO -1, deoarece
- // s-a incercat un mtxlock() fara sa se fi facut vreun mtxopen()
- if (!is_process_list_init) {
- printf("Eroare mtxlock(): Nu s-a apelat niciun mtxopen() pentru a face mtxlock()!\n");
- *retval = -1;
- return 0;
- };
- // Cautam procesul curent in lista de procese
- struct Process *process = NULL, *process_iterator;
- LIST_FOREACH(process_iterator, &process_list, link) {
- // p->p_p->ps_pid = pid-ul procesului
- if (process_iterator->process_id == p->p_p->ps_pid) {
- process = process_iterator;
- break;
- }
- }
- // Nu exista niciun proces in lista de procese cu pid-ul procesului ce a
- // apelat mtxlock => se incearca mtxlock() pe un proces ce nu are niciun mutex
- if (process == NULL) {
- printf("Eroare mtxlock(): Nu exista niciun mutex pentru acest proces!\n");
- *retval = -1;
- return 0;
- }
- // Cautam mutex-ul al carui descriptor l-am primit in lista de mutecsi a procesului
- if (!(process->is_mutex_list_init)) {
- printf("Eroare mtxlock(): Nu exista niciun mutex pentru acest proces!\n");
- *retval = -1;
- return 0;
- }
- struct Mutex *mutex = NULL, *mutex_iterator;
- LIST_FOREACH(mutex_iterator, &(process->mutex_list), link) {
- if (mutex_iterator->descriptor == descriptor) {
- mutex = mutex_iterator;
- break;
- }
- }
- // Nu am gasit mutex-ul cu descriptorul dat => procesul nu are niciun mutex
- // cu descriptorul respectiv
- if (mutex == NULL){
- printf("Eroare mtxlock(): Nu s-a gasit mutex-ul cu descriptorul %d pentru procesul curent!\n", descriptor);
- *retval = -1;
- return 0;
- }
- // Adaugam thread-ul curent in lista de thread-uri in asteptare a mutexului
- if (!(mutex->is_threads_list_init)) {
- printf("Eroare mtxlock(): Nu exista niciun thread pentru acest proces!\n");
- *retval = -1;
- return 0;
- }
- struct Thread *thread = malloc(sizeof(struct Thread), M_TEMP, M_WAITOK);
- thread->thread_id = p->p_tid;
- LIST_INSERT_HEAD(&(mutex->waiting_threads_list), thread, link);
- int error;
- // Punem thread-ul pe sleep pana cand primeste grant
- while (true) {
- error = tsleep(&resource, PSOCK | PCATCH, "awaiting lock", 0);
- if (error) {
- LIST_REMOVE(thread, link);
- *retval = -1;
- return error;
- }
- if (mutex->wakeup_tid == p->p_tid) {
- break;
- }
- }
- LIST_REMOVE(thread, link);
- *retval = 0;
- return 0;
- }
- // 334 STD { int sys_mtxunlock(int d); }
- int sys_mtxunlock(struct proc *p, void *v, register_t *retval) {
- // Preluam argumentul d (descriptorul mutexului de deblocat)
- struct sys_mtxunlock_args *uap = v;
- int descriptor = SCARG(uap, d);
- // Lista de procese nu a fost initializata, facem ERRNO -1, deoarece
- // s-a incercat un mtxunlock() fara sa se fi facut vreun mtxopen()
- if (!is_process_list_init) {
- printf("Eroare mtxunlock(): Nu s-a apelat niciun mtxopen() pentru a face mtxunlock()!\n");
- *retval = -1;
- return 0;
- };
- // Cautam procesul curent in lista de procese
- struct Process *process = NULL, *process_iterator;
- LIST_FOREACH(process_iterator, &process_list, link) {
- // p->p_p->ps_pid = pid-ul procesului
- if (process_iterator->process_id == p->p_p->ps_pid) {
- process = process_iterator;
- break;
- }
- }
- // Nu exista niciun proces in lista de procese cu pid-ul procesului ce a
- // apelat mtxunlock => se incearca mtxunlock() pe un proces ce nu are niciun mutex
- if (process == NULL) {
- printf("Eroare mtxunlock(): Nu exista niciun mutex pentru acest proces!\n");
- *retval = -1;
- return 0;
- }
- // Cautam mutex-ul al carui descriptor l-am primit in lista de mutecsi a procesului
- if (!(process->is_mutex_list_init)) {
- printf("Eroare mtxunlock(): Nu exista niciun mutex pentru acest proces!\n");
- *retval = -1;
- return 0;
- }
- struct Mutex *mutex = NULL, *mutex_iterator;
- LIST_FOREACH(mutex_iterator, &(process->mutex_list), link) {
- if (mutex_iterator->descriptor == descriptor) {
- mutex = mutex_iterator;
- break;
- }
- }
- // Nu am gasit mutex-ul cu descriptorul dat => procesul nu are niciun mutex
- // cu descriptorul respectiv
- if (mutex == NULL){
- printf("Eroare mtxunlock(): Nu s-a gasit mutex-ul cu descriptorul %d pentru procesul curent!\n", descriptor);
- *retval = -1;
- return 0;
- }
- mutex->is_locked = false;
- *retval = 0;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement