aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2012-05-13 00:19:04 +1000
committerPaul Gilbert2012-05-17 20:45:31 +1000
commit8153d7868b048bcea6df6e8e6c8227ccda0b83dc (patch)
tree73637348a1f393427cd6f7b8669ad98dabb071be
parentac20e271730462aeb1006683a22aca2b9ab25f66 (diff)
downloadscummvm-rg350-8153d7868b048bcea6df6e8e6c8227ccda0b83dc.tar.gz
scummvm-rg350-8153d7868b048bcea6df6e8e6c8227ccda0b83dc.tar.bz2
scummvm-rg350-8153d7868b048bcea6df6e8e6c8227ccda0b83dc.zip
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.
-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;