aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/coroutines.cpp58
-rw-r--r--common/coroutines.h3
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;