#include "h/const.h" #include "h/types.h" #include "e/libumps.e" #include "e/pcb.e" /* semaphore descriptor type */ typedef struct semd_t { struct semd_t *s_next; /* next element on the ASL */ int *s_semAdd; /* pointer to the semaphore*/ pcb_t *s_procQ; /* tail pointer to a */ /* process queue */ } semd_t; HIDDEN semd_t *semd_h; HIDDEN semd_t *semdFree_h; int insertBlocked(int *semAdd, pcb_t *p); pcb_t *removeBlocked(int *semAdd); pcb_t *outBlocked(pcb_t *p); pcb_t *headBlocked(int *semAdd); void initASL(); int insertBlocked(int *semAdd, pcb_t *p) { semd_t *curr = semd_h; semd_t *prev = NULL; semd_t *n; while (curr != NULL) { if (curr->s_semAdd == semAdd) { p->p_semAdd = semAdd; insertProcQ(&(curr->s_procQ), p); return FALSE; } prev = curr; curr = curr->s_next; } if (semdFree_h == NULL) return TRUE; else { n = semdFree_h; semdFree_h = semdFree_h->s_next; n->s_semAdd = semAdd; n->s_procQ = mkEmptyProcQ(); insertProcQ(&(n->s_procQ), p); p->p_semAdd = semAdd; if (prev == NULL) { n->s_next = NULL; semd_h = n; } else { n->s_next = curr; prev->s_next = n; } return FALSE; } } pcb_t *removeBlocked(int *semAdd) { semd_t *curr = semd_h; semd_t *prev = NULL; pcb_t *h; while (curr != NULL) { if (curr->s_semAdd == semAdd) { h = outProcQ(&(curr->s_procQ), headProcQ(curr->s_procQ)); if (emptyProcQ(curr->s_procQ)) { if (prev != NULL) prev->s_next = curr->s_next; else semd_h = curr->s_next; curr->s_next = semdFree_h; semdFree_h = curr; } return h; } prev = curr; curr = curr->s_next; } return NULL; } pcb_t *outBlocked(pcb_t *p) { semd_t *curr = semd_h; semd_t *prev = NULL; pcb_t *ret; while (curr != NULL) { if (curr->s_semAdd == p->p_semAdd) { ret = outProcQ(&(curr->s_procQ), p); if (emptyProcQ(curr->s_procQ)) { if (prev != NULL) prev->s_next = curr->s_next; else semd_h = curr->s_next; curr->s_next = semdFree_h; semdFree_h = curr; } return ret; } prev = curr; curr = curr->s_next; } return NULL; } pcb_t *headBlocked(int *semAdd) { semd_t *curr = semd_h; while (curr != NULL) { if (curr->s_semAdd == semAdd) { return headProcQ(curr->s_procQ); } curr = curr->s_next; } return NULL; } void initASL() { int i = 0; static semd_t semdTable[MAXPROC]; semdFree_h = NULL; semd_h = NULL; for (i = 0; i < MAXPROC; i++) { semdTable[i].s_next = semdFree_h; semdFree_h = &(semdTable[i]); } }