This source file includes following definitions.
- show_task
- show_stat
- math_state_restore
- schedule
- sys_pause
- sleep_on
- interruptible_sleep_on
- wake_up
- floppy_select
- floppy_deselect
- ticks_to_floppy_on
- floppy_on
- floppy_off
- do_floppy_timer
- add_timer
- do_timer
- sys_alarm
- sys_getpid
- sys_getppid
- sys_getuid
- sys_geteuid
- sys_getgid
- sys_getegid
- sys_nice
- sched_init
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/sched.h>
14 #include <linux/kernel.h>
15 #include <linux/sys.h>
16 #include <linux/fdreg.h>
17 #include <asm/system.h>
18 #include <asm/io.h>
19 #include <asm/segment.h>
20
21 #include <signal.h>
22
23 #define _S(nr) (1<<((nr)-1))
24 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
25
26 void show_task(int nr,struct task_struct * p)
27 {
28 printk("%d: pid=%d, state=%d, ",nr,p->pid,p->state);
29 printk("eip=%04x:%08x\n\r",p->tss.cs&0xffff,p->tss.eip);
30 }
31
32 void show_stat(void)
33 {
34 int i;
35
36 for (i=0;i<NR_TASKS;i++)
37 if (task[i])
38 show_task(i,task[i]);
39 }
40
41 #define LATCH (1193180/HZ)
42
43 extern void mem_use(void);
44
45 extern int timer_interrupt(void);
46 extern int system_call(void);
47
48 union task_union {
49 struct task_struct task;
50 char stack[PAGE_SIZE];
51 };
52
53 static union task_union init_task = {INIT_TASK,};
54
55 long volatile jiffies=0;
56 long startup_time=0;
57 struct task_struct *current = &(init_task.task);
58 struct task_struct *last_task_used_math = NULL;
59
60 struct task_struct * task[NR_TASKS] = {&(init_task.task), };
61
62 long user_stack [ PAGE_SIZE>>2 ] ;
63
64 struct {
65 long * a;
66 short b;
67 } stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };
68
69
70
71
72 void math_state_restore()
73 {
74 if (last_task_used_math == current)
75 return;
76 if (last_task_used_math) {
77 __asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));
78 }
79 if (current->used_math) {
80 __asm__("frstor %0"::"m" (current->tss.i387));
81 } else {
82 __asm__("fninit"::);
83 current->used_math=1;
84 }
85 last_task_used_math=current;
86 }
87
88
89
90
91
92
93
94
95
96
97
98 void schedule(void)
99 {
100 int i,next,c;
101 struct task_struct ** p;
102
103
104
105 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
106 if (*p) {
107 if ((*p)->alarm && (*p)->alarm < jiffies) {
108 (*p)->signal |= (1<<(SIGALRM-1));
109 (*p)->alarm = 0;
110 }
111 if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&
112 (*p)->state==TASK_INTERRUPTIBLE)
113 (*p)->state=TASK_RUNNING;
114 }
115
116
117
118 while (1) {
119 c = -1;
120 next = 0;
121 i = NR_TASKS;
122 p = &task[NR_TASKS];
123 while (--i) {
124 if (!*--p)
125 continue;
126 if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
127 c = (*p)->counter, next = i;
128 }
129 if (c) break;
130 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
131 if (*p)
132 (*p)->counter = ((*p)->counter >> 1) +
133 (*p)->priority;
134 }
135 switch_to(next);
136 }
137
138 int sys_pause(void)
139 {
140 current->state = TASK_INTERRUPTIBLE;
141 schedule();
142 return 0;
143 }
144
145 void sleep_on(struct task_struct **p)
146 {
147 struct task_struct *tmp;
148
149 if (!p)
150 return;
151 if (current == &(init_task.task))
152 panic("task[0] trying to sleep");
153 tmp = *p;
154 *p = current;
155 current->state = TASK_UNINTERRUPTIBLE;
156 schedule();
157 if (tmp)
158 tmp->state=0;
159 }
160
161 void interruptible_sleep_on(struct task_struct **p)
162 {
163 struct task_struct *tmp;
164
165 if (!p)
166 return;
167 if (current == &(init_task.task))
168 panic("task[0] trying to sleep");
169 tmp=*p;
170 *p=current;
171 repeat: current->state = TASK_INTERRUPTIBLE;
172 schedule();
173 if (*p && *p != current) {
174 (**p).state=0;
175 goto repeat;
176 }
177 *p=NULL;
178 if (tmp)
179 tmp->state=0;
180 }
181
182 void wake_up(struct task_struct **p)
183 {
184 if (p && *p) {
185 (**p).state=0;
186 *p=NULL;
187 }
188 }
189
190
191
192
193
194
195 static struct task_struct * wait_motor[4] = {NULL,NULL,NULL,NULL};
196 static int mon_timer[4]={0,0,0,0};
197 static int moff_timer[4]={0,0,0,0};
198 unsigned char current_DOR = 0x0C;
199 unsigned char selected = 0;
200 struct task_struct * wait_on_floppy_select = NULL;
201
202 void floppy_select(unsigned int nr)
203 {
204 if (nr>3)
205 printk("floppy_select: nr>3\n\r");
206 cli();
207 while (selected)
208 sleep_on(&wait_on_floppy_select);
209 current_DOR &= 0xFC;
210 current_DOR |= nr;
211 outb(current_DOR,FD_DOR);
212 sti();
213 }
214
215 void floppy_deselect(unsigned int nr)
216 {
217 if (nr != (current_DOR & 3))
218 printk("floppy_deselect: drive not selected\n\r");
219 selected = 0;
220 wake_up(&wait_on_floppy_select);
221 }
222
223 int ticks_to_floppy_on(unsigned int nr)
224 {
225 unsigned char mask = 1<<(nr+4);
226
227 if (nr>3)
228 panic("floppy_on: nr>3");
229 moff_timer[nr]=10000;
230 cli();
231 if (!(mask & current_DOR)) {
232 current_DOR |= mask;
233 if (!selected) {
234 current_DOR &= 0xFC;
235 current_DOR |= nr;
236 }
237 outb(current_DOR,FD_DOR);
238 mon_timer[nr] = HZ;
239 }
240 sti();
241 return mon_timer[nr];
242 }
243
244 void floppy_on(unsigned int nr)
245 {
246 cli();
247 while (ticks_to_floppy_on(nr))
248 sleep_on(nr+wait_motor);
249 sti();
250 }
251
252 void floppy_off(unsigned int nr)
253 {
254 moff_timer[nr]=3*HZ;
255 }
256
257 void do_floppy_timer(void)
258 {
259 int i;
260 unsigned char mask = 0x10;
261
262 for (i=0 ; i<4 ; i++,mask <<= 1) {
263 if (!(mask & current_DOR))
264 continue;
265 if (mon_timer[i]) {
266 if (!--mon_timer[i])
267 wake_up(i+wait_motor);
268 } else if (!moff_timer[i]) {
269 current_DOR &= ~mask;
270 outb(current_DOR,FD_DOR);
271 } else
272 moff_timer[i]--;
273 }
274 }
275
276 #define TIME_REQUESTS 64
277
278 static struct timer_list {
279 long jiffies;
280 void (*fn)();
281 struct timer_list * next;
282 } timer_list[TIME_REQUESTS], * next_timer = NULL;
283
284 void add_timer(long jiffies, void (*fn)(void))
285 {
286 struct timer_list * p;
287
288 if (!fn)
289 return;
290 cli();
291 if (jiffies <= 0)
292 (fn)();
293 else {
294 for (p = timer_list ; p < timer_list + TIME_REQUESTS ; p++)
295 if (!p->fn)
296 break;
297 if (p >= timer_list + TIME_REQUESTS)
298 panic("No more time requests free");
299 p->fn = fn;
300 p->jiffies = jiffies;
301 p->next = next_timer;
302 next_timer = p;
303 while (p->next && p->next->jiffies < p->jiffies) {
304 p->jiffies -= p->next->jiffies;
305 fn = p->fn;
306 p->fn = p->next->fn;
307 p->next->fn = fn;
308 jiffies = p->jiffies;
309 p->jiffies = p->next->jiffies;
310 p->next->jiffies = jiffies;
311 p = p->next;
312 }
313 }
314 sti();
315 }
316
317 void do_timer(long cpl)
318 {
319 if (cpl)
320 current->utime++;
321 else
322 current->stime++;
323 if (next_timer) {
324 next_timer->jiffies--;
325 while (next_timer && next_timer->jiffies <= 0) {
326 void (*fn)(void);
327
328 fn = next_timer->fn;
329 next_timer->fn = NULL;
330 next_timer = next_timer->next;
331 (fn)();
332 }
333 }
334 if (current_DOR & 0xf0)
335 do_floppy_timer();
336 if ((--current->counter)>0) return;
337 current->counter=0;
338 if (!cpl) return;
339 schedule();
340 }
341
342 int sys_alarm(long seconds)
343 {
344 int old = current->alarm;
345
346 if (old)
347 old = (old - jiffies) / HZ;
348 current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;
349 return (old);
350 }
351
352 int sys_getpid(void)
353 {
354 return current->pid;
355 }
356
357 int sys_getppid(void)
358 {
359 return current->father;
360 }
361
362 int sys_getuid(void)
363 {
364 return current->uid;
365 }
366
367 int sys_geteuid(void)
368 {
369 return current->euid;
370 }
371
372 int sys_getgid(void)
373 {
374 return current->gid;
375 }
376
377 int sys_getegid(void)
378 {
379 return current->egid;
380 }
381
382 int sys_nice(long increment)
383 {
384 if (current->priority-increment>0)
385 current->priority -= increment;
386 return 0;
387 }
388
389 void sched_init(void)
390 {
391 int i;
392 struct desc_struct * p;
393
394 if (sizeof(struct sigaction) != 16)
395 panic("Struct sigaction MUST be 16 bytes");
396 set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));
397 set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));
398 p = gdt+2+FIRST_TSS_ENTRY;
399 for(i=1;i<NR_TASKS;i++) {
400 task[i] = NULL;
401 p->a=p->b=0;
402 p++;
403 p->a=p->b=0;
404 p++;
405 }
406 ltr(0);
407 lldt(0);
408 outb_p(0x36,0x43);
409 outb_p(LATCH & 0xff , 0x40);
410 outb(LATCH >> 8 , 0x40);
411 set_intr_gate(0x20,&timer_interrupt);
412 outb(inb_p(0x21)&~0x01,0x21);
413 set_system_gate(0x80,&system_call);
414 }