git subrepo pull --force deps/lightrec
[pcsx_rearmed.git] / deps / libretro-common / libco / ps2.c
CommitLineData
3719602c
PC
1#define LIBCO_C
2#include "libco.h"
3
4#include <stdlib.h>
5#include <stdint.h>
6#include <kernel.h>
7
8/* Since cothread_t is a void pointer it must contain an address. We can't return a reference to a local variable
9 * because it would go out of scope, so we create a static variable instead so we can return a reference to it.
10 */
11static int32_t active_thread_id = -1;
12extern void *_gp;
13
14cothread_t co_active()
15{
16 active_thread_id = GetThreadId();
17 return &active_thread_id;
18}
19
20cothread_t co_create(unsigned int size, void (*entrypoint)(void))
21{
22 /* Similar scenario as with active_thread_id except there will only be one active_thread_id while there could be many
23 * new threads each with their own handle, so we create them on the heap instead and delete them manually when they're
24 * no longer needed in co_delete().
25 */
26 ee_thread_t thread;
27 int32_t new_thread_id;
28 cothread_t handle = malloc(sizeof(cothread_t));
29 void *threadStack = (void *)malloc(size);
30
31 if (!threadStack)
32 return -1;
33
34 thread.stack_size = size;
35 thread.gp_reg = &_gp;
36 thread.func = (void *)entrypoint;
37 thread.stack = threadStack;
38 thread.option = 0;
39 thread.initial_priority = 1;
40
41 new_thread_id = CreateThread(&thread);
42 StartThread(new_thread_id, NULL);
43 *(uint32_t *)handle = new_thread_id;
44 return handle;
45}
46
47void co_delete(cothread_t handle)
48{
49 TerminateThread(*(uint32_t *)handle);
50 DeleteThread(*(uint32_t *)handle);
51 free(handle);
52}
53
54void co_switch(cothread_t handle)
55{
56 WakeupThread(*(uint32_t *)handle);
57 /* Sleep the currently active thread so the new thread can start */
58 SleepThread();
59}