int test_outProcQ(void) { int success = 1; pcb_t *p1, *p2, *p3; pcbq_t *q; initProc(); q = mkEmptyProcQ(); p1 = allocPcb(); p2 = allocPcb(); p3 = allocPcb(); success &= outProcQ(NULL, p1) == NULL; success &= outProcQ(&q, NULL) == NULL; success &= outProcQ(&q, p1) == NULL; success &= outProcQ(&q, p2) == NULL; success &= outProcQ(&q, p3) == NULL; insertProcQ(&q, p1); insertProcQ(&q, p2); success &= outProcQ(&q, p3) == NULL; insertProcQ(&q, p3); success &= outProcQ(&q, p3) == p3; success &= outProcQ(&q, p1) == p1; success &= removeProcQ(&q) == p2; return success; }
/*TerminatePcb si preoccupa di terminare ricorsivamente tutta la progenie di p, root dell'albero di processi*/ void terminatePcb(pcb_t *p){ semd_t* semd; if(p->p_first_child != NULL) terminatePcb(p->p_first_child); if(p->p_first_child == NULL && p->p_sib != NULL) terminatePcb(p->p_sib); if(p->p_first_child == NULL && p->p_sib == NULL){ lock(MUTEX_SCHEDULER); if(outBlocked(p)){ /*Rimuovo p dalla coda dei processi del suo semaforo*/ lessSoftCounter(); /*Decremento il softBlock counter*/ semd = getSemd(p->p_semkey); /*Se p è bloccato su un semaforo di un device, non incremento il value. Sarà l'interrupt a farlo*/ if(!checkSemaphore(p)) (*semd->s_key)++; } /*Tolgo p dalla ReadyQueue, se presente*/ outProcQ(&ready_queue[getPRID()], p); outChild(p); freePcb(p); unlock(MUTEX_SCHEDULER); } }
/* Remove the procBlc pointed by p */ pcb_t *outBlocked (pcb_t *p){ semd_t *tmp = semd_h->s_next; semd_t *prec = semd_h; /* Search for the semaphore descriptor equals to semaaphore value of p */ while ((tmp->s_semAdd) != (p->p_semAdd) && tmp != NULL){ prec = tmp; tmp = tmp->s_next; } /* Remove the pcb if we find it */ if (tmp != NULL){ pcb_t *tp; tp = outProcQ(&(tmp->s_procQ), p); if (emptyProcQ(tmp->s_procQ)) { prec->s_next = tmp->s_next; tmp->s_next= semdFree_h->s_next; semdFree_h->s_next = tmp; } return tp; } /* */ return NULL; }
/*Rimuove il pcb puntato da p dalla coda dei processi sul semaforo a lui associato (p->p_semkey) sulla ASL. Se il processo non risulta bloccato (cioè è un errore), restituisce NULL, altrimenti restituisce il puntatore al processo*/ pcb_t* outBlocked(pcb_t *p){ semd_t *semd_target = getSemd(p->p_semkey); pcb_t *blocked = NULL; if(semd_target) blocked = outProcQ(&(semd_target->s_procQ), p); /*Se p non esiste nella coda del semaforo*/ return blocked; }
/*[11] * Rimuove il PCB puntato da p dalla lista dei figli del padre. Se il PCB puntato da p non ha un * padre, res*tuisce NULL. Altrimenti restituisce l’elemento * rimosso (cioe’ p). A differenza della removeChild, p puo’ trovarsi in una posizione arbitraria */ pcb_t *outChild(pcb_t *p){ /*se p non ha padre*/ if(p->p_parent==NULL) return NULL; pcb_t *parent=p->p_parent; return outProcQ(&parent->p_first_child, p); }
/*[7] * Rimuove il PCB puntato da p dalla coda del semaforo su cui e’ bloccato, termina anche tutti i processi discendenti */ void outChildBlocked(pcb_t *p){ semd_t *tmp; tmp = getSemd(p->p_semkey); outProcQ(&(tmp->s_procQ), p); if(p->p_first_child == NULL){ p->p_first_child = NULL; return; }else{ outChildBlocked(p->p_first_child); } }
/*[6] * rimuove il pcb puntato da p dalla coda dei processi*/ pcb_t* outBlocked(pcb_t *p){ semd_t *tmp; pcb_t *temp; tmp = getSemd(p->p_semkey); temp = outProcQ(&(tmp->s_procQ), p); /*se non esiste*/ if(temp==NULL){ return NULL; }else{ return temp; } }
/** Rimuove il pcb puntato da p dalla process queue associata al suo semAdd e lo restituisce * Restituisce NULL se il p non si trova nella coda associata */ pcb_t *outBlocked(pcb_t *p){ pcb_t *result = NULL; semd_t *i = findSemd(p->p_semAdd); if(i != NULL){ result = outProcQ(&(i->s_procQ), p); /* Se la sua coda diventa vuota */ if(emptyProcQ(i ->s_procQ)){ freeSemd(i); } } return result; }
/*[7] * Rimuove il PCB puntato da p dalla coda dei processi * puntata da head. Se p non e’ presente nella coda, restituisce NULL. */ pcb_t *outProcQ(pcb_t **head, pcb_t *p){ if((*head)!=NULL){ if(*head==p){ (*head)=(*head)->p_next; return p; } else { /*scorro la coda , se non trovo p nella prima posizione*/ return outProcQ(&(*head)->p_next, p); } } /*se la coda e vuota, restituisco NULL*/ return NULL; }
int test_headProcQ(void) { int success = 1; pcb_t *p1, *p2; pcbq_t *q; initProc(); q = mkEmptyProcQ(); p1 = allocPcb(); p2 = allocPcb(); success &= headProcQ(q) == NULL; insertProcQ(&q, p1); success &= headProcQ(q) == p1; insertProcQ(&q, p2); success &= headProcQ(q) == p1; outProcQ(&q, p1); success &= headProcQ(q) == p2; return success; }
int main() { int i; initPcbs(); addokbuf("Initialized process control blocks \n"); /* Check allocPcb */ for (i = 0; i < MAXPROC; i++) { if ((procp[i] = allocPcb()) == NULL) adderrbuf("allocPcb(): unexpected NULL "); } if (allocPcb() != NULL) { adderrbuf("allocPcb(): allocated more than MAXPROC entries "); } addokbuf("allocPcb ok \n"); /* return the last 10 entries back to free list */ for (i = 10; i < MAXPROC; i++) freePcb(procp[i]); addokbuf("freed 10 entries \n"); /* create a 10-element process queue */ qa = mkEmptyProcQ(); if (!emptyProcQ(qa)) adderrbuf("emptyProcQ(qa): unexpected FALSE "); addokbuf("Inserting... \n"); for (i = 0; i < 10; i++) { if ((q = allocPcb()) == NULL) adderrbuf("allocPcb(): unexpected NULL while insert "); switch (i) { case 0: firstproc = q; break; case 5: midproc = q; break; case 9: lastproc = q; break; default: break; } insertProcQ(&qa, q); } addokbuf("inserted 10 elements \n"); if (emptyProcQ(qa)) adderrbuf("emptyProcQ(qa): unexpected TRUE" ); /* Check outProcQ and headProcQ */ if (headProcQ(qa) != firstproc) adderrbuf("headProcQ(qa) failed "); q = outProcQ(&qa, firstproc); if ((q == NULL) || (q != firstproc)) adderrbuf("outProcQ(&qa, firstproc) failed on first entry "); freePcb(q); q = outProcQ(&qa, midproc); if (q == NULL || q != midproc) adderrbuf("outProcQ(&qa, midproc) failed on middle entry "); freePcb(q); if (outProcQ(&qa, procp[0]) != NULL) adderrbuf("outProcQ(&qa, procp[0]) failed on nonexistent entry "); addokbuf("outProcQ() ok \n"); /* Check if removeProc and insertProc remove in the correct order */ addokbuf("Removing... \n"); for (i = 0; i < 8; i++) { if ((q = removeProcQ(&qa)) == NULL) adderrbuf("removeProcQ(&qa): unexpected NULL "); freePcb(q); } if (q != lastproc) adderrbuf("removeProcQ(): failed on last entry "); if (removeProcQ(&qa) != NULL) adderrbuf("removeProcQ(&qa): removes too many entries "); if (!emptyProcQ(qa)) adderrbuf("emptyProcQ(qa): unexpected FALSE "); addokbuf("insertProcQ(), removeProcQ() and emptyProcQ() ok \n"); addokbuf("process queues module ok \n"); addokbuf("checking process trees...\n"); if (!emptyChild(procp[2])) adderrbuf("emptyChild: unexpected FALSE "); /* make procp[1] through procp[9] children of procp[0] */ addokbuf("Inserting... \n"); for (i = 1; i < 10; i++) { insertChild(procp[0], procp[i]); } addokbuf("Inserted 9 children \n"); if (emptyChild(procp[0])) adderrbuf("emptyChild(procp[0]): unexpected TRUE "); /* Check outChild */ q = outChild(procp[1]); if (q == NULL || q != procp[1]) adderrbuf("outChild(procp[1]) failed on first child "); q = outChild(procp[4]); if (q == NULL || q != procp[4]) adderrbuf("outChild(procp[4]) failed on middle child "); if (outChild(procp[0]) != NULL) adderrbuf("outChild(procp[0]) failed on nonexistent child "); addokbuf("outChild ok \n"); /* Check removeChild */ addokbuf("Removing... \n"); for (i = 0; i < 7; i++) { if ((q = removeChild(procp[0])) == NULL) adderrbuf("removeChild(procp[0]): unexpected NULL "); } if (removeChild(procp[0]) != NULL) adderrbuf("removeChild(): removes too many children "); if (!emptyChild(procp[0])) adderrbuf("emptyChild(procp[0]): unexpected FALSE "); addokbuf("insertChild(), removeChild() and emptyChild() ok \n"); addokbuf("process tree module ok \n"); for (i = 0; i < 10; i++) freePcb(procp[i]); /* check ASL */ initASL(); addokbuf("Initialized active semaphore list \n"); /* check removeBlocked and insertBlocked */ addokbuf("insertBlocked() test #1 started \n"); for (i = 10; i < MAXPROC; i++) { procp[i] = allocPcb(); if (insertBlocked(&sem[i], procp[i])) adderrbuf("insertBlocked() test#1: unexpected TRUE "); } addokbuf("insertBlocked() test #2 started \n"); for (i = 0; i < 10; i++) { procp[i] = allocPcb(); if (insertBlocked(&sem[i], procp[i])) adderrbuf("insertBlocked() test #2: unexpected TRUE "); } /* check if semaphore descriptors are returned to free list */ p = removeBlocked(&sem[11]); if (insertBlocked(&sem[11],p)) adderrbuf("removeBlocked(): fails to return to free list "); if (insertBlocked(&onesem, procp[9]) == FALSE) adderrbuf("insertBlocked(): inserted more than MAXPROC "); addokbuf("removeBlocked() test started \n"); for (i = 10; i< MAXPROC; i++) { q = removeBlocked(&sem[i]); if (q == NULL) adderrbuf("removeBlocked(): wouldn't remove "); if (q != procp[i]) adderrbuf("removeBlocked(): removed wrong element "); if (insertBlocked(&sem[i-10], q)) adderrbuf("insertBlocked(3): unexpected TRUE "); } if (removeBlocked(&sem[11]) != NULL) adderrbuf("removeBlocked(): removed nonexistent blocked proc "); addokbuf("insertBlocked() and removeBlocked() ok \n"); if (headBlocked(&sem[11]) != NULL) adderrbuf("headBlocked(): nonNULL for a nonexistent queue "); if ((q = headBlocked(&sem[9])) == NULL) adderrbuf("headBlocked(1): NULL for an existent queue "); if (q != procp[9]) adderrbuf("headBlocked(1): wrong process returned "); p = outBlocked(q); if (p != q) adderrbuf("outBlocked(1): couldn't remove from valid queue "); q = headBlocked(&sem[9]); if (q == NULL) adderrbuf("headBlocked(2): NULL for an existent queue "); if (q != procp[19]) adderrbuf("headBlocked(2): wrong process returned "); p = outBlocked(q); if (p != q) adderrbuf("outBlocked(2): couldn't remove from valid queue "); p = outBlocked(q); if(c = p) addokbuf("saaaaaas \n"); if (p != NULL) adderrbuf("outBlocked(): removed same process twice."); if (headBlocked(&sem[9]) != NULL) adderrbuf("out/headBlocked: unexpected nonempty queue "); addokbuf("headBlocked() and outBlocked() ok \n"); addokbuf("ASL module ok \n"); addokbuf("So Long and Thanks for All the Fish\n"); return 0; }
int main() { int i; initPcbs(); addokbuf("Initialized Process Control Blocks \n"); /* Check allocPcb */ for (i = 0; i < MAXPROC; i++) { if ((procp[i] = allocPcb()) == NULL) adderrbuf("allocPcb(): unexpected NULL "); } if (allocPcb() != NULL) { adderrbuf(" ERROR: allocPcb(): allocated more than MAXPROC entries "); } addokbuf(" allocPcb test OK \n"); /* Return the last 10 entries back to free list */ for (i = 10; i < MAXPROC; i++) freePcb(procp[i]); addokbuf(" Added 10 entries to the free PCB list \n"); /* Create a 10-element process queue */ INIT_LIST_HEAD(&qa); if (!emptyProcQ(&qa)) adderrbuf("ERROR: emptyProcQ(qa): unexpected FALSE "); addokbuf("Testing insertProcQ ... \n"); for (i = 0; i < 10; i++) { if ((q = allocPcb()) == NULL) adderrbuf("ERROR: allocPcb(): unexpected NULL while insert "); switch (i) { case 3: q->priority=DEFAULT_PCB_PRIORITY; proc = q; break; case 4: q->priority=MAX_PCB_PRIORITY; maxproc = q; break; case 5: q->priority=MIN_PCB_PRIORITY; minproc=q; break; default: q->priority=DEFAULT_PCB_PRIORITY; break; } insertProcQ(&qa, q); } addokbuf("Test insertProcQ: OK. Inserted 10 elements \n"); if (emptyProcQ(&qa)) adderrbuf("ERROR: emptyProcQ(qa): unexpected TRUE" ); /* Check outProcQ and headProcQ */ if (headProcQ(&qa) != maxproc) adderrbuf("ERROR: headProcQ(qa) failed "); /* Removing an element from ProcQ */ q = outProcQ(&qa, proc); if ((q == NULL) || (q != proc)) adderrbuf("ERROR: outProcQ(&qa, proc) failed to remove the entry "); freePcb(q); /* Removing the first element from ProcQ */ q = removeProcQ(&qa); if (q == NULL || q != maxproc) adderrbuf("ERROR: removeProcQ(&qa, midproc) failed to remove the elements in the right order "); freePcb(q); /* Removing other 7 elements */ addokbuf(" Testing removeProcQ ... \n"); for (i = 0; i < 7; i++) { if ((q = removeProcQ(&qa)) == NULL) adderrbuf("removeProcQ(&qa): unexpected NULL "); freePcb(q); } // Removing the last element q=removeProcQ(&qa); if (q != minproc) adderrbuf("ERROR: removeProcQ(): failed on last entry "); freePcb(q); if (removeProcQ(&qa) != NULL) adderrbuf("ERROR: removeProcQ(&qa): removes too many entries "); if (!emptyProcQ(&qa)) adderrbuf("ERROR: emptyProcQ(qa): unexpected FALSE "); addokbuf(" Test insertProcQ(), removeProcQ() and emptyProcQ(): OK \n"); addokbuf(" Test process queues module: OK \n"); addokbuf(" Testing process trees...\n"); if (!emptyChild(procp[2])) adderrbuf("ERROR: emptyChild: unexpected FALSE "); /* make procp[1],procp[2],procp[3], procp[7] children of procp[0] */ addokbuf("Inserting... \n"); insertChild(procp[0], procp[1]); insertChild(procp[0], procp[2]); insertChild(procp[0], procp[3]); insertChild(procp[0], procp[7]); addokbuf("Inserted 2 children of pcb0 \n"); /* make procp[8],procp[9] children of procp[7] */ insertChild(procp[7], procp[8]); insertChild(procp[7], procp[9]); addokbuf("Inserted 2 children of pcb7 \n"); if (emptyChild(procp[0])) adderrbuf("ERROR: emptyChild(procp[0]): unexpected TRUE "); if (emptyChild(procp[7])) adderrbuf("ERROR: emptyChild(procp[0]): unexpected TRUE "); /* Check outChild */ q = outChild(procp[1]); if (q == NULL || q != procp[1]) adderrbuf("ERROR: outChild(procp[1]) failed "); q = outChild(procp[8]); if (q == NULL || q != procp[8]) adderrbuf("ERROR: outChild(procp[8]) failed "); /* Check removeChild */ q = removeChild(procp[0]); if (q == NULL || q != procp[2]) adderrbuf("ERROR: removeChild(procp[0]) failed "); q = removeChild(procp[7]); if (q == NULL || q != procp[9]) adderrbuf("ERROR: removeChild(procp[7]) failed "); q = removeChild(procp[0]); if (q == NULL || q != procp[3]) adderrbuf("ERROR: removeChild(procp[0]) failed "); q = removeChild(procp[0]); if (q == NULL || q != procp[7]) adderrbuf("ERROR: removeChild(procp[0]) failed "); if (removeChild(procp[0]) != NULL) adderrbuf("ERROR: removeChild(): removes too many children "); if (!emptyChild(procp[0])) adderrbuf("ERROR: emptyChild(procp[0]): unexpected FALSE "); addokbuf("Test: insertChild(), removeChild() and emptyChild() OK \n"); addokbuf("Testing process tree module OK \n"); freePcb(procp[0]); freePcb(procp[1]); freePcb(procp[2]); freePcb(procp[3]); freePcb(procp[4]); freePcb(procp[5]); freePcb(procp[6]); freePcb(procp[7]); freePcb(procp[8]); freePcb(procp[9]); /* check ASL */ initASL(); addokbuf("Initializing active semaphore list \n"); /* check removeBlocked and insertBlocked */ addokbuf(" Test insertBlocked(): test #1 started \n"); for (i = 10; i < MAXPROC; i++) { procp[i] = allocPcb(); if (insertBlocked(i, procp[i])) adderrbuf("ERROR: insertBlocked() test#1: unexpected TRUE "); } addokbuf("Test insertBlocked(): test #2 started \n"); for (i = 0; i < 10; i++) { procp[i] = allocPcb(); if (insertBlocked(i, procp[i])) adderrbuf("ERROR:insertBlocked() test #2: unexpected TRUE "); } /* check if semaphore descriptors are returned to the free list */ p = removeBlocked(11); if (insertBlocked(11,p)) adderrbuf("ERROR: removeBlocked(): fails to return to free list "); if (insertBlocked(MAXPROC+1, procp[9]) == FALSE) adderrbuf("ERROR: insertBlocked(): inserted more than MAXPROC "); addokbuf("Test removeBlocked(): test started \n"); for (i = 10; i< MAXPROC; i++) { q = removeBlocked(i); if (q == NULL) adderrbuf("ERROR: removeBlocked(): wouldn't remove "); if (q != procp[i]) adderrbuf("ERROR: removeBlocked(): removed wrong element "); } if (removeBlocked(11) != NULL) adderrbuf("ERROR: removeBlocked(): removed nonexistent blocked proc "); addokbuf("Test: insertBlocked() and removeBlocked() ok \n"); if (headBlocked(11) != NULL) adderrbuf("ERROR: headBlocked(): nonNULL for a nonexistent queue "); if ((q = headBlocked(9)) == NULL) adderrbuf("ERROR: headBlocked(1): NULL for an existent queue "); if (q != procp[9]) adderrbuf("ERROR: headBlocked(1): wrong process returned "); p = outBlocked(q); if (p != q) adderrbuf("ERROR: outBlocked(1): couldn't remove from valid queue "); /* Creating a 2-layer tree */ insertChild(procp[0], procp[1]); insertChild(procp[0], procp[2]); insertChild(procp[0], procp[3]); insertChild(procp[3], procp[4]); /* Testing outChildBlocked */ outChildBlocked(procp[0]); if (headBlocked(0) != NULL) adderrbuf("ERROR: outChildBlocked(): nonNULL for a nonexistent queue (0) "); if (headBlocked(1) != NULL) adderrbuf("ERROR: outChildBlocked(): nonNULL for a nonexistent queue (1) "); if (headBlocked(2) != NULL) adderrbuf("ERROR: outChildBlocked(): nonNULL for a nonexistent queue (2) "); if (headBlocked(3) != NULL) adderrbuf("ERROR: outChildBlocked(): nonNULL for a nonexistent queue (3) "); if (headBlocked(4) != NULL) adderrbuf("ERROR: outChildBlocked(): nonNULL for a nonexistent queue (4) "); if (headBlocked(5) == NULL) adderrbuf("ERROR: outChildBlocked(): NULL for an existent queue (5) "); addokbuf("Test headBlocked() and outBlocked(): OK \n"); addokbuf("ASL module OK \n"); addokbuf("So Long and Thanks for All the Fish\n"); return 0; }
/* [6] * rimuove il primo elemento dalla coda dei processi * puntata da head. Ritorna NULL se la coda e’ vuota. Altrimenti ritorna * il puntatore all’elemento rimosso dalla lista. */ pcb_t *removeProcQ(pcb_t **head){ /*se la coda e vuota*/ if (*head==NULL) return NULL; return outProcQ(head, headProcQ(*head)); }