-
Notifications
You must be signed in to change notification settings - Fork 6
/
kernel.h
522 lines (450 loc) · 14.3 KB
/
kernel.h
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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
/***************************************************************************
*
* Copyright (c) 1997, 1998 Timpanogas Research Group, Inc. All Rights
* Reserved.
*
* AUTHOR : Jeff V. Merkey
* FILE : KERNEL.H
* DESCRIP : Multi-Processing Kernel for MANOS v1.0
* DATE : December 10, 1997
*
*
***************************************************************************/
#include "types.h"
#include "version.h"
#define KERNEL_DEBUG 0
#define RWLOCK_TRACE 1
#define LWP_INACTIVE 0
#define LWP_ACTIVE 1
#define LWP_RUNNING 2
#define USER_MEMORY 0x00000000
#define KERNEL_MEMORY 0xFEEDBEEF
#define PROCESS_SIGNATURE 0xBEEFBEEF
#define SEMA_SIGNATURE 0xC0EDBEEF
#define LSEMA_SIGNATURE 0xC0EDBEFF
#define MUTEX_SIGNATURE 0xC1EDBEEF
#define LMUTEX_SIGNATURE 0xC1EDBEFF
#define RWLOCK_SIGNATURE 0xC2EDBEEF
#define LRWLOCK_SIGNATURE 0xC2EDBEFF
#define STACK_END 0xDEADBEEF
#define IDLE_THREAD 1
#define KERNEL_THREAD 2
#define PS_INIT 0
#define PS_ACTIVE 1
#define PS_SLEEP 2
#define PS_SYNC 3
#define PS_LWP 4
#define PS_HALT 5
#define PS_SHUTDOWN 6
#define PS_SWAPPED 7
#define PROCESS_DELAYED 0x000000C1
#define PROCESS_AWAKENED 0x000000C2
#define PROCESS_BLOCKED_KEYBOARD 0x000000C3
#define PROCESS_BLOCKED_SYNC 0x000000C4
#define PROCESS_READER_BLOCKED_SYNC 0x000000C5
#define PROCESS_WRITER_BLOCKED_SYNC 0x000000C6
#if (IA32_OPCODE)
// 128 bytes total size numeric register context
typedef struct _NPXREG {
WORD sig0; // 10 bytes total size this structure
WORD sig1;
WORD sig2;
WORD sig3;
WORD exponent:15;
WORD sign:1;
} NUMERIC_REGISTER_CONTEXT;
typedef struct _NPX {
LONG control;
LONG status;
LONG tag;
LONG eip;
LONG cs;
LONG dataptr;
LONG datasel;
NUMERIC_REGISTER_CONTEXT reg[8]; // 80 bytes
LONG pad[5];
} NUMERIC_FRAME;
// 128 bytes total size register context
typedef struct _CONTEXT_FRAME {
WORD cBackLink;
WORD cTSSReserved;
LONG cESP0;
WORD cSS0;
WORD cSS0res;
LONG cESP1;
WORD cSS1;
WORD cSS1res;
LONG cESP2;
WORD cSS2;
WORD cSS2res;
LONG cCR3;
LONG cEIP;
LONG cSystemFlags;
LONG cEAX;
LONG cECX;
LONG cEDX;
LONG cEBX;
LONG cESP;
LONG cEBP;
LONG cESI;
LONG cEDI;
LONG cES;
LONG cCS;
LONG cSS;
LONG cDS;
LONG cFS;
LONG cGS;
LONG cLDT;
LONG cIOPermissMap;
LONG pad[6];
} CONTEXT_FRAME;
#endif
// NOTE: these structures (SEMA, PROCESS) are also contained in kernel.inc
// If you change these structures, then you must change them there
// as well
typedef struct _SEMA {
struct _SEMA *next;
struct _SEMA *prior;
struct _SEMA *kernelNext;
struct _SEMA *kernelPrior;
long sema_value;
void *sema_head;
void *sema_tail;
LONG sema_mutex;
LONG sema_waiters;
LONG sema_signature;
LONG timerID;
} sema_t;
// general purpose sync structure
typedef struct _SYNC {
struct _SYNC *next;
struct _SYNC *prior;
struct _SYNC *kernelNext;
struct _SYNC *kernelPrior;
LONG value;
LONG mutex;
LONG waiters;
LONG signature;
LONG owner;
LONG owner_count;
} sync_t;
// general purpose sync structure
typedef struct _SYNC_Q {
struct _SYNC_Q *next;
struct _SYNC_Q *prior;
struct _SYNC_Q *kernelNext;
struct _SYNC_Q *kernelPrior;
LONG value;
void *head;
void *tail;
LONG mutex;
LONG waiters;
LONG signature;
LONG owner;
LONG owner_count;
} sync_q_t;
// general purpose sync structure
#if RWLOCK_TRACE
#define READER_LOCK 0x11
#define READER_UNLOCK 0x21
#define READER_SLEEP 0x31
#define READER_WAKE 0x41
#define WRITER_LOCK 0x51
#define WRITER_UNLOCK 0x61
#define WRITER_SLEEP 0x71
#define WRITER_WAKE 0x81
#define WRITER_TO_READER 0x91
#define READER_TO_WRITER 0xA1
#define RREAD_LOCK 0xB1
#define RREAD_TRY_LOCK 0xC1
#define RREAD_UNLOCK 0xD1
#define WWRITE_LOCK 0xE1
#define WWRITE_TRY_LOCK 0xF1
#define WWRITE_UNLOCK 0x1F
#define WWRITER_TO_READER 0x2F
#define RREADER_TO_WRITER 0x3F
#endif
typedef struct _RW_Q {
struct _RW_Q *next;
struct _RW_Q *prior;
struct _RW_Q *kernelNext;
struct _RW_Q *kernelPrior;
LONG readers;
LONG writers;
void *head;
void *tail;
LONG mutex;
LONG waiters;
LONG signature;
LONG owner;
LONG owner_count;
LONG flags;
#if RWLOCK_TRACE
LONG RWProcess[256];
LONG RWTarget[256];
LONG RWOp[256];
LONG RWTime[256];
LONG RWType[256];
LONG RWIndex;
#endif
} rw_q_t;
typedef sync_t spin_t;
typedef sync_q_t mutex_t;
typedef sync_q_t rmutex_t;
typedef rw_q_t rwlock_t;
typedef struct _PROCESS_CONTROL {
struct _PROCESS_CONTROL *next;
struct _PROCESS_CONTROL *prior;
struct _PROCESS_CONTROL *kernelNext;
struct _PROCESS_CONTROL *kernelPrior;
struct _PROCESS_CONTROL *syncNext;
struct _PROCESS_CONTROL *syncPrior;
LONG processID;
LONG typeID;
LONG *stackPointer;
LONG *stackLimit;
LONG *stackEnd;
LONG processSignature;
LONG refCount;
LONG threadMutex;
LONG processorBinding;
LONG realTimePriority;
LONG inheritedPriority;
LONG setMemberPriority;
BYTE processName[64];
LONG (*startAddress)(struct _PROCESS_CONTROL *);
void *startParm;
LONG utilizationCount;
LONG threadState;
LONG threadType;
LONG threadFlags;
LONG codeSegment;
LONG threadDataArea[10];
LONG lastProcessor;
LONG resourceFlag;
LONG threadSemaphore;
LONG threadUtilization;
// NOTE: this section mirrors a timer control block
// if you change the timer comtrol block structure
// in timer.h, then you must change this structure
// as well and in context.386.
void *delayNext;
void *delayPrior;
LONG delaySignature;
LONG delayWaitTime;
LONG delayCurrTime;
void *delayParameter;
void (*delayFunction)(void *);
LONG delayFlags;
LONG delayStamp;
LONG keyBuffer;
LONG typeAheadCount;
LONG threadSubUtil;
LONG threadPreempt;
LONG bindswFlags;
CONTEXT_FRAME ProcessContext;
NUMERIC_FRAME NumericContext;
void *ModuleContext;
void *AddressSpace;
sema_t thread_sema;
void *syncObject;
LONG syncState;
LONG syncFlag;
} PROCESS;
typedef struct _LIGHT_WEIGHT_PROCESS {
struct _LIGHT_WEIGHT_PROCESS *next;
struct _LIGHT_WEIGHT_PROCESS *prior;
LONG (*procedureAddress)(void *);
LONG lwpState;
LONG lwpDelay;
LONG lwpFlags;
void *lwpArgument;
} LWP;
typedef struct _PROCESSOR_QUEUE {
PROCESS *idle_process;
PROCESS *running_process;
PROCESS *local_queue_head;
PROCESS *local_queue_tail;
PROCESS *bind_queue_head;
PROCESS *bind_queue_tail;
LONG bind_queue_mutex;
LWP *lwp_queue_head;
LWP *lwp_queue_tail;
LWP *lwp_bind_queue_head;
LWP *lwp_bind_queue_tail;
LONG lwp_bind_queue_mutex;
LWP *soft_int_head;
LWP *soft_int_tail;
LONG soft_int_mutex;
LWP *fast_lwp_head;
LWP *fast_lwp_tail;
LONG fast_lwp_mutex;
PROCESS *lwp_worker_queue_head;
PROCESS *lwp_worker_queue_tail;
LONG local_queue_count;
LONG bind_queue_count;
LONG lwp_queue_count;
LONG lwpExecCount;
LONG idleCount;
LONG utilizationCount;
LONG sampleCount;
LONG processorUtilization;
LONG eligibleCount;
LONG activeCount;
LONG lwpProcessCounter;
LONG sleepDisallowed;
LONG processorNumber;
PROCESS *bindsw_queue_head;
PROCESS *bindsw_queue_tail;
LONG bindsw_queue_mutex;
void *ModuleContext;
void *AddressSpace;
} PROCESSOR_SET;
extern PROCESSOR_SET *ptable[MAX_PROCESSORS];
extern PROCESSOR_SET processorSet[MAX_PROCESSORS];
extern PROCESS idle_p[MAX_PROCESSORS];
extern PROCESS *dispatch_queue_head;
extern PROCESS *dispatch_queue_tail;
extern LONG dispatch_queue_mutex;
extern LWP *lwp_dispatch_queue_head;
extern LWP *lwp_dispatch_queue_tail;
extern LONG lwp_dispatch_queue_mutex;
extern LONG dispatch_queue_count;
extern LONG lwp_dispatch_queue_count;
extern PROCESS *get_dispatch(void);
extern void put_dispatch(PROCESS *p);
PROCESS *get_rundown(void);
void put_rundown(PROCESS *p);
extern PROCESS *get_local(LONG proc);
extern void put_local(PROCESS *p, LONG proc);
extern PROCESS *get_bind(LONG proc);
extern void put_bind(PROCESS *p, LONG proc);
extern void put_bind_pset(PROCESS *p, PROCESSOR_SET *pset);
extern PROCESS *get_bindsw(LONG proc);
extern void put_bindsw(PROCESS *p, LONG proc);
extern LWP *get_lwp_bind(LONG proc);
extern void put_lwp_bind(LWP *p, LONG proc);
extern LWP *get_dispatch_lwp(void);
extern void put_dispatch_lwp(LWP *p);
extern LWP *get_local_lwp(LONG proc);
extern void put_local_lwp(LWP *p, LONG proc);
extern void thread_switch(void);
extern void thread_switch_target(PROCESS *p);
extern PROCESS *get_running_process(void);
extern void idle_loop(LONG p);
extern switch_process_context(PROCESS *p, PROCESS *t);
extern preempt_restore(PROCESS *target);
PROCESS *get_lwp_thread(LONG proc);
void put_lwp_thread(PROCESS *p, LONG proc);
extern LONG close_processor(LONG p);
extern void processor_init(LONG p);
extern LONG activate_processor(LONG p);
extern void processor_exit(LONG p);
extern PROCESS *commandP;
extern LONG LWPCount;
extern void LWPProcess(LONG proc);
extern void EnterDebugger(void);
extern PROCESS *get_free_process(void);
extern void put_free_process(PROCESS *p);
extern void remove_process(PROCESS *p);
extern void insert_process(PROCESS *p);
extern void threadCleanup(PROCESS *p);
extern void threadStart(PROCESS *p);
extern PROCESS *createThread(BYTE *name, LONG (*start)(), LONG stackSize, void *parm, LONG bind);
extern PROCESS *createThreadContext(BYTE *name, LONG (*start)(), LONG stackSize, void *parm, LONG bind);
extern PROCESS *sleepThread(void);
extern LONG rescheduleThread(PROCESS *p);
extern LONG killThread(PROCESS *p);
extern LONG delayThread(LONG delay);
extern LONG scheduleLocalLWP(LWP *lwp);
extern LONG cancelLocalLWP(LWP *lwp);
extern LONG scheduleBoundLWP(LWP *lwp, LONG proc);
extern LONG cancelBoundLWP(LWP *lwp);
extern LONG scheduleLWP(LWP *lwp);
extern LONG cancelLWP(LWP *lwp);
extern LONG scheduleFastLWP(LWP *lwp);
extern LONG cancelFastLWP(LWP *lwp);
extern LONG scheduleSoftInt(LWP *lwp);
extern LONG cancelSoftInt(LWP *lwp);
extern PROCESS *systemThreadHead;
extern PROCESS *systemThreadTail;
extern LONG systemThreadmutex;
extern PROCESS *rundown_queue_head;
extern PROCESS *rundown_queue_tail;
extern LONG rundown_queue_mutex;
extern LONG active_processors;
extern LONG initial_stack_array[MAX_PROCESSORS];
extern LONG initial_stack_size_array[MAX_PROCESSORS];
extern LONG systemUtilization;
extern LONG processorUtilization[MAX_PROCESSORS];
extern LONG processorCountArray[MAX_PROCESSORS];
extern LONG threadCountArray[MAX_PROCESSORS];
extern LONG idleCountArray[MAX_PROCESSORS];
extern LONG IDLE_COUNT;
extern LONG SAMPLE_INTERVAL;
extern LONG DELTA;
extern LONG LWP_PROCESS_COUNT;
extern LONG DisablePreemption(void);
extern LONG EnablePreemption(void);
extern void panic(BYTE *msg);
extern LWP *get_fast_lwp_chain(void);
extern LWP *get_fast_lwp(void);
extern void put_fast_lwp(LWP *p);
extern LWP *get_local_fast_lwp_chain(LONG proc);
extern LWP *get_local_fast_lwp(LONG proc);
extern void put_local_fast_lwp(LWP *p, LONG proc);
extern LWP *get_local_soft_int_chain(LONG proc);
extern LWP *get_local_soft_int(LONG proc);
extern void put_local_soft_int(LWP *p, LONG proc);
extern LWP *get_soft_int_chain(void);
extern LWP *get_soft_int(void);
extern void put_soft_int(LWP *p);
extern LONG StartSleepNotAllowed(void);
extern LONG EndSleepNotAllowed(void);
extern LONG thread_switch_processor(LONG);
extern LONG thread_switch_and_bind(LONG);
// sema prototypes
extern sema_t *sema_init(sema_t *sema, LONG value);
extern sema_t *sema_alloc(LONG value);
extern LONG sema_free(sema_t *sema);
extern LONG sema_wait(sema_t *sema);
extern LONG sema_post(sema_t *sema);
extern LONG sema_timed_wait(sema_t *sema, LONG delay);
extern LONG sema_timed_post(sema_t *sema);
extern LONG sema_release(sema_t *sema);
extern PROCESS *get_sema_process(sema_t *sema);
extern void put_sema_process(sema_t *sema, PROCESS *p);
// mutex prototypes
extern mutex_t *mutex_init(mutex_t *mutex, LONG value);
extern mutex_t *mutex_alloc(LONG value);
extern LONG mutex_free(mutex_t *mutex);
extern LONG mutex_lock(mutex_t *mutex);
extern LONG mutex_unlock(mutex_t *mutex);
extern LONG mutex_release(mutex_t *mutex);
extern PROCESS *get_mutex_process(mutex_t *mutex);
extern void put_mutex_process(mutex_t *mutex, PROCESS *p);
// rmutex prototypes
extern rmutex_t *rmutex_init(rmutex_t *rmutex, LONG value);
extern rmutex_t *rmutex_alloc(LONG value);
extern LONG rmutex_free(rmutex_t *rmutex);
extern LONG rmutex_lock(rmutex_t *rmutex);
extern LONG rmutex_unlock(rmutex_t *rmutex);
extern LONG rmutex_release(rmutex_t *rmutex);
extern PROCESS *get_rmutex_process(rmutex_t *rmutex);
extern void put_rmutex_process(rmutex_t *rmutex, PROCESS *p);
// rwlock prototypes
extern rwlock_t *rwlock_init(rwlock_t *rwlock);
extern rwlock_t *rwlock_alloc(void);
extern LONG rwlock_free(rwlock_t *rwlock);
extern LONG rwlock_read_lock(rwlock_t *rwlock);
extern LONG rwlock_write_lock(rwlock_t *rwlock);
extern LONG rwlock_read_try_lock(rwlock_t *rwlock);
extern LONG rwlock_write_try_lock(rwlock_t *rwlock);
extern LONG rwlock_read_unlock(rwlock_t *rwlock);
extern LONG rwlock_write_unlock(rwlock_t *rwlock);
extern LONG rwlock_reader_to_writer(rwlock_t *rwlock);
extern LONG rwlock_reader_to_writer_unordered(rwlock_t *rwlock);
extern LONG rwlock_writer_to_reader(rwlock_t *rwlock);
extern PROCESS *get_rwlock_process(rwlock_t *rwlock);
extern void put_rwlock_process(rwlock_t *rwlock, PROCESS *p);
extern LONG rwlock_release(rwlock_t *rwlock);