diff options
| -rw-r--r-- | common/coroutines.cpp | 58 | ||||
| -rw-r--r-- | common/coroutines.h | 3 | 
2 files changed, 31 insertions, 30 deletions
| diff --git a/common/coroutines.cpp b/common/coroutines.cpp index fff6198c22..5a2baccfae 100644 --- a/common/coroutines.cpp +++ b/common/coroutines.cpp @@ -20,8 +20,9 @@   */  #include "common/coroutines.h" -#include "common/textconsole.h" +#include "common/algorithm.h"  #include "common/system.h" +#include "common/textconsole.h"  namespace Common { @@ -159,7 +160,7 @@ void CoroutineScheduler::reset() {  	while (pProc != NULL) {  		delete pProc->state;  		pProc->state = 0; -		pProc->waiting = false; +		Common::fill(&pProc->pidWaiting[0], &pProc->pidWaiting[CORO_MAX_PID_WAITING], 0);  		pProc = pProc->pNext;  	} @@ -373,8 +374,8 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio  	CORO_BEGIN_CODE(_ctx); -	// Signal as waiting -	pCurrent->waiting = true; +	// Signal the process Id this process is now waiting for +	pCurrent->pidWaiting[0] = pid;  	_ctx->endTime = (duration == CORO_INFINITE) ? CORO_INFINITE : g_system->getMillis() + duration;  	if (expired) @@ -412,7 +413,7 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio  	}  	// Signal waiting is done -	pCurrent->waiting = false; +	Common::fill(&pCurrent->pidWaiting[0], &pCurrent->pidWaiting[CORO_MAX_PID_WAITING], 0);  	CORO_END_CODE;  } @@ -442,8 +443,9 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *  	CORO_BEGIN_CODE(_ctx); -	// Signal as waiting -	pCurrent->waiting = true; +	// Signal the waiting events +	assert(nCount < CORO_MAX_PID_WAITING); +	Common::copy(pidList, pidList + nCount, pCurrent->pidWaiting);  	_ctx->endTime = (duration == CORO_INFINITE) ? CORO_INFINITE : g_system->getMillis() + duration;  	if (expired) @@ -487,7 +489,7 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *  	}  	// Signal waiting is done -	pCurrent->waiting = false; +	Common::fill(&pCurrent->pidWaiting[0], &pCurrent->pidWaiting[CORO_MAX_PID_WAITING], 0);  	CORO_END_CODE;  } @@ -510,9 +512,6 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) {  	CORO_BEGIN_CODE(_ctx); -	// Signal as waiting -	pCurrent->waiting = true; -  	_ctx->endTime = g_system->getMillis() + duration;  	// Outer loop for doing checks until expiry  @@ -521,9 +520,6 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) {  		CORO_SLEEP(1);  	} -	// Signal waiting is done -	pCurrent->waiting = false; -  	CORO_END_CODE;  } @@ -848,23 +844,27 @@ void CoroutineScheduler::pulseEvent(uint32 pidEvent) {  		pNext = pProc->pNext;  		// Only call processes that are currently waiting (either in waitForSingleObject or -		// waitForMultipleObjects). If one is found, execute it immediately -		if (pProc->waiting) { -			// Dispatch the process -			pCurrent = pProc; -			pProc->coroAddr(pProc->state, pProc->param); +		// waitForMultipleObjects) for the given event Pid +		for (int i = 0; i < CORO_MAX_PID_WAITING; ++i) { +			if (pProc->pidWaiting[i] == pidEvent) { +				// Dispatch the process +				pCurrent = pProc; +				pProc->coroAddr(pProc->state, pProc->param); + +				if (!pProc->state || pProc->state->_sleep <= 0) { +					// Coroutine finished +					pCurrent = pCurrent->pPrevious; +					killProcess(pProc); +				} else { +					pProc->sleepTime = pProc->state->_sleep; +				} + +				// pCurrent may have been changed +				pNext = pCurrent->pNext; +				pCurrent = NULL; -			if (!pProc->state || pProc->state->_sleep <= 0) { -				// Coroutine finished -				pCurrent = pCurrent->pPrevious; -				killProcess(pProc); -			} else { -				pProc->sleepTime = pProc->state->_sleep; +				break;  			} - -			// pCurrent may have been changed -			pNext = pCurrent->pNext; -			pCurrent = NULL;  		}  		pProc = pNext; diff --git a/common/coroutines.h b/common/coroutines.h index 3303028e1c..80748e352d 100644 --- a/common/coroutines.h +++ b/common/coroutines.h @@ -278,6 +278,7 @@ public:  // the maximum number of processes  #define	CORO_NUM_PROCESS	100  #define CORO_MAX_PROCESSES	100 +#define CORO_MAX_PID_WAITING 5  #define CORO_INFINITE 0xffffffff  #define CORO_INVALID_PID_VALUE 0 @@ -294,7 +295,7 @@ struct PROCESS {  	int sleepTime;		///< number of scheduler cycles to sleep  	uint32 pid;			///< process ID -	bool waiting;		///< process is currently in a waiting state +	uint32 pidWaiting[CORO_MAX_PID_WAITING];	///< Process ID(s) process is currently waiting on  	char param[CORO_PARAM_SIZE];	///< process specific info  };  typedef PROCESS *PPROCESS; | 
