X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=deps%2Flibretro-common%2Flibco%2Fscefiber.c;fp=deps%2Flibretro-common%2Flibco%2Fscefiber.c;h=0a2407301b0d58b5dfa14ad2884c78d0890980cd;hb=3719602cbe883fb394a71353e20a10a4a306e814;hp=0000000000000000000000000000000000000000;hpb=8659d7fd2cdb11f63724ead0997f47f4c694f8c2;p=pcsx_rearmed.git diff --git a/deps/libretro-common/libco/scefiber.c b/deps/libretro-common/libco/scefiber.c new file mode 100644 index 00000000..0a240730 --- /dev/null +++ b/deps/libretro-common/libco/scefiber.c @@ -0,0 +1,92 @@ +/* + libco.win (2016-09-06) + authors: frangarcj + license: public domain +*/ + +#define LIBCO_C +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static thread_local cothread_t co_active_ = 0; + +typedef struct SceFiber +{ + char reserved[128]; +} SceFiber __attribute__( ( aligned ( 8 ) ) ) ; + +/* Forward declarations */ +int32_t _sceFiberInitializeImpl(SceFiber *fiber, char *name, void *entry, uint32_t argOnInitialize, + void* addrContext, int32_t sizeContext, void* params); +int32_t sceFiberFinalize(SceFiber* fiber); +int32_t sceFiberRun(SceFiber* fiber, uint32_t argOnRunTo, uint32_t* argOnRun); +int32_t sceFiberSwitch(SceFiber* fiber, uint32_t argOnRunTo, uint32_t* argOnRun); +int32_t sceFiberReturnToThread(uint32_t argOnReturn, uint32_t* argOnRun); + +static void co_thunk(uint32_t argOnInitialize, uint32_t argOnRun) +{ + ((void (*)(void))argOnInitialize)(); +} + +cothread_t co_active(void) +{ + if (!co_active_) + { + sceSysmoduleLoadModule(SCE_SYSMODULE_FIBER); + co_active_ = (cothread_t)1; + } + return co_active_; +} + +cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) +{ + int ret; + SceFiber* tail_fiber = malloc(sizeof(SceFiber)); + char * m_ctxbuf = malloc(sizeof(char)*heapsize); + if (!co_active_) + { + sceSysmoduleLoadModule(SCE_SYSMODULE_FIBER); + co_active_ = (cothread_t)1; + } + + /* _sceFiberInitializeImpl */ + if ((ret = _sceFiberInitializeImpl( + tail_fiber, "tailFiber", co_thunk, + (uint32_t)coentry, (void*)m_ctxbuf, heapsize, NULL)) == 0) + return (cothread_t)tail_fiber; + return (cothread_t)ret; +} + +void co_delete(cothread_t cothread) +{ + if (cothread != (cothread_t)1) + sceFiberFinalize((SceFiber*)cothread); +} + +void co_switch(cothread_t cothread) +{ + uint32_t argOnReturn = 0; + if (cothread == (cothread_t)1) + { + co_active_ = cothread; + sceFiberReturnToThread(0, NULL); + } + else + { + SceFiber* theFiber = (SceFiber*)cothread; + co_active_ = cothread; + if (co_active_ == (cothread_t)1) + sceFiberRun(theFiber, 0, &argOnReturn); + else + sceFiberSwitch(theFiber, 0, &argOnReturn); + } +} + +#ifdef __cplusplus +} +#endif