blob: 485d7464a59d6832676425190af9927bd9082504 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
|
{$IFDEF OGC_INTERFACE}
//#define _LWPTHREADS_DEBUG
const
LWP_TIMESLICE_TIMER_ID = $00070040;
const
LWP_CPU_BUDGET_ALGO_NONE = 0;
LWP_CPU_BUDGET_ALGO_TIMESLICE = 1;
type
lwp_cpu_budget_algorithms = Integer;
type
_lwpwaitinfo = record
id : cuint32;
cnt : cuint32;
ret_arg : pointer;
ret_arg_1 : pointer;
option : cuint32;
ret_code : cuint32;
block2n : lwp_queue;
queue : Plwp_thrqueue;
end;
lwp_waitinfo = _lwpwaitinfo;
type
Tentry = function(par0: pointer): pointer; cdecl;
_lwpcntrl = record
object_ : lwp_obj;
cur_prio : cuint8;
real_prio : cuint8;
suspendcnt : cuint32;
res_cnt : cuint32;
isr_level : cuint32;
cur_state : cuint32;
cpu_time_budget : cuint32;
budget_algo : lwp_cpu_budget_algorithms;
is_preemptible : cbool;
wait : lwp_waitinfo;
priomap : prio_cntrl;
timer : wd_cntrl;
entry : TEntry;
arg : pointer;
stack : pointer;
stack_size : cuint32;
stack_allocated : cuint8;
ready : Plwp_queue;
join_list : lwp_thrqueue;
context : frame_context; //16
libc_reent : pointer;
end;
lwp_cntrl = _lwpcntrl;
lwp_cntrl_t = ^_lwpcntrl;
plwp_cntrl = ^_lwpcntrl;
var
_thr_main : Plwp_cntrl; external;
_thr_idle : Plwp_cntrl; external;
_thr_executing : Plwp_cntrl; external;
_thr_heir : Plwp_cntrl; external;
_thr_allocated_fp : Plwp_cntrl; external;
_context_switch_want : cuint32; external;
_thread_dispatch_disable_level : cuint32; external;
_lwp_wd_timeslice : wd_cntrl; external;
__lwp_thr_libc_reent : Ppointer; external;
_lwp_thr_ready: array [0..0] of lwp_queue; external;
procedure __thread_dispatch; cdecl; external;
procedure __lwp_thread_yield; cdecl; external;
procedure __lwp_thread_closeall; cdecl; external;
procedure __lwp_thread_setstate(par0: Plwp_cntrl; par1: cuint32); cdecl; external;
procedure __lwp_thread_clearstate(par0: Plwp_cntrl; par1: cuint32); cdecl; external;
procedure __lwp_thread_changepriority(par0: Plwp_cntrl; par1, par2: cuint32); cdecl; external;
procedure __lwp_thread_setpriority(par0: Plwp_cntrl; par1: cuint32); cdecl; external;
procedure __lwp_thread_settransient(par0: Plwp_cntrl); cdecl; external;
procedure __lwp_thread_suspend(par0: Plwp_cntrl); cdecl; external;
procedure __lwp_thread_resume(par0: Plwp_cntrl; par1: cuint32); cdecl; external;
procedure __lwp_thread_loadenv(par0: Plwp_cntrl); cdecl; external;
procedure __lwp_thread_ready(par0: Plwp_cntrl); cdecl; external;
function __lwp_thread_init(par0: Plwp_cntrl; par1: pointer;
par2, par3, par4: cuint32; par5: cbool): cuint32; cdecl; external;
function __lwp_thread_start(par0: Plwp_cntrl; par1: TEntry;
par2: pointer): cuint32; cdecl; external;
procedure __lwp_thread_exit(par0: pointer); cdecl; external;
procedure __lwp_thread_close(par0: Plwp_cntrl); cdecl; external;
procedure __lwp_thread_startmultitasking; cdecl; external;
type
TExitFunc = procedure; cdecl;
procedure __lwp_thread_stopmultitasking(exitfunc: TExitFunc); cdecl; external;
function __lwp_thread_getobject(par0: Plwp_cntrl): Plwp_obj; cdecl; external;
function __lwp_evaluatemode: cuint32; cdecl; external;
function __lwp_isr_in_progress: cuint32; cdecl; external;
procedure __lwp_thread_resettimeslice; cdecl; external;
procedure __lwp_rotate_readyqueue(par0: cuint32); cdecl; external;
procedure __lwp_thread_delayended(par0: pointer); cdecl; external;
procedure __lwp_thread_tickle_timeslice(par0: pointer); cdecl; external;
//#ifdef LIBOGC_INTERNAL
//#include <libogc/lwp_threads.inl>
//#endif
procedure __lwp_thread_dispatchdisable(); inline;
{$ENDIF}
{$IFDEF OGC_IMPLEMENTATION}
function __lwp_thread_isexec(thethread: plwp_cntrl): cuint32;
begin
result := 0;
if (thethread = _thr_executing) then result := 1;
end;
function __lwp_thread_isheir(thethread: plwp_cntrl): cuint32;
begin
result := 0;
if (thethread = _thr_heir) then result := 1;
end;
procedure __lwp_thread_calcheir();
begin
_thr_heir := plwp_cntrl(_lwp_thr_ready[__lwp_priomap_highest()].first);
//#ifdef _LWPTHREADS_DEBUG
// printf("__lwp_thread_calcheir(%p)\n",_thr_heir);
//#endif
end;
function __lwp_thread_isallocatedfp(thethread: plwp_cntrl): cuint32;
begin
result := 0;
if (thethread = _thr_allocated_fp) then result := 1;
end;
procedure __lwp_thread_deallocatefp();
begin
_thr_allocated_fp := nil;
end;
procedure __lwp_thread_dispatchinitialize();
begin
_thread_dispatch_disable_level := 1;
end;
procedure __lwp_thread_dispatchenable();
begin
dec(_thread_dispatch_disable_level);
if (_thread_dispatch_disable_level = 0) then
__thread_dispatch();
end;
procedure __lwp_thread_dispatchdisable();
begin
inc(_thread_dispatch_disable_level);
end;
procedure __lwp_thread_dispatchunnest();
begin
dec(_thread_dispatch_disable_level);
end;
procedure __lwp_thread_unblock(thethread: plwp_cntrl);
begin
__lwp_thread_clearstate(thethread, LWP_STATES_BLOCKED);
end;
function __lwp_thread_getlibcreent(): pointer;
begin
result := __lwp_thr_libc_reent;
end;
procedure __lwp_thread_setlibcreent(libc_reent: pointer);
begin
__lwp_thr_libc_reent := libc_reent;
end;
function __lwp_thread_isswitchwant(): cbool;
begin
result := cbool(_context_switch_want);
end;
function __lwp_thread_isdispatchenabled(): cbool;
begin
result := (_thread_dispatch_disable_level = 0);
end;
procedure __lwp_thread_inittimeslice();
begin
__lwp_wd_initialize(@_lwp_wd_timeslice, @__lwp_thread_tickle_timeslice, LWP_TIMESLICE_TIMER_ID, nil);
end;
procedure __lwp_thread_starttimeslice();
begin
__lwp_wd_insert_ticks(@_lwp_wd_timeslice, millisecs_to_ticks(1));
end;
procedure __lwp_thread_stoptimeslice();
begin
__lwp_wd_remove_ticks(@_lwp_wd_timeslice);
end;
//procedure __lwp_thread_dispatchdisable(); inline;
//begin
// inc(_thread_dispatch_disable_level);
//end;
{$ENDIF}
|