示例#1
0
/**********************************************************************
														TERMINATE

	Si occupa di:
	-Uccidere root e tutti i figli ricorsivamente
	-Rimettere i thread nella lista dei liberi
	-Togliere i thread dalle varie liste/array in cui sono presenti
	-Decrementare il valore di thread_count
	-Pulire la inbox da eventuali messaggi

**********************************************************************/
void terminate (tcb_t *target) {
	
	msg_t *msg;
	tcb_t *child;

	/* Se ha un padre lo elimino dai suoi figli */
	outChild(target);

	/* Caso ricorsivo -> HA figli (su cui viene chiamata la terminate) */
	while (TRUE) {
		if ( (child = removeChild(target)) == NULL ) break; /* Passa al caso base e pulisce thread, liste, messaggi... */
		terminate(child);
	}

	/* Caso base -> NON ha figli */

	/* Se è in qualche lista o è il thread corrente lo elimino */
	if (((outThread(&ready_queue, target)) != NULL) || (current_thread == target)) {

		/* Pulisco la inbox */
		while (TRUE) {
			if ( (msg = popMessage(&(target->t_inbox), NULL)) == NULL ) break;
			freeMsg(msg);
		}

		/* Se è un manager lo elimino dal trap_managers array */
		delete_manager(target);

		if (current_thread == target) current_thread=NULL;

		/* Restituisco ai thread liberi */
		freeTcb(target);
		thread_count--;
	}

	else if (outThread(&wait_queue, target)) {

		/* Decremento contatore processi in attesa I/O o SSI */	
		if (target->waiting_for == SSI_tcb)
			soft_block_count--;

		/* Tutto come caso precedente*/
		while (TRUE) {
			if ( (msg = popMessage(&(target->t_inbox), NULL)) == NULL ) break;
			freeMsg(msg);
		}

		delete_manager(target);
		freeTcb(target);
		thread_count--;
	}

	else PANIC();
}
示例#2
0
/* inizializza tutti i tcb_t contenuti in tcbTable mettendoli nella lista tcbFree_h,
   rendedoli di fatto tutti disponibili all'utilizzo, questa funzione è chiamata
   solo una volta durante l'inizializzazione delle strutture. */
void initTcbs(void) {
    int i;
    INIT_LIST_HEAD(&tcbFree_h.t_next);
    for (i = 0; i < MAXTHREADS; i++) {
        INIT_LIST_HEAD(&(tcbTable[i].t_inbox));
        freeTcb(&tcbTable[i]);
    }
}
示例#3
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;

}