standalone: fix w/h confusion
[pcsx_rearmed.git] / deps / libretro-common / libco / ucontext.c
CommitLineData
3719602c
PC
1/*
2 libco.ucontext (2008-01-28)
3 author: Nach
4 license: public domain
5*/
6
7/*
8 * WARNING: the overhead of POSIX ucontext is very high,
9 * assembly versions of libco or libco_sjlj should be much faster
10 *
11 * This library only exists for two reasons:
12 * 1 - as an initial test for the viability of a ucontext implementation
13 * 2 - to demonstrate the power and speed of libco over existing implementations,
14 * such as pth (which defaults to wrapping ucontext on unix targets)
15 *
16 * Use this library only as a *last resort*
17 */
18
19#define LIBCO_C
20#include <libco.h>
21#include <stdlib.h>
22#include <ucontext.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28static thread_local ucontext_t co_primary;
29static thread_local ucontext_t *co_running = 0;
30
31cothread_t co_active(void)
32{
33 if (!co_running)
34 co_running = &co_primary;
35 return (cothread_t)co_running;
36}
37
38cothread_t co_create(unsigned int heapsize, void (*coentry)(void))
39{
40 ucontext_t *thread;
41 if (!co_running)
42 co_running = &co_primary;
43
44 if ((thread = (ucontext_t*)malloc(sizeof(ucontext_t))))
45 {
46 if ((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize)))
47 {
48 thread->uc_link = co_running;
49 thread->uc_stack.ss_size = heapsize;
50 makecontext(thread, coentry, 0);
51 }
52 else
53 {
54 co_delete((cothread_t)thread);
55 thread = 0;
56 }
57 }
58 return (cothread_t)thread;
59}
60
61void co_delete(cothread_t cothread)
62{
63 if (!cothread)
64 return;
65
66 if (((ucontext_t*)cothread)->uc_stack.ss_sp)
67 free(((ucontext_t*)cothread)->uc_stack.ss_sp);
68 free(cothread);
69}
70
71void co_switch(cothread_t cothread)
72{
73 ucontext_t *old_thread = co_running;
74 co_running = (ucontext_t*)cothread;
75 swapcontext(old_thread, co_running);
76}
77
78#ifdef __cplusplus
79}
80#endif