Ejemplo n.º 1
0
void useExStVec(int type){
    if(currentProcess!=NULL)  {
        /* Se ho già fatto spectrapvec per il tipo di eccezione*/
        if (currentProcess->excStVec[type*2]!=NULL){
            /* Salvo lo stato nella oldarea adeguata*/
            switch(type){
                case SPECTLB:
                	saveStateIn(tlb_old, currentProcess->excStVec[type*2]);
                    break;
                case SPECPGMT:
                	saveStateIn(pgmtrap_old, currentProcess->excStVec[type*2]);
                    break;
                case SPECSYSBP:
                	saveStateIn(sysbp_old, currentProcess->excStVec[type*2]);
                    break;
            }
            /* Carico lo stato dalla newarea */
            LDST(currentProcess->excStVec[(type*2)+1]);
        }else{
           /* Altrimenti tratto come una SYS2  */
           terminateProcess(currentProcess); 
           scheduler();
        }
    } 
}
Ejemplo n.º 2
0
void scheduler()
{
	
	//Due possibili casi:
	//	-Esiste un processo in esecuzione -> context switch
	//	-Non c'è un processo -> ne carico uno
	
	if(currentProcess!=NULL){ //current process è quello che deve essere eseguito
		
		timer+=getTODLO()-last_access;
		last_access=getTODLO();
		
		//#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -> sta su uARMconst
		//#define SCHED_TIME_SLICE 5000
		//#define SCHED_PSEUDO_CLOCK 100000

		setTIMER(MIN(SCHED_TIME_SLICE, SCHED_PSEUDO_CLOCK-timer));
		
		LDST(&(currentProcess->s_t));
		
		
	}
	else{
		
		//Anche qui due casi possibili, controlliamo se la readyQueue è vuota
		if(clist_empty(readyQueue)){
			
			//processCount = 0 -> HALT -> non ci sono processi
			if(processCount == 0) HALT();
			
			//processCount>0 e SBC==0-> qualcosa è andato storto -> deadlock
			if(processCount>0 && softBlockCount == 0) PANIC();
			
			//caso "normale" -> aspettiamo che un processo necessiti di essere allocato
			if(processCount>0 && softBlockCount > 0) WAIT();
			
			//qualsiasi altro stato
			PANIC();
			
		}
		
		else{
			//semplicemente carico il primo processo in memoria
			//scherzavo, non è semplice
			
			currentProcess = removeProcQ(readyQueue);
			
			if(currentProcess == NULL) PANIC(); //qualcosa è andato storto
			
			//imposta i timer e altre cose brutte
		
			scheduler();
		}
	}

}
Ejemplo n.º 3
0
/**
	Quando invocata, la sys8 esegue una P sul semaforo associato al device identificato da intNo, dnume e waitForTermRead
	Registro a1: linea di interrupt
	Registro a2: device number
	Registro a3: operazione di terminal read/write
	Registro v0: status del device
*/
void wait_for_io_device(void){

	state_t* before = (state_t*)new_old_areas[getPRID()][SYSBK_OLD];
	int line = before->reg_a1;
	int devno = before->reg_a2;
	int rw = before->reg_a3;

	_passeren((line*(devno+1)+20)+rw);

	before->reg_v0 = devstatus[line-3][devno+rw];
	devstatus[line-3][devno+rw] = 0;
	LDST(before);
}
Ejemplo n.º 4
0
void schedule() {

    /* azioni da compiere quando non c'e' nessun thread pronto ad eseguire */
    if (emptyThreadQ(&readyQueue) && currentThread == NULL) {
        prova();
        
        if (threadCount == 1)/* se c'e' solo il SSI -> normal system shutdown */
            HALT(); /* chiamo la HALT ROM routine */
        else if (threadCount > 0 && softBlockCount == 0) {/* deadlock */
            PANIC(); /* chiamo la PANIC ROM routine */
        } else if (threadCount > 0 && softBlockCount > 0) { /* in attesa di un interrupt -> wait state */
            /* se ci sono thread in attesa dello pseudo tick,
             * carico il valore dello pseudo clock nel registro della cpu.*/
            if (!emptyThreadQ(&waitForPseudoClockQueue)) {
                SET_IT(SCHED_PSEUDO_CLOCK);
            }
            /* impostiamo lo stato del processore con gli interrupt abilitati*/
            setSTATUS(getSTATUS() | STATUS_IEc | STATUS_INT_UNMASKED);
            for (;;);
        }
    } else {
        /* Se non c'è nessun Thread in esecuzione ma c'e n'è almeno uno nella readyQueue allora 
           carico un thread*/
        if (currentThread == NULL) {
            currentThread = removeThread(&readyQueue);
            currentThread->elapsedTime = 0;
            currentThread->startTime = GET_TODLOW;
            SET_IT(SCHED_TIME_SLICE);
            /* Altrimenti se è passato il SCHED_TIME_SLICE rimuovo il thread corrente dall'esecuzione*/
        } else if (currentThread->elapsedTime >= SCHED_TIME_SLICE) {
            //in questo modo do priorità all'SSI
            if (currentThread != tcb_SSI) {
                insertThread(&readyQueue, currentThread);
                /*Carico un nuovo thread*/
                currentThread = removeThread(&readyQueue);
            }

            currentThread->elapsedTime = 0;
            currentThread->startTime = GET_TODLOW;

            /* Se e' scattato lo pseudo clock non settiamo il timer a 5 ms 
             * dato che scattera' subito l'interrupt dello pseudo clock */
            if (!isPseudoClock)
                SET_IT(SCHED_TIME_SLICE);

        }
        /* carico lo stato del thread nel processore  dalla sua tcb */
        LDST(&(currentThread->t_state));
    }
}
Ejemplo n.º 5
0
/**
	Quando invocata, la sys11 consente di definire gestori di SYS/BP Exception per il processo corrente.
	Registro a1: indirizzo della OLDArea in cui salvare lo stato corrente del processore.
	Registro a2: indirizzo della NEWArea del processore (da utilizzare nel caso si verifichi una SYS/BP Exception)
*/
void specify_sys_state_vector(void){


	pcb_t* suspend = currentproc[getPRID()];
	state_t* before = (state_t*)new_old_areas[getPRID()][SYSBK_OLD];
	
	if ((suspend->handler[SYSBK+3] == NULL) && (suspend->handler[SYSBK] == NULL)){
		suspend->handler[SYSBK+3] = (state_t*)before->reg_a1;
		suspend->handler[SYSBK] = (state_t*)before->reg_a2;
		LDST(&suspend->p_s);
	} else {
		kill(suspend);
		scheduler();
	}
}
Ejemplo n.º 6
0
/**
	Quando invocata, la sys5 esegue una P sul semaforo con chiave semKey.
	Registro a1: chiave del semaforo su cui effettuare la P.
*/
void passeren(void){

	pcb_t* suspend = currentproc[getPRID()];
	state_t* before = (state_t*)new_old_areas[getPRID()][SYSBK_OLD];
	int semkey = before->reg_a1;
	semd_t* sem;
	while (!CAS(&mutex_semaphoreprova,0,1)); /* critical section */
	sem = mygetSemd(semkey);
	sem->s_value--;
	if (sem->s_value >= 0){ /* GO! */
		CAS(&mutex_semaphoreprova,1,0); /* release mutex */
		LDST(&suspend->p_s);
	} else { /* wait */
		insertBlocked(semkey,suspend);
		CAS(&mutex_semaphoreprova,1,0); /* release mutex */
		scheduler();
	}
}
Ejemplo n.º 7
0
/**
@brief The function will undertake one of the following actions:
(1) If the offending process has NOT issued a SYS5, then invoke SYS2;
(2) If the offending process has issued a SYS5, then pass up the exception.
@return Void.
*/
HIDDEN void checkSYS5(int exceptionType, state_t *exceptionOldArea)
{
	/* [Case 1] SYS5 has not been issued */
	if (CurrentProcess->exceptionState[exceptionType] == 0)
	{
		/* Terminate the current process (SYS2) */
		terminateProcess();

		/* Call the scheduler */
		scheduler();
	}
	/* [Case 2] SYS5 has been issued */
	else
	{
		/* Move current process Exception State Area into the processor Exception State Area */
		saveCurrentState(exceptionOldArea, CurrentProcess->p_stateOldArea[exceptionType]);

		/* Load the processor state in order to start execution */
		LDST(CurrentProcess->p_stateNewArea[exceptionType]);
	}
}
Ejemplo n.º 8
0
/*
 * carica il processore con lo snapshot salvato nel TCB in testa
 * alla ready queue
 */
