#include "../h/asl.h" static semd_t* semdFree_h; // free semd_t* semd_h; // active static semd_t semdTable[MAXPROC + 2]; /* * Function: insertBlocked * -------------------- * Insert the PCB pointed to by p at the tail of the process queue * associated with the semaphore whose physical address is semAdd * and set the semaphore address of p to semdAdd. * * semAdd: pointer to semaphore value * p: pointer to PCB * * returns: returns 1 if semaphore is not in ASL and semdFree is empty * returns 0 otherwise */ int insertBlocked(int *semAdd, pcb_t *p) { int found = 0; semd_t* current = semd_h; while(current->s_semAdd <= semAdd){ if(current->s_semAdd == semAdd){ found = 1; break; } current = current->s_next; } if (found) { // Semaphore found in ASL insertProcQ(&(current->s_procQ), p); } else { // Semaphore not found in ASL if(semdFree_h == NULL){ return 1; } // Get new semaphore from head of free list semd_t* semNew = semdFree_h; semdFree_h = semdFree_h->s_next; // Place new semaphore in ASL semd_t* current = semd_h; while(current->s_next->s_semAdd <= semAdd) { current = current->s_next; } semNew->s_next = current->s_next; current->s_next = semNew; semNew->s_semAdd = semAdd; semNew->s_procQ = mkEmptyProcQ(); insertProcQ(&(semNew->s_procQ), p); } p->p_semAdd = semAdd; return 0; } /* * Function: removeBlocked * -------------------- * Removes the first PCB from the process queue of the semaphore. * * semAdd: pointer to semaphore value * * returns: returns pointer to PCB removed if semaphore found * returns NULL otherwise */ pcb_t* removeBlocked(int *semAdd) { int found = 0; semd_t* prev = NULL; semd_t* current = semd_h; while(current->s_semAdd <= semAdd){ if(current->s_semAdd == semAdd){ found = 1; break; } prev = current; current = current->s_next; } if(!found){ // Semaphore is not found in ASL return NULL; } // Remove the first PCB from process queue pcb_t* removed = removeProcQ(&(current->s_procQ)); if(emptyProcQ(current->s_procQ)){ // Process queue is empty, remove the semaphore from ASL if (prev != NULL) { prev->s_next = current->s_next; } else { return removed; } // Return the semaphore to the free list current->s_next = semdFree_h; semdFree_h = current; } return removed; } /* * Function: outBlocked * -------------------- * Remove the PCB pointed to by p from the process queue associate with * p's semaphore (p -> p_semAdd) on the ASL. * * p: pointer to PCB * * returns: returns pointer to PCB removed if semaphore found and p * if found in the process queue * returns NULL otherwise */ pcb_t* outBlocked(pcb_t *p) { int found = 0; semd_t* prev = NULL; semd_t* current = semd_h; while(current->s_semAdd <= p->p_semAdd){ if(current->s_semAdd == p->p_semAdd){ found = 1; break; } prev = current; current = current->s_next; } if(!found){ // Semaphore not found in ASl return NULL; } pcb_t* result = outProcQ(&(current->s_procQ), p); if(result == NULL){ return result; } p->p_semAdd = NULL; if(emptyProcQ(current->s_procQ)){ // Process queue is empty, remove the semaphore from ASL if (prev != NULL) { prev->s_next = current->s_next; } else { return result; } // Return the semaphore to the free list current->s_next = semdFree_h; semdFree_h = current; } return result; } /* * Function: headBlocked * -------------------- * Return (without removal) a pointer to the PCB that is at the head * head of the process queue associated with the semaphore semAdd. * * p: pointer to PCB * * returns: returns pointer to PCB at the head of the process queue if * semAdd found and the queue is non-empty * returns NULL otherwise */ pcb_t* headBlocked(int *semAdd) { int found = 0; semd_t* current = semd_h; while(current->s_semAdd <= semAdd){ if(current->s_semAdd == semAdd){ found = 1; break; } current = current->s_next; } if(!found){ // Semaphore not found in ASL return NULL; } if(current->s_procQ == NULL){ // Semaphore has empty process queue return NULL; } return current->s_procQ->p_next; } /* * Function: initASL * -------------------- * Initialize the semdFree list to contain all the elements of * the array. * */ void initASL() { // Free list semdFree_h = &semdTable[1]; for(int i = 1; i< MAXPROC; i++){ semdTable[i].s_next = &semdTable[i+1]; } semdTable[MAXPROC].s_next = NULL; // Active list semd_h = &semdTable[0]; // head semd_h->s_procQ = NULL; semd_h->s_semAdd = (int*) 0x00000000; // tail semd_h->s_next = &semdTable[MAXPROC+1]; semd_h->s_next->s_procQ = NULL; semd_h->s_next->s_semAdd = (int*) 0xFFFFFFFF; semd_h->s_next->s_next = NULL; }