Esempio n. 1
0
/*
 * The reaper thread.  Its job is to de-allocate memory
 * used by threads which have finished.
 */
static void Reaper(ulong_t arg)
{
    struct Kernel_Thread *kthread;

    Disable_Interrupts();

    while (true) {
	/* See if there are any threads needing disposal. */
	if ((kthread = s_graveyardQueue.head) == 0) {
	    /* Graveyard is empty, so wait for a thread to die. */
	    Wait(&s_reaperWaitQueue);
	}
	else {
	    /* Make the graveyard queue empty. */
	    Clear_Thread_Queue(&s_graveyardQueue);

	    /*
	     * Now we can re-enable interrupts, since we
	     * have removed all the threads needing disposal.
	     */
	    Enable_Interrupts();
	    Yield();   /* allow other threads to run? */

	    /* Dispose of the dead threads. */
	    while (kthread != 0) {
		struct Kernel_Thread* next = Get_Next_In_Thread_Queue(kthread);
#if 0
		Print("Reaper: disposing of thread @ %x, stack @ %x\n",
		    kthread, kthread->stackPage);
#endif
		Destroy_Thread(kthread);
		kthread = next;
	    }

	    /*
	     * Disable interrupts again, since we're going to
	     * do another iteration.
	     */
	    Disable_Interrupts();
	}
    }
}
Esempio n. 2
0
	DC_ID CScriptModule::Resume_Thread(DC_ID ThreadID) {
		THREAD_MAP_ITER iFind = m_Threads.find(ThreadID);
		
		if( iFind == m_Threads.end() ) {
			Log(LOG_SCRIPT, "Invalid Thread ID: %d\n", ThreadID);
			return DC_INVALID_ID;
		}
		
		CThread* pThread = iFind->second;
		
		// Do the resume
		
		int status = lua_resume( pThread->m_pState, NULL, 0);
		if(status == LUA_YIELD) {
			return pThread->GetID();
		} else if( status == 0 ) {
			// Thread exited normally
			Destroy_Thread(pThread->GetID());
			return DC_INVALID_ID;
		}
		return DC_INVALID_ID;
	}
Esempio n. 3
0
	DC_ID CScriptModule::Call_Threaded_Script_Method(const char* func, const char* sig, ...) {
		va_list vl;
		int narg, nres;
		
		// New Thread
		CThread* pNewThread = Create_Thread();
		lua_State* pThread = pNewThread->m_pState;
		
		// Push the method
		lua_getglobal( pThread, func );
		
		va_start(vl, sig);
		
		narg = 0;
		while (*sig) {
			switch (*sig++) {
				case 'd': {
					lua_pushnumber(pThread, va_arg(vl, double));
					break;
				}
				case 'i': {
					lua_pushnumber(pThread, va_arg(vl, int));
					break;
				}
				case 's': {
					lua_pushstring(pThread, va_arg(vl, char *));
					break;
				}
				case '>': {
					goto endwhile;
				}
				default: {
					break;
				}
			}
			narg++;
			luaL_checkstack(pThread, 1, "Too many arguments\n");
		} endwhile:
	
		nres = strlen(sig);
		
		int status = lua_resume( pThread, NULL, narg );
		
		// Thread exited normally
		if( status == 0 ) {
			DLog(LOG_SCRIPT, "Thread exited normally\n");
		} else if( status == LUA_YIELD ) {
			DLog(LOG_SCRIPT, "Thread yielded\n");
		} else {
			// TODO: check the stack here
			
			string errmsg = lua_tostring( pThread, -1 );
			Log( LOG_SCRIPT, "Error running thread: %s\n", errmsg.c_str() );
			lua_pop( pThread, 1 );
			return DC_INVALID_ID;
		}
		
		nres = -nres;
		while (*sig) {
			switch (*sig++) {
				case 'd': {
					if (!lua_isnumber(pThread, nres)) {
						DLog(LOG_SCRIPT, "Wrong result type\n");
					}
					*va_arg(vl, double *) = lua_tonumber(pThread, nres);
					break;
				}
				case 'i': {
					if (!lua_isnumber(pThread, nres)) {
						DLog(LOG_SCRIPT, "Wrong result type\n");
					}
					*va_arg(vl, int *) = (int)lua_tonumber(pThread, nres);
					break;
				}
				case 's': {
					if (!lua_isstring(pThread, nres)) {
						DLog(LOG_SCRIPT, "Wrong result type\n");
					}
					*va_arg(vl, const char **) = lua_tostring(pThread, nres);
					break;
				}
				default: {
					DLog(LOG_SCRIPT, "Invalid option\n");
				}
			}
			nres++;
		}
		va_end(vl);
		
		if( status ==0 ) {
			Destroy_Thread(pNewThread->GetID());
			return DC_INVALID_ID;
		} else {
			return pNewThread->GetID();
		}

		
	}