예제 #1
0
/**
@brief (SYS6) Retrieve the CPU time of the current process.
@return CPU time of the current process.
*/
EXTERN U32 getCPUTime()
{
	/* Perform a last update of the CPU time */
	CurrentProcess->p_cpu_time += getTODLO() - ProcessTOD;
	ProcessTOD = getTODLO();

	return CurrentProcess->p_cpu_time;
}
예제 #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();
		}
	}

}
예제 #3
0
int main()
{
	pcb_t *init;
	int i;

	/* Populate the processor state areas into the ROM Reserved Frame */
	populateArea(SYSBK_NEWAREA,		(memaddr) sysBpHandler);	/* SYS/BP Exception Handling */
	populateArea(PGMTRAP_NEWAREA,	(memaddr) pgmTrapHandler);	/* PgmTrap Exception Handling */
	populateArea(INT_NEWAREA,		(memaddr) intHandler);		/* Interrupt Exception Handling */
	populateArea(TLB_NEWAREA,		(memaddr) tlbHandler);		/* TLB Exception Handling */

	/* Initialize data structures */
	initPcbs();
	initASL();
	
	/* Initialize global variables */
	ReadyQueue = mkEmptyProcQ();
	CurrentProcess = NULL;
	ProcessCount = SoftBlockCount = TimerTick = PseudoClock = 0;
	
	/* Initialize device semaphores */
	for (i = 0; i < DEV_PER_INT; i++)
		Semaphore.disk[i] =
		Semaphore.tape[i] =
		Semaphore.network[i] =
		Semaphore.printer[i] =
		Semaphore.terminalR[i] =
		Semaphore.terminalT[i] = 0;

	/* Initialize init method */
	if (!(init = allocPcb()))
		PANIC(); /* Anomaly */
	
	/* Enable interrupts; enable Kernel-Mode; disable Virtual Memory */
	init->p_s.CP15_Control &= ~(0x1);
	init->p_s.cpsr =  STATUS_SYS_MODE | STATUS_ALL_INT_ENABLE(init->p_s.cpsr);
	
	/* Initialize Stack Pointer */
	init->p_s.sp = RAM_TOP - BUS_REG_RAM_SIZE;
	
	/* Initialize Program Counter with the test process */
	init->p_s.pc = (memaddr) test;

	/* Insert init in ProcQ */
	insertProcQ(&ReadyQueue, init);
	
	/* Initialize Process Id */
	ProcessCount++;

	/* Start the timer tick */
	StartTimerTick = getTODLO();
	/* Call the scheduler */
	scheduler();

	/* Anomaly */
	PANIC();
	return 0;
}
예제 #4
0
//gestore degli interrupt
void int_handler(){	
	interruptStart = getTODLO();	//tempo in cui comincia la gestione dell'interrupt, da
					//assegnare poi ad un eventuale processo svegliato dall'interrupt
	state_t *returnState = (state_t*) INT_OLDAREA;
	returnState->pc -= 4;
	if( current_process != NULL){
		copy_state( returnState, &current_process->p_s );
		current_process->userTime += interruptStart - userTimeStart;//se c'è un processo aggiorno il suo userTime
		current_process->CPUTime += interruptStart - CPUTimeStart;
	}
	int cause = getCAUSE();
	if(CAUSE_IP_GET(cause, IL_TIMER)){
		if( current_timer == PSEUDO_CLOCK ){
			while( devSem[CLOCK_SEM] < 0 ){	//Ad ogni pseudo clock tick mi assicuro che il semaforo sia sempre a zero
				verhogen( &devSem[CLOCK_SEM], 1, 0, getTODLO() - interruptStart);
			}
		}
		else if(current_timer == TIME_SLICE ){
			if( current_process != NULL ){
				insertProcQ( priority_queue(current_process->priority), current_process);
				current_process->CPUTime += getTODLO() - interruptStart;	//se metto in pausa il processo aggiorno anche il suo CPUTime
				current_process = NULL;
			}
		}
	}
	else if(CAUSE_IP_GET(cause, IL_DISK)){
		dtnp_interrupt(IL_DISK);
	}
	else if(CAUSE_IP_GET(cause, IL_TAPE)){
		dtnp_interrupt(IL_TAPE);
	}
	else if(CAUSE_IP_GET(cause, IL_ETHERNET)){
		dtnp_interrupt(IL_ETHERNET);
	}
	else if(CAUSE_IP_GET(cause, IL_PRINTER)){
		dtnp_interrupt(IL_PRINTER);
	}
	else if(CAUSE_IP_GET(cause, IL_TERMINAL)){
		terminal_interrupt();
	}
	scheduler();
}
예제 #5
0
//disk, tape, network, printer interrupt handler
void dtnp_interrupt(int int_line){	
	dtpreg_t *dev_g;
	int i;
	unsigned int status;		//valore da far ritornare alla SYS8
	memaddr *interrupt_line = (memaddr*) CDEV_BITMAP_ADDR(int_line);	//ottengo la linea di interrupt
	int dev_num = pending_interrupt_device(interrupt_line);	//ottengo il device su cui pende l'interrupt
	dev_g = (dtpreg_t*) DEV_REG_ADDR(int_line, dev_num);
	dev_g->command = DEV_C_ACK;	//passo l'acknowledgement
	i = devSemIndex(int_line, dev_num) ;
	if( devSem[i] < 1 ){				//se ci sono dei processi bloccati sul semaforo
		status = dev_g->status;			//li libero e passo loro lo status register e il tempo di gestione
		verhogen( &devSem[i] , 1 , status,  getTODLO() - interruptStart);
		devStatus[i] = 0;
	}
	else{	//se nessuno sta aspettando l'interrupt salvo lo status register e il tempo di gestione dell'interrupt
		// per quando qualcuno li richiederà
		devStatus[i] = dev_g->status;
		interruptTime[i] = getTODLO() - interruptStart;
	}
}
예제 #6
0
//gestore degli interrupt per i terminali
void terminal_interrupt(){	
	termreg_t *dev_t;
	int i ;
	memaddr *interrupt_line = (memaddr*) CDEV_BITMAP_ADDR(IL_TERMINAL);	//ottengo la linea di interrupt per i terminali
	int dev_num = pending_interrupt_device(interrupt_line);	//ottengo il terminale su cui pende l'interrupt
	dev_t = (termreg_t*) DEV_REG_ADDR(IL_TERMINAL, dev_num);	//ottengo il registro del terminale
	unsigned int status ;      //valore da far ritornare alla SYS8
	status_iprint = dev_t->transm_status;
	if( (dev_t->transm_status & DEV_TERM_STATUS ) == DEV_TTRS_S_CHARTRSM){
		//trattasi di una scrittura, priorità più alta della lettura
		status = dev_t->transm_status;
		i = devSemIndex(IL_TERMINAL+1, dev_num);
		dev_t->transm_command = DEV_C_ACK;	//acknowledgement
		if( devSem[i] < 1 ){				//se ci sono dei processi bloccati sul semaforo
			verhogen(&devSem[i], 1, status, getTODLO() - interruptStart);	//li libero e passo loro lo status register
			devStatus[i] = 0;
		}
		else{	//se nessuno sta aspettando l'interrupt salvo lo status register per quando qualcuno lo richiederà
			devStatus[i] = dev_t->transm_status;
			interruptTime[i] = getTODLO() - interruptStart;	//tempo impegato a gestire l'interrupt
		}
	}
	else if( (dev_t->recv_status & DEV_TERM_STATUS) == DEV_TRCV_S_CHARRECV ){
		//trattasi di una lettura
		status = dev_t->recv_status;
		i = devSemIndex(IL_TERMINAL, dev_num);
		dev_t->recv_command = DEV_C_ACK;	//acknowledgement
		if( devSem[i] < 1 ){
			verhogen(&devSem[i], 1,status, getTODLO() - interruptStart);	//come sopra
			devStatus[i] = 0;
		}
		else{
			devStatus[i] = dev_t->recv_status;
			interruptTime[i] = getTODLO() - interruptStart;	//tempo impegato a gestire l'interrupt
		}
	}
	
}
예제 #7
0
int main() {
	initExceptionHandlers();
	initPcbs();
	initASL();
	// Initialize device semaphores
	memset(&semaphores, 0, sizeof(semaphores));
	// Create init and start the scheduler
	pcb_t *init;
	init = makeInit();
	init->p_pid = 1;
	boot_start=getTODLO();
	schedStart(init);
	return 0;
}