-
Notifications
You must be signed in to change notification settings - Fork 2
/
thread.h
227 lines (193 loc) · 5.22 KB
/
thread.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
/*
* Copyright (C) 2016 Tom Trebisky <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*
* thread.h
* T. Trebisky 8/25/2002
*/
#include "arch/types.h"
#include "arch/cpu.h"
#ifndef NULL
#define NULL (0)
#endif
enum console_mode { SERIAL, VGA, SIO_0, SIO_1 };
typedef void (*tfptr) ( long );
typedef void (*vfptr) ( void );
/* priorities >= MAGIC are for special use.
* (and I will probably reserve single digit
* priorities similarly.)
* No priority *ever* gets set as high as MAX_PRI
#define PRI_USER 950
*/
#define PRI_SYS 5
#define PRI_USER 10
#define PRI_MAGIC 900
#define MAX_PRI 1001
#define PRI_IDLE 1234
enum thread_state {
READY, /* 0 - ready to go */
WAIT, /* 1 - blocked */
SWAIT, /* 2 - blocked on semaphore */
DELAY, /* 3 - blocked on timer event */
IDLE, /* 4 - running idle loop */
JOIN, /* 5 - waiting to join somebody */
ZOMBIE, /* 6 - waiting to be joined */
FAULT, /* 7 - did something bad */
REPEAT, /* 8 - blocked on repeat event */
KILLED, /* 9 - killed by shell command */
DEAD /* 10 - on free list (we hope) */
};
struct thread *thr_new ( char *, tfptr, void *, int, int );
struct thread *thr_new_repeat ( char *, tfptr, void *, int, int, int );
struct thread *thr_self ( void );
void thr_kill ( struct thread * );
void thr_exit ( void );
void thr_block ( enum thread_state );
void thr_unblock ( struct thread * );
struct thread * safe_thr_new ( char *, tfptr, void *, int, int );
/* flags for thr_new:
*/
#define TF_BLOCK 0x0001
#define TF_FPU 0x0002
#define TF_JOIN 0x0004
#define TF_REPEAT 0x0008
/* flags for sem_new:
*/
#define SEM_FIFO 0x0000
#define SEM_PRIO 0x0001
#define SEM_TIMEOUT 0x0002
enum sem_state { CLEAR, SET };
// struct sem *sem_new ( enum sem_state, int );
struct sem *sem_mutex_new ( int );
struct sem *sem_signal_new ( int );
void sem_block ( struct sem * );
void sem_unblock ( struct sem * );
// struct cv *cv_new ( struct sem * );
struct cv *cv_new ( void );
void cv_wait ( struct cv * );
void cv_signal ( struct cv * );
#ifdef notyet
struct sem * cpu_new ( void );
void cpu_wait ( struct sem * );
void cpu_signal ( struct sem * );
#endif
/* This was 6 in Skidoo */
// #define MAX_TNAME 10
#define MAX_TNAME 16
#ifdef ARCH_ARM
/* XXX - move this */
/* For setjmp/longjmp */
/* We only need to save registers that the
* compiler EABI says we should, since this
* is always done from synchronous calls
*/
struct jmp_regs {
reg_t regs[NUM_IREGS];
};
/* We have to save all registers here, since
* an interrupt is entirely unpredictable.
*/
struct int_regs {
reg_t regs[NUM_IREGS];
};
/* These aren't really registers.
* We bit the bullet on the ARM, and put the
* info for cont (and quick) in their own place
* I think there were bugs waiting in the x86 code by
* trying to keep this in the jmp_regs, so this ought
* to be retroed to the x86 someday.
*/
#define NUM_CREGS 4
struct cont_regs {
reg_t regs[NUM_CREGS];
};
#endif
#ifdef ARCH_X86
/* XXX - move this stuff */
/* This is what is saved by save_t/restore_t
* if the size of this changes, you must fiddle
* some constants in locore.S so that the next
* batch of registers get found properly.
*/
struct jmp_regs {
int ebx;
int esp;
int ebp;
int esi;
int edi;
int eip; /* We need this */
};
/* We don't need eip here, since ...
* well things are just different here.
*/
struct int_regs {
int eax;
int ebx;
int ecx;
int edx;
int esi;
int edi;
int ebp;
int esp;
};
#endif
enum thread_mode { JMP, INT, CONT };
/* The iregs structure is referenced from the assembly language
* interrupt handling code which expects to find a place to store
* the interrupt context at the start of this structure.
*/
struct thread {
struct int_regs iregs; /* must be first */
struct jmp_regs jregs;
struct cont_regs cregs; /* new for ARM */
int prof;
struct thread *next; /* all threads */
struct thread *wnext; /* waiting list */
enum thread_state state;
enum thread_mode mode; /* how to resume */
enum console_mode con_mode; /* type of console */
char *stack;
int stack_size;
int pri;
int delay;
int rep_reload;
int rep_count;
struct thread *rep_next; /* list of repeating threads */
int overruns;
int fault; /* why we are suspended */
char name[MAX_TNAME];
#ifdef notdef
tfptr c_func; /* continuation function */
int c_arg; /* continuation argument */
#endif
int flags;
struct thread *join; /* who wants to join us */
struct thread *yield; /* who yielded to us */
struct sem *cur_sem; /* if we are blocked on a sem, this is the one */
};
/* Here are fault codes (kind of like errno)
* XXX - maybe this should be an enum.
*/
#define FA_NIL 0
#define FA_ZDIV 1
/* ---------------------------------------------------------
*/
#define MAX_SEM_NAME 9
struct sem {
struct sem *next; /* links together avail and on timer */
struct thread *list; /* list of threads blocked on this */
int state; /* SET or CLEAR */
int flags;
int delay; /* for sem with timeout */
char name[MAX_SEM_NAME]; /* for debugging 1-3-2022 */
};
struct cv {
struct cv *next;
struct sem *signal;
struct sem *mutex;
};
/* THE END */