void thread_exit(void *retval){ #ifdef O_PREEMPTION interruptsOff(); #endif //le thread qui veut terminer son execution thread *courant = getRunningThread(); //on recupere la valeur de retour courant->valRetour = retval; //on met le statut a FINISH courant->state = STATUS_FINISH; #ifdef O_KILLCHILDREN //on tue tous les eventuels enfants du thread if(courant->is_father == TRUE){ killThreadChildren(courant->tid); } #endif //si le thread est attendu par un autre thread if(courant->est_attendu == TRUE){ thread* waiting = courant->threadAttendant; //on fait le nettoyage nettoyage_thread_termine(courant); //on lance le thread qui attendait que le thread termine removeThreadByTid(&fifo_STOP,waiting->tid); waiting->state = STATUS_READY; setRunningThread(waiting); #ifdef O_PREEMPTION interruptsOn(); #endif setcontext(waiting->context); exit(1); } //sinon on lance le prochain thread thread* prochain = prochainThread(); if(prochain->tid != courant->tid){ addInFifo(courant); setRunningThread(prochain); #ifdef O_PREEMPTION interruptsOn(); #endif setcontext(prochain->context); } exit(1); }
int thread_yield(){ #ifdef O_PREEMPTION interruptsOff(); #endif //le thread courant thread *th1 = getRunningThread(); //le prochain thread thread *th2 = prochainThread(); #ifdef O_PRIORITE updatePriority(th1); #endif #ifdef O_PREEMTION setAlarm(); #endif if(th2->tid != th1->tid){ addInFifo(th1); setRunningThread(th2); #ifdef O_PREEMPTION interruptsOn(); #endif swapcontext(th1->context,th2->context); } return 0; }
int launch(void *arg) { userArgStruct *uas = (userArgStruct *) arg; interruptsOn(); userMode(); int rc = uas->func(uas->arg); free(uas); Sys_Terminate(rc); /*Never gets here*/ return rc; }
int thread_create(thread_t*t,void*(*func)(void *),void*arg){ #ifdef O_PREEMPTION interruptsOff(); #endif //si le main n'est pas un thread, il le devient sinon if(MAIN_IS_THREAD == FALSE && mainBecomesThread()==-1) return -1; //on cree le context du thread ucontext_t *uc = createContext((void (*) (void))func,arg); if(uc == NULL) return -1; //on cree le thread *t = getNextTID(); thread *newth = newThread(*t, STATUS_READY, uc); //on met à jour la rélation thread pere et thread fils thread* pere = getRunningThread(); pere->is_father = TRUE; newth->father = pere; newth->context->uc_link = pere->context; addInFifo(pere); #ifdef O_PRIORITE updatePriority(pere); #endif //on lance le nouveau thread cree setRunningThread(newth); #ifdef O_PREEMPTION interruptsOn(); #endif swapcontext(pere->context, newth->context); return 0; }
static int ClockDriver(void *arg) { interruptsOn(); int result; int status; int rc = 0; /* * Let the parent know we are running and enable interrupts. */ P1_V(running); while (1) { result = P1_WaitDevice(USLOSS_CLOCK_DEV, 0, &status); if (result != 0) { rc = 1; goto done; } /* * Compute the current time and wake up any processes * whose time has come. */ wakeUpProcesses(); } wakeUpProcesses(); done: return rc; }
void sysHandler(int type,void *arg) { if(arg == NULL){ USLOSS_Console("USLOSS_Sysargs is NULL!\n"); return; } USLOSS_Sysargs *sysArgs = (USLOSS_Sysargs *) arg; int retVal = 0; int retVal2 = 0; int sectSize = 0; int sectors = 0; int tracks = 0; interruptsOn(); switch (sysArgs->number) { case SYS_TERMREAD: retVal = P2_TermRead((int)sysArgs->arg3, (int)sysArgs->arg2, sysArgs->arg1); if(retVal >= 0){ sysArgs->arg4 = (void *)0; sysArgs->arg2 = (void *)retVal; }else{ sysArgs->arg4 = (void *)-1; } break; case SYS_TERMWRITE: retVal = P2_TermWrite((int)sysArgs->arg3,(int)sysArgs->arg2,(char *)sysArgs->arg1); if(retVal >= 0){ sysArgs->arg4 = (void *)0; sysArgs->arg2 = (void *)retVal; }else{ sysArgs->arg4 = (void *)-1; } break; case SYS_SPAWN: //Part 1 retVal = P2_Spawn(sysArgs->arg5, sysArgs->arg1, sysArgs->arg2, (int) sysArgs->arg3, (int) sysArgs->arg4); if (retVal == -3 || retVal == -2) { sysArgs->arg4 = (void *) -1; sysArgs->arg1 = (void *) -1; } else { sysArgs->arg1 = (void *) retVal; sysArgs->arg4 = (void *) 0; } break; case SYS_WAIT: //Part 1 retVal = P2_Wait(&retVal2); if(retVal == -1){ sysArgs->arg1 = (void *)-1; sysArgs->arg4 = (void *)-1; sysArgs->arg2 = (void *)-1; }else{ sysArgs->arg1 = (void *)retVal; sysArgs->arg2 = (void *)retVal2; sysArgs->arg4 = (void *)0; } break; case SYS_TERMINATE: //Part 1 P2_Terminate((int)sysArgs->arg1); break; case SYS_SLEEP: // Part 1 retVal = P2_Sleep((int)sysArgs->arg1); sysArgs->arg4 = (void *) retVal; break; case SYS_DISKREAD: retVal = P2_DiskRead((int)sysArgs->arg5,(int)sysArgs->arg3,(int) sysArgs->arg4,(int)sysArgs->arg2,(void *)sysArgs->arg1); if (retVal == -1) { sysArgs->arg1 = (void *)retVal; sysArgs->arg4 = (void *)-1; } else if (retVal == 0) { sysArgs->arg1 = (void *)0; sysArgs->arg4 = (void *)0; }else { sysArgs->arg1 = (void *)retVal; //output is the disk's status register sysArgs->arg4 = (void *)0; } break; case SYS_DISKWRITE: retVal = P2_DiskWrite((int)sysArgs->arg5,(int)sysArgs->arg3,(int) sysArgs->arg4,(int)sysArgs->arg2,(void *)sysArgs->arg1); if (retVal == -1) { sysArgs->arg1 = (void *)retVal; sysArgs->arg4 = (void *)-1; } else if (retVal == 0) { sysArgs->arg1 = (void *)0; sysArgs->arg4 = (void *)0; }else { sysArgs->arg1 = (void *)retVal; //output is the disk's status register sysArgs->arg4 = (void *)0; } break; case SYS_DISKSIZE: retVal = P2_DiskSize((int)sysArgs->arg1,§Size,§ors,&tracks); if (retVal == -1) { sysArgs->arg4 = (void *)-1; }else { sysArgs->arg4 = (void *)0; sysArgs->arg1 = (void *)sectSize; sysArgs->arg2 = (void *)sectors; sysArgs->arg3 = (void *)tracks; } break; case SYS_GETTIMEOFDAY: //Part 1 sysArgs->arg1 = (void *)USLOSS_Clock(); break; case SYS_CPUTIME: //Part 1 sysArgs->arg1 = (void *)P1_ReadTime(); break; case SYS_DUMPPROCESSES: //Part 1 P1_DumpProcesses(); break; case SYS_GETPID: //Part 1 sysArgs->arg1 = (void *) P1_GetPID(); break; case SYS_SEMCREATE: //Part 1 retVal = (int)sysArgs->arg1; if(retVal < 0){ sysArgs->arg4 = (void *)-1; }else{ sysArgs->arg4 = (void *)0; sysArgs->arg1 = (void *) semAdd(P1_SemCreate(retVal)); } break; case SYS_SEMP: // Part 1 if(validSem((int)sysArgs->arg1) == 0){ sysArgs->arg4 = (void *) -1; return; } retVal = P1_P(userSemList[(int)sysArgs->arg1].sem); if(retVal < 0){ sysArgs->arg4 = (void *) -1; } else{ sysArgs->arg4 = (void *) 0; } break; case SYS_SEMV: // Part 1 if(validSem((int)sysArgs->arg1) == 0){ sysArgs->arg4 = (void *) -1; return; } retVal = P1_V(userSemList[(int)sysArgs->arg1].sem); if(retVal < 0){ sysArgs->arg4 = (void *) -1; } else{ sysArgs->arg4 = (void *) 0; } break; case SYS_SEMFREE: // Part 1 if(validSem((int)sysArgs->arg1) == 0){ sysArgs->arg4 = (void *) -1; return; } retVal = semDelete((int)sysArgs->arg1); if(retVal < 0){ sysArgs->arg4 = (void *) -1; } else{ sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXCREATE: //Part 1 retVal = P2_MboxCreate((int)sysArgs->arg1,(int)sysArgs->arg2); if(retVal == -2){ sysArgs->arg1 = (void *) -1; sysArgs->arg4 = (void *) -1; }else{ sysArgs->arg1 = (void *) retVal; sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXRELEASE: // Part 1 retVal = P2_MboxRelease((int)sysArgs->arg1); if(retVal < 0){ sysArgs->arg4 = (void *) -1; }else{ sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXSEND: // Part 1 retVal = P2_MboxSend((int)sysArgs->arg1,sysArgs->arg2,(int *)&sysArgs->arg3); if(retVal < 0){ sysArgs->arg4 = (void *) -1; }else{ sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXRECEIVE: // Part 1 retVal = P2_MboxReceive((int)sysArgs->arg1,sysArgs->arg2,(int *)&sysArgs->arg3); if(retVal < 0){ sysArgs->arg4 = (void *) -1; }else{ sysArgs->arg4 = (void *) 0; sysArgs->arg2 = (void *) retVal; } break; case SYS_MBOXCONDSEND: // Part 1 retVal = P2_MboxCondSend((int)sysArgs->arg1,sysArgs->arg2,(int *)&sysArgs->arg3); if(retVal == -1){ sysArgs->arg4 = (void *) -1; }else if(retVal == -2){ sysArgs->arg4 = (void *) 1; } else{ sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXCONDRECEIVE: // Part 1 retVal = P2_MboxCondReceive((int)sysArgs->arg1,sysArgs->arg2,(int *)&sysArgs->arg3); if(retVal == -1){ sysArgs->arg4 = (void *) -1; }else if(retVal == -2){ sysArgs->arg4 = (void *) 1; } else{ sysArgs->arg4 = (void *) 0; sysArgs->arg2 = (void *) retVal; } break; default: P1_Quit(1); } }