COMMON: Improved waiting processes to store what PIDs they're waiting for

This is then used in PulseEvent to only execute processes that are specifically waiting on the given PID, rather than all waiting events.
This commit is contained in:
Paul Gilbert 2012-05-13 00:19:04 +10:00
parent 073e46503c
commit 045f93f0fe
2 changed files with 31 additions and 30 deletions

View File

@ -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;
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;
break;
}
// pCurrent may have been changed
pNext = pCurrent->pNext;
pCurrent = NULL;
}
pProc = pNext;

View File

@ -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;