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()) 58 #ifdef COROUTINE_DEBUG 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 309 uint32 pidWaiting[CORO_MAX_PID_WAITING];
310 #ifndef NO_CXX11_ALIGNAS 385 PROCESS *getProcess(uint32 pid);
386 EVENT *getEvent(uint32 pid);
408 void rescheduleAll();
414 void reschedule(PPROCESS pReSchedProc =
nullptr);
421 void giveWay(PPROCESS pReSchedProc =
nullptr);
430 void waitForSingleObject(
CORO_PARAM,
int pid, uint32 duration,
bool *expired =
nullptr);
441 void waitForMultipleObjects(
CORO_PARAM,
int nCount, uint32 *pidList,
bool bWaitAll,
442 uint32 duration,
bool *expired =
nullptr);
461 PROCESS *createProcess(uint32 pid,
CORO_ADDR coroAddr,
const void *pParam,
int sizeParam);
470 uint32 createProcess(
CORO_ADDR coroAddr,
const void *pParam,
int sizeParam);
478 uint32 createProcess(
CORO_ADDR coroAddr,
const void *pParam);
485 void killProcess(
PROCESS *pKillProc);
495 int getCurrentPID()
const;
505 int killMatchingProcess(uint32 pidKill,
int pidMask = -1);
516 void setResourceCallback(VFPTRPP pFunc);
530 uint32 createEvent(
bool bManualReset,
bool bInitialState);
536 void closeEvent(uint32 pidEvent);
542 void setEvent(uint32 pidEvent);
548 void resetEvent(uint32 pidEvent);
559 void pulseEvent(uint32 pidEvent);
568 #endif // COMMON_COROUTINES_H CoroContext state
State of the coroutine.
Definition: coroutines.h:304
Definition: coroutines.h:319
void(* CORO_ADDR)(CoroContext &, const void *)
Definition: coroutines.h:297
Definition: coroutines.h:330
PROCESS * pPrevious
Pointer to the previous process in an active or free list.
Definition: coroutines.h:302
CoroBaseContext(const char *func)
PROCESS * pNext
Pointer to the next process in an active or free list.
Definition: coroutines.h:301
#define CORO_PARAM
Definition: coroutines.h:107
Definition: coroutines.h:300
Definition: algorithm.h:29
int sleepTime
Number of scheduler cycles to sleep.
Definition: coroutines.h:307
uint32 pid
Process ID.
Definition: coroutines.h:308
Definition: coroutines.h:54
#define CORO_PARAM_SIZE
Definition: coroutines.h:286
Definition: coroutines.h:90
CORO_ADDR coroAddr
Entry point of the coroutine.
Definition: coroutines.h:305
virtual ~CoroBaseContext()
Definition: singleton.h:42