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;
}
Пример #3
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;
}
Пример #5
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;
}
Пример #6
0
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,&sectSize,&sectors,&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);
	}
}