update vibration handling
[pcsx_rearmed.git] / deps / libretro-common / libco / ps2.c
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  */
11 static int32_t active_thread_id = -1;
12 extern void *_gp;
13
14 cothread_t co_active()
15 {
16   active_thread_id = GetThreadId();
17   return &active_thread_id;
18 }
19
20 cothread_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
47 void co_delete(cothread_t handle)
48 {
49    TerminateThread(*(uint32_t *)handle);
50    DeleteThread(*(uint32_t *)handle);
51    free(handle);
52 }
53
54 void 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 }