Skip to content

Commit

Permalink
COMMON: Improved waiting processes to store what PIDs they're waiting…
Browse files Browse the repository at this point in the history
… for

This is then used in PulseEvent to only execute processes that are specifically waiting on the given PID, rather than all waiting events.
  • Loading branch information
dreammaster committed May 12, 2012
1 parent 073e465 commit 045f93f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 30 deletions.
58 changes: 29 additions & 29 deletions common/coroutines.cpp
Expand Up @@ -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 {

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand All @@ -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
Expand All @@ -521,9 +520,6 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) {
CORO_SLEEP(1);
}

// Signal waiting is done
pCurrent->waiting = false;

CORO_END_CODE;
}

Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion common/coroutines.h
Expand Up @@ -278,6 +278,7 @@ class CoroContextHolder {
// 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
Expand All @@ -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;
Expand Down

0 comments on commit 045f93f

Please sign in to comment.