22#ifndef COMMON_COROUTINES_H
23#define COMMON_COROUTINES_H
25#include "common/scummsys.h"
26#include "common/util.h"
27#include "common/list.h"
28#include "common/singleton.h"
44#define CoroScheduler (Common::CoroutineScheduler::instance())
59 const char *_funcName;
95 assert(ctx->_sleep >= 0);
99 if (_ctx && _ctx->_sleep == 0) {
107#define CORO_PARAM Common::CoroContext &coroParam
131#define CORO_BEGIN_CONTEXT \
132 struct CoroContextTag : Common::CoroBaseContext { \
133 CoroContextTag() : CoroBaseContext(SCUMMVM_CURRENT_FUNCTION) { DUMMY = 0; } \
141#define CORO_END_CONTEXT(x) } *x = (CoroContextTag *)coroParam
147#define CORO_BEGIN_CODE(x) \
148 if (&coroParam == &Common::nullContext) assert(!Common::nullContext); \
149 if (!x) { coroParam = x = new CoroContextTag(); } \
151 Common::CoroContextHolder tmpHolder(coroParam); \
152 switch (coroParam->_line) { default: break; case 0:;
157#define CORO_END_CODE \
158 if (&coroParam == &Common::nullContext) { \
159 delete Common::nullContext; \
160 Common::nullContext = NULL; \
167#define CORO_SLEEP(delay) \
169 coroParam->_line = __LINE__; \
170 coroParam->_sleep = delay; \
171 assert(&coroParam != &Common::nullContext); \
172 return; case __LINE__:; \
175#define CORO_GIVE_WAY do { CoroScheduler.giveWay(); CORO_SLEEP(1); } while (0)
176#define CORO_RESCHEDULE do { CoroScheduler.reschedule(); CORO_SLEEP(1); } while (0)
186#define CORO_KILL_SELF() \
187 do { if (&coroParam != &Common::nullContext) { coroParam->_sleep = -1; } return; } while (0)
194#define CORO_SUBCTX coroParam->_subctx
216#define CORO_INVOKE_ARGS(subCoro, ARGS) \
218 coroParam->_line = __LINE__; \
219 coroParam->_subctx = 0; \
222 if (!coroParam->_subctx) break; \
223 coroParam->_sleep = coroParam->_subctx->_sleep; \
224 assert(&coroParam != &Common::nullContext); \
225 return; case __LINE__:; \
235#define CORO_INVOKE_ARGS_V(subCoro, RESULT, ARGS) \
237 coroParam->_line = __LINE__; \
238 coroParam->_subctx = 0; \
241 if (!coroParam->_subctx) break; \
242 coroParam->_sleep = coroParam->_subctx->_sleep; \
243 assert(&coroParam != &Common::nullContext); \
244 return RESULT; case __LINE__:; \
252#define CORO_INVOKE_0(subCoroutine) \
253 CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX))
259#define CORO_INVOKE_1(subCoroutine, a0) \
260 CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0))
266#define CORO_INVOKE_2(subCoroutine, a0,a1) \
267 CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1))
273#define CORO_INVOKE_3(subCoroutine, a0,a1,a2) \
274 CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1, a2))
280#define CORO_INVOKE_4(subCoroutine, a0,a1,a2,a3) \
281 CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1, a2, a3))
286#define CORO_PARAM_SIZE 40
289#define CORO_NUM_PROCESS 100
290#define CORO_MAX_PROCESSES 100
291#define CORO_MAX_PID_WAITING 5
293#define CORO_INFINITE 0xffffffff
294#define CORO_INVALID_PID_VALUE 0
310#ifndef NO_CXX11_ALIGNAS
385 PROCESS *getProcess(uint32 pid);
386 EVENT *getEvent(uint32 pid);
442 uint32 duration,
bool *expired =
nullptr);
Definition: coroutines.h:90
Definition: coroutines.h:330
void(* VFPTRPP)(PROCESS *)
Definition: coroutines.h:333
void resetEvent(uint32 pidEvent)
int killMatchingProcess(uint32 pidKill, int pidMask=-1)
uint32 createEvent(bool bManualReset, bool bInitialState)
PROCESS * createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam)
PROCESS * getCurrentProcess()
void pulseEvent(uint32 pidEvent)
int getCurrentPID() const
void setEvent(uint32 pidEvent)
uint32 createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam)
void closeEvent(uint32 pidEvent)
void reschedule(PPROCESS pReSchedProc=nullptr)
void killProcess(PROCESS *pKillProc)
void sleep(Common::CoroContext &coroParam, uint32 duration)
void giveWay(PPROCESS pReSchedProc=nullptr)
void waitForMultipleObjects(Common::CoroContext &coroParam, int nCount, uint32 *pidList, bool bWaitAll, uint32 duration, bool *expired=nullptr)
uint32 createProcess(CORO_ADDR coroAddr, const void *pParam)
void setResourceCallback(VFPTRPP pFunc)
void waitForSingleObject(Common::CoroContext &coroParam, int pid, uint32 duration, bool *expired=nullptr)
Definition: singleton.h:42
#define CORO_PARAM
Definition: coroutines.h:107
#define CORO_PARAM_SIZE
Definition: coroutines.h:286
void(* CORO_ADDR)(CoroContext &, const void *)
Definition: coroutines.h:297
Definition: algorithm.h:29
Definition: coroutines.h:54
virtual ~CoroBaseContext()
CoroBaseContext(const char *func)
Definition: coroutines.h:319
Definition: coroutines.h:300
CORO_ADDR coroAddr
Entry point of the coroutine.
Definition: coroutines.h:305
char param[40]
Process-specific information.
Definition: coroutines.h:313
PROCESS * pPrevious
Pointer to the previous process in an active or free list.
Definition: coroutines.h:302
int sleepTime
Number of scheduler cycles to sleep.
Definition: coroutines.h:307
uint32 pidWaiting[5]
Process ID(s) that the process is currently waiting on.
Definition: coroutines.h:309
uint32 pid
Process ID.
Definition: coroutines.h:308
CoroContext state
State of the coroutine.
Definition: coroutines.h:304
PROCESS * pNext
Pointer to the next process in an active or free list.
Definition: coroutines.h:301