Example #1
0
/**
	Quando invocata, la sys6 restituisce il tempo di CPU (in microsecondi) usato dal processo corrente.
	Registro v0: valore di ritorno.
*/
void get_cpu_time(void){

	pcb_t* suspend = currentproc[getPRID()];
	state_t* before = (state_t*)new_old_areas[getPRID()][SYSBK_OLD];
	
	before->reg_v0 = suspend->cpu_time;
}
Example #2
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();
	}
}
Example #3
0
/*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);
	} 
}
Example #4
0
HIDDEN void IOIntHandler(unsigned int devAddr, unsigned int devCommand)
{
	unsigned int cpuID = getPRID();
	memaddr *devCommandReg;
	
	// Esegue una V sul semaforo del device, risvegliando il primo processo bloccato
	unsigned char unlockedProcess = devSemV(devAddr);
	
	if(unlockedProcess == FALSE)
		saveRetDevStatus(devAddr);
	
	mutexLock(getDevDbMutex());

	/* Mando l'ack dell'interrupt */
	devCommandReg = (memaddr *) devCommand;
	*devCommandReg = DEV_C_ACK;

	mutexUnlock(getDevDbMutex());

	if(getCurrentProcess(cpuID) != NULL)
		// RILANCIO IL PROCESSO CHE ESEGUIVA SULLA CPU
		currentProcessRestart(cpuID, FALSE);
	else
	{
		processInterleave(NULL);
		currentProcessRestart(cpuID, TRUE);
	}
}
Example #5
0
HIDDEN void pltIntHandler(pcb_t* current)
{
	// esegue l'interleaving tra processi, scarica il processo in current nella coda ready più corta e ne prende uno dalla coda ready più lunga mettendolo in current sulla cpu
	processInterleave(current);
	
	// rifa partire il processo current settando i timer e salvando il tempo di partenza per l'aggiornamento dei tempi di esecuzione
	currentProcessRestart(getPRID(), TRUE);
}
Example #6
0
/**
	Quando invocata, la sys2 determina la creazione di un processo fratello del processo chiamante.
	Registro a1: indirizzo fisico dello state_t del nuovo processo.
	Registro a2: priorità del nuovo processo.
	Valori di ritorno nel registro v0:
	- 0 nel caso di creazione corretta
	- -1 nel caso di errore.
*/
void create_brother(void){

	pcb_t* suspend = currentproc[getPRID()];
	pcb_t* father = suspend->p_parent;
	pcb_t* bro;
	state_t* before = (state_t*)new_old_areas[getPRID()][SYSBK_OLD];
	
	if (bro = allocaPcb(before->reg_a2)){
		bro->p_s = *((state_t*)before->reg_a1);
		while (!CAS(&mutex_scheduler,0,1));
		insertChild(father,bro);
		insertProcQ(readyQ,bro);
		CAS(&mutex_scheduler,1,0);
		before->reg_v0 = 0;
	} else {
		before->reg_v0 = -1;
	}
}
Example #7
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();
	}
}
Example #8
0
/**
	Quando invocata, la sys1 determina la creazione di un processo figlio del processo chiamante.
	Registro a1: indirizzo fisico dello state_t del nuovo processo.
	Registro a2: priorità del nuovo processo.
	Valori di ritorno nel registro v0:
	- 0 nel caso di creazione corretta
	- -1 nel caso di errore
*/
void create_process(void){
	
	pcb_t* suspend = currentproc[getPRID()];
	pcb_t* son;
	state_t* before = (state_t*)new_old_areas[getPRID()][SYSBK_OLD];

	
	
	if (son = allocaPcb(before->reg_a2)){
		son->p_s = *((state_t*)before->reg_a1);
		while (!CAS(&mutex_scheduler,0,1));
		insertChild(suspend,son);
		insertProcQ(readyQ,son);
		CAS(&mutex_scheduler,1,0);
		before->reg_v0 = 0;
	} else {
		before->reg_v0 = -1;
	}
}
Example #9
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);
}
Example #10
0
/**
	Quando invocata, la sys7 esegue una P sul semaforo associato allo pseudo-clock timer. 
	La V su tale semaforo deve essere eseguito dal nucleo ogni 100 millisecondi (tutti i processi in coda su tale 	
	semaforo devono essere sbloccati).
*/
void wait_for_clock(void){

	int i=0;
	pcb_t* suspend = currentproc[getPRID()];

	while (!CAS(&mutex_wait_clock,0,1)); /* critical section */
	
	softBlockCounter++;
	CAS(&mutex_wait_clock,1,0);
	_passerenclock(MAXPROC+MAX_DEVICES);
	
	return scheduler();
}
Example #11
0
/**
	Quando invocata, la sys4 esegue una V sul semaforo con chiave semKey
	Registro a1: chiave del semaforo su cui effettuare la V.
*/
void verhogen(void){

	
	pcb_t* next;
	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 (headBlocked(semkey)){ /* wake up someone! */
		next = removeBlocked(semkey);
		CAS(&mutex_semaphoreprova,1,0); /* release mutex */
		inserisciprocessoready(next);
	} else {
		CAS(&mutex_semaphoreprova,1,0); /* release mutex */
	}
}
Example #12
0
HIDDEN void intervalIntHandler(state_t *int_oldarea)
{
	unsigned int cpuID = getPRID();
	
	// Sblocca tutti i processi in coda sul semaforo dello pseudoClock
	flushPseudoClock();

	// Risetta il timer di pseudoClock
	setPseudoClockTimer();

	if(getCurrentProcess(cpuID) != NULL)
		// RILANCIO IL PROCESSO CHE ESEGUIVA SULLA CPU
		currentProcessRestart(cpuID, FALSE);
	else
	{
		processInterleave(NULL);
		currentProcessRestart(cpuID, TRUE);
	}
}
Example #13
0
void intHandler(void) {

	unsigned int timeStamp = GET_TODLOW;
	unsigned int prid = getPRID();
	
	state_t *ints_oldarea;
	pcb_t* current = getCurrentProcess(prid);

	if(prid == 0)
		ints_oldarea = (state_t *) INT_OLDAREA;
	else
		ints_oldarea = getNewOldAreaPtr(prid, INT_OLDAREA_INDEX);

	// Aggiorno i tempi di esecuzione del processo
	updateProcessExecTime(timeStamp, current);

	// Aggiorno lo stato del processore nel pcb
	updatePcbCPUState(ints_oldarea, current);

	/* selezione del gestore per gli interrupt giusto */
	if(CAUSE_IP_GET(ints_oldarea->cause, 1)) /* interrupt processor local timer */
	{
		pltIntHandler(current);
	}	
	else if (CAUSE_IP_GET(ints_oldarea->cause, 2))
	{
		intervalIntHandler(ints_oldarea); /* interval timer interrupt */
	}
	else if (CAUSE_IP_GET(ints_oldarea->cause, 7)) /* int terminali */
 	{
		unsigned int dBA = dev_search(devCalc(4));
		
		/* calcolo se l'int è del sub-device trasmettitore, ricevitore o entrambi */
		if (((*(memaddr *) dBA + 0x8) >= ILLEGAL_OPCODE) || ((*(memaddr *) dBA + 0x8) <= CHAR_TRASM))
			IOIntHandler(dBA + 0x8, dBA + 0xc);
		
		if (((*(memaddr *) dBA) >= ILLEGAL_OPCODE) || ((*(memaddr *) dBA) <= CHAR_RECV))
			IOIntHandler(dBA, dBA + 0x4);
	}
}
Example #14
0
/**
 * quando invocata la sys3 termina il processo corrente e tutta la sua progenia.
 */
void terminate_process(void){
	pcb_t* suspend = currentproc[getPRID()];
	kill(suspend);
	return scheduler();
}