Ejemplo n.º 1
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.º 2
0
/*
 * termina/elimina il TCB passato ponendo in stato READY_THREAD tutti i
 * thread che fossero in inbox e in oubox, questi ultimi vengono poi 
 * re-inseriti nella ready_queue
 */
HIDDEN void force_terminate(tid_t bill) {
	tcb_t	*bill_t, *tmp_bill;

	bill_t = resolveTid(bill);

	/* controllo presenza TCB in attesa in inbox */
	while (!emptyThreadQ(bill_t->inbox)) {
		tmp_bill = removeThreadQ(&(bill_t->inbox));
		tmp_bill->status = READY_THREAD;
		insertBackThreadQ(&ready_queue, tmp_bill);
	}

	/* controllo presenza TCB in attesa in outbox */
	while (!emptyThreadQ(bill_t->outbox)) {
		tmp_bill = removeThreadQ(&(bill_t->outbox));
		tmp_bill->status = READY_THREAD;
		insertBackThreadQ(&ready_queue, tmp_bill);
	}

	killTcb(bill);
	thread_count--;
}
Ejemplo n.º 3
0
/* Rimuove il tcb_t puntato da p dalla coda la cui testa è puntata da head.
   Se l'elemento p non è presente nella coda allora restituisce NULL*/
tcb_t *outThread(struct list_head *head, tcb_t *p) {
    struct list_head *t_temp = NULL;

    /* se il puntatore a coda */
    if(emptyThreadQ(head))
        return NULL;

    /* cerco in tutta la lista se c'è una corrispondenza con con p */
    list_for_each(t_temp, head) {
        if( t_temp == &(p->t_next) ) {/* nel caso la trovo allora la elimino e lo restituisco */
            list_del( &(p->t_next) );
            INIT_LIST_HEAD(&(p->t_next));
            return p;
        }
    }
    /* altrimenti restituisco NULL */
    return NULL;
}
Ejemplo n.º 4
0
/*
 * funzione principale
 */
void schedule(void) {
	tcb_t	*SSI_t, *tmp_q;
	unsigned int execKill;

	/* esami tutta la ready queue, spostando tutti i thread contrassegnati to_kill
	 * nella killable_queue. Inizia la scansione da capo ad ogni thread spostato */
	if (!emptyThreadQ(ready_queue)){
		tmp_q = ready_queue;
		do{
			execKill = FALSE;
			if(tmp_q->to_kill == TRUE){
				tmp_q = outThreadQ(&ready_queue, tmp_q);
				insertBackThreadQ(&killable_queue, tmp_q);
				execKill = TRUE;
			}
			tmp_q = tmp_q->t_prev;
			if (execKill == TRUE)
				tmp_q = ready_queue;
			if (emptyThreadQ(ready_queue))
				execKill = FALSE;
		} while(((tmp_q != ready_queue) && (!emptyThreadQ(ready_queue))) || execKill == TRUE);
	}

	/* termina tutti i thread, svuotando contestualmente killable_queue */
	if (!emptyThreadQ(killable_queue)){
		tmp_q = killable_queue;
		do{
			outThreadQ(&killable_queue, tmp_q);
			force_terminate(tmp_q->tid);
			tmp_q = tmp_q->t_prev;
		} while(!emptyThreadQ(killable_queue));
	}

	if (emptyThreadQ(ready_queue)) {
		if (thread_count == 1) HALT(); /* dovrebbe bastare questo tipo di controllo */
		SSI_t = resolveTid(SSI_TID);
		if (thread_count > 0 && softb_count == 0) PANIC();
		/* anche la SSI non puo' eseguire perche' e' in recv */
		if (thread_count > 0 && softb_count > 0 && SSI_t->status == W4_ANYTID) {
			all_blocked = TRUE; /* tutti i thread sospesi */
			last_time_slice = TOD_SNAPSHOT;
			SET_IT(pseudo_count); /* settaggio interval timer con il valore di pseudo clock */
			ENABLE_INTERRUPT;
			for (;;); /* aspetta una interrupt */
		}
	}
	upThread(); /* dispatch di un nuovo thread */
}
Ejemplo n.º 5
0
int main() {
	int i;

	initTcbs();
	addokbuf("Initialized thread control blocks   \n");

	/* Check allocTcb */
	for (i = 0; i < MAXPROC; i++) {
		if ((threadp[i] = allocTcb()) == NULL)
			adderrbuf("allocTcb(): unexpected NULL   ");
	}
	if (allocTcb() != NULL) {
		adderrbuf("allocTcb(): allocated more than MAXPROC entries   ");
	}
	addokbuf("allocTcb ok   \n");

	/* return the last 10 entries back to free list */
	for (i = 10; i < MAXPROC; i++)
		freeTcb(threadp[i]);
	addokbuf("freed 10 entries   \n");

	/* create a 10-element thread queue */
	qa = mkEmptyThreadQ();
	if (!emptyThreadQ(qa)) adderrbuf("emptyThreadQ(qa): unexpected FALSE   ");
	addokbuf("Inserting...   \n");
	for (i = 0; i < 10; i++) {
		if ((q = allocTcb()) == NULL)
			adderrbuf("allocTcb(): unexpected NULL while insert   ");
		switch (i) {
		case 0:
			firstthread = q;
			break;
		case 5:
			midthread = q;
			break;
		case 9:
			lastthread = q;
			break;
		default:
			break;
		}
		insertBackThreadQ(&qa, q);
	}
	addokbuf("inserted 10 elements   \n");

	if (emptyThreadQ(qa)) adderrbuf("emptyThreadQ(qa): unexpected TRUE"   );

	/* Check outThreadQ and headThreadQ */
	if (headThreadQ(qa) != firstthread)
		adderrbuf("headThreadQ(qa) failed   ");
		
	q = outThreadQ(&qa, firstthread);
	if ((q == NULL) || (q != firstthread))
		adderrbuf("outThreadQ(&qa, firstthread) failed on first entry   ");		
	freeTcb(q);
	
	q = outThreadQ(&qa, midthread);
	if (q == NULL || q != midthread)
		adderrbuf("outThreadQ(&qa, midthread) failed on middle entry   ");
	freeTcb(q);

	if (outThreadQ(&qa, threadp[0]) != NULL)
		adderrbuf("outThreadQ(&qa, threadp[0]) failed on nonexistent entry   ");
	addokbuf("outThreadQ() ok   \n");

	/* Check if removeThread and insertThread remove in the correct order */
	addokbuf("Removing...   \n");
	for (i = 0; i < 8; i++) {
		if ((q = removeThreadQ(&qa)) == NULL)
			adderrbuf("removeThreadQ(&qa): unexpected NULL   ");
		freeTcb(q);
	}
	
	if (q != lastthread)
		adderrbuf("removeThreadQ(): failed on last entry   ");
		
	if (removeThreadQ(&qa) != NULL)
		adderrbuf("removeThreadQ(&qa): removes too many entries   ");

  if (!emptyThreadQ(qa))
    adderrbuf("emptyThreadQ(qa): unexpected FALSE   ");

	addokbuf("insertThreadQ(), removeThreadQ() and emptyThreadQ() ok   \n");
	addokbuf("thread queues module ok      \n");

	addokbuf("After all, tomorrow is another day!\n");
  
	return 0;

}