HIDDEN void upThread(void) {
	tcb_t *current;
	signed int time_snap;
	
	/* inizio del conteggio del tempo passato in codice kernel, solo per la prima
	 * esecuzione, altrimenti inizializzazione prevista negli vari handler */
	if (first_up) time_in_kernel = TOD_SNAPSHOT;

	current = removeThreadQ(&ready_queue);
	current_thread = current->tid;
	current->status = RUNN_THREAD;
	current = resolveTid(current_thread);
	if (current->cpu_remain == 0)
		current->cpu_remain = SCHED_TIME_SLICE;

	/* aggiorna il valore dello pseudo count evitando un possibile underflow */
	if (pseudo_count < (last_time_slice + STCK(time_snap) - time_in_kernel)) /* STCK piu' preciso */
		pseudo_count = 0;
	else
		pseudo_count -= last_time_slice + time_snap - time_in_kernel;

	/* settaggio interval timer considerando il tempo rimasto allo scadere dello pseudo clock*/
	if (pseudo_count > SCHED_TIME_SLICE) {
		if (current->cpu_remain < SCHED_TIME_SLICE) {
			last_time_slice = TOD_SNAPSHOT; /* inizio intervallo di tempo del prossimo time slice */
			SET_IT(current->cpu_remain); /* settaggio dell'interval timer */
		}
		else {
			last_time_slice = TOD_SNAPSHOT; /* inizio intervallo di tempo del prossimo time slice */
			SET_IT(SCHED_TIME_SLICE); /* settaggio dell'interval timer */
		}
	}
	else {
		last_time_slice = TOD_SNAPSHOT; /* inizio intervallo di tempo del prossimo time slice */
		SET_IT(pseudo_count); /* settaggio dell'interval timer */
	}
	/* carica il processore con lo stato del thread */
	LDST(&(current->cpu_snapshot));
	/* esegue codice del thread appena caricato */
}
Ejemplo n.º 9
0
void sysBpHandler(){
	
	int cause;
	int mode;
	
	//1-dovremmo salvare lo stato del registro
	
	//2-boh -> il tipo dice per evitare loop syscall :/
	currentProcess->p_s.cpsr += //qualcosa;
	
	//3-prendiamo il mode
	mode= ((sysBp_old->cpsr & STATUS_SYS_MODE) >> 0x3); //forse funziona -> STATUS_SYS_MODE in uarmConst.h
	
	//4-cause interrupt
	cause=getCAUSE();
	
	if(cause == EXC_SYSCALL){ //caso system call
		
		//controlla se è in user mode
		if(mode==TRUE){ //è definito da qualche parte il true?
			
			//controllo se è una delle 11 syscall
			if((sysBp_old->reg_a0 >= 1) && (sysBp_old->reg_a0 <= SYSCALL_MAX)){ //SYSCALL_MAX sta in const.h
			
				sysBp_old->CP15_Cause = setCAUSE(); //siamo sicuri non ci vadano parametri?
				
				//salva il sysbp old in pgmtrap old
				
				pgmTrapHandler();
				
			}
			else{
				//ERRORE!!! FACCIAMO UN ALTRA VOLTA!!!
			}
		}
		else{//caso kernel mode
			
			int ret;
			
			/* Salva i parametri delle SYSCALL */
			U32 argv1 = sysBp_old->a2;
			U32 argv2 = sysBp_old->a3;
			U32 argv3 = sysBp_old->a4;
			
			
			
			/* Gestisce ogni singola SYSCALL */
			switch(sysBp_old->a1)
			{
				case CREATEPROCESS:
					//currentProcess->p_state.reg_v0 = createProcess((state_t *) arg1);
					break;
					
				case TERMINATEPROCESS:
					//ris = terminateProcess((int) arg1);
					//if(currentProcess != NULL) currentProcess->p_state.reg_v0 = ris;
					break;
					
				case SEMOP:
					semaphoreOperation((int *) argv1, (int) argv2);
					break;
				
				case SPECSYSHDL:
					
					break;
					
				case SPECTLBHDL:
					
					break;
					
				case SPECPGMTHDL:
					
					break;
					
					
				case EXITTRAP:
					
					break;
					
				case GETCPUTIME:
					//currentProcess->p_state.reg_v0 = getCPUTime();
					break;
					
				case WAITCLOCK:
					//waitClock();
					break;
					
				case IODEVOP:
					
					break;
					
				case GETPID:
					currentProcess->p_state.reg_v0 = getPid();
					break;
					
				
				/*
					
				case WAITIO:
					currentProcess->p_state.reg_v0 = waitIO((int) arg1, (int) arg2, (int) arg3);
					break;
					
				case GETPPID:
					currentProcess->p_state.reg_v0 = getPpid();
					break;
					
				case SPECTLBVECT:
					specTLBvect((state_t *) arg1, (state_t *)arg2);
					break;
					
				case SPECPGMVECT:
					specPGMvect((state_t *) arg1, (state_t *)arg2);
					break;
					
				case SPECSYSVECT:
					specSYSvect((state_t *) arg1, (state_t *)arg2);
					break;
					
				 */
					
				default:
					/* Se non è già stata eseguita la SYS12, viene terminato il processo corrente */
					if(currentProcess->ExStVec[ESV_SYSBP] == 0)
					{
						int ris;
						
						ris = terminateProcess(-1);
						if(currentProcess != NULL) currentProcess->p_state.reg_v0 = ris;
					}
					/* Altrimenti viene salvata la SysBP Old Area all'interno del processo corrente */
					else
					{
						saveCurrentState(sysBp_old, currentProcess->sysbpState_old);
						LDST(currentProcess->sysbpState_new);
					}
			}
			
			scheduler();
			
		}
	}
	else{ //caso breakpoint
	
 
	}
}