Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/libco/sjlj-multi.c
2 views
1
#define LIBCO_C
2
#include "libco.h"
3
#include <stdlib.h>
4
#include <setjmp.h>
5
6
#ifdef __cplusplus
7
extern "C" {
8
#endif
9
10
typedef struct
11
{
12
jmp_buf context;
13
coentry_t coentry;
14
void *stack;
15
unsigned long seh_frame, stack_top, stack_bottom;
16
cothread_t caller;
17
} cothread_struct;
18
19
static thread_local cothread_struct co_primary;
20
static thread_local cothread_struct *co_running = 0;
21
22
//-------------------
23
#if defined(_MSC_VER) || defined(MINGW32)
24
25
__declspec(dllimport) cothread_t os_co_create();
26
__declspec(dllimport) void os_pre_setjmp(cothread_t target);
27
__declspec(dllimport) void os_pre_longjmp(cothread_struct* rec);
28
29
#elif defined(__ARM_EABI__) || defined(__ARMCC_VERSION)
30
31
//http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libc/machine/arm/setjmp.S?rev=1.5&content-type=text/x-cvsweb-markup&cvsroot=src
32
33
typedef struct
34
{
35
#ifdef LIBCO_ARM_JUMBLED
36
int r8,r9,r10,r11,lr,r4,r5,r6,r7,sp;
37
#else
38
int r4,r5,r6,r7,r8,r9,r10,fp;
39
#ifndef LIBCO_ARM_NOIP
40
int ip;
41
#endif
42
int sp,lr;
43
#endif
44
} _JUMP_BUFFER;
45
46
static void os_co_create(cothread_struct* rec, unsigned int size, coentry_t coentry)
47
{
48
_JUMP_BUFFER* jb = (_JUMP_BUFFER*)&rec->context;
49
50
jb->sp = (unsigned long)rec->stack + size - 4;
51
jb->lr = (unsigned long)coentry;
52
}
53
54
static void os_pre_setjmp(cothread_t target)
55
{
56
cothread_struct* rec = (cothread_struct*)target;
57
rec->caller = co_running;
58
}
59
60
static void os_pre_longjmp(cothread_struct* rec)
61
{
62
}
63
64
#else
65
#error "sjlj-multi: unsupported processor, compiler or operating system"
66
#endif
67
//-------------------
68
69
cothread_t co_active()
70
{
71
if(!co_running) co_running = &co_primary;
72
return (cothread_t)co_running;
73
}
74
75
cothread_t co_create(unsigned int size, void (*coentry)(void))
76
{
77
cothread_struct *thread;
78
79
if(!co_running) co_running = &co_primary;
80
81
thread = (cothread_struct*)malloc(sizeof(cothread_struct));
82
if(thread)
83
{
84
thread->coentry = coentry;
85
thread->stack = malloc(size);
86
{
87
setjmp(thread->context);
88
os_co_create(thread,size,coentry);
89
}
90
}
91
92
return (cothread_t)thread;
93
}
94
95
void co_delete(cothread_t cothread)
96
{
97
if(cothread)
98
{
99
if(((cothread_struct*)cothread)->stack)
100
{
101
free(((cothread_struct*)cothread)->stack);
102
}
103
free(cothread);
104
}
105
}
106
107
void co_switch(cothread_t cothread)
108
{
109
os_pre_setjmp(cothread);
110
if(!setjmp(co_running->context))
111
{
112
co_running = (cothread_struct*)cothread;
113
os_pre_longjmp(co_running);
114
longjmp(co_running->context,0);
115
}
116
}
117
118
#ifdef __cplusplus
119
}
120
#endif
121
122