startthread.c 2.21 KB
/**************************************************************************
 *									  *
 *		 Copyright (C) 1994, Silicon Graphics, Inc.		  *
 *									  *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright law.  They  may  not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *									  *
 **************************************************************************/

#include "osint.h"

/*
 * osStartThread
 *
 * Enqueue the thread onto the run queue if is waiting for a message,
 * otherwise, restore it to the queue it was on (since this thread
 * was explicitly stopped by osStopThread)
 */
void
osStartThread(OSThread *t)
{
	register u32 saveMask;

	/* Disable interrupts */
	saveMask = __osDisableInt();

	switch (t->state) {
	case OS_STATE_WAITING:
		/* thread t is waiting for a message */
		/* this path is reached by messaging routines */
		t->state = OS_STATE_RUNNABLE;
	       	__osEnqueueThread(&__osRunQueue, t);
		break;
	case OS_STATE_STOPPED:
		/* thread t was stopped by osStopThread */
		if ((t->queue == NULL) || (t->queue == &__osRunQueue)) {
			/* if thread t was just started or pulled out of RunQueue */
			t->state = OS_STATE_RUNNABLE;
			__osEnqueueThread(&__osRunQueue, t);
		} else {
			/* thread t was pulled out of a message queue */
			t->state = OS_STATE_WAITING;
			__osEnqueueThread(t->queue, t);
			/* kick the first thread in the message queue */
			__osEnqueueThread(&__osRunQueue, __osPopThread(t->queue));
		}
		break;
#ifdef _DEBUG
	default:
		__osError(ERR_OSSTARTTHREAD, 0);
		__osRestoreInt(saveMask);
		return;
#endif
	}

	/* determine who gets to execute */
	if (__osRunningThread == NULL)
		__osDispatchThread();
	/*
	 * If the new thread is the highest priority runnable
	 * thread, yield the processor and invoke the dispatcher.
	 */
	else if (__osRunningThread->priority < __osRunQueue->priority) {
		__osRunningThread->state = OS_STATE_RUNNABLE;
		__osEnqueueAndYield(&__osRunQueue);
	}


	/* Restore interrupts */
	__osRestoreInt(saveMask);
}