|
|
1.1 root 1: /*
2: * 'sched.c' is the main kernel file. It contains scheduling primitives
3: * (sleep_on, wakeup, schedule etc) as well as a number of simple system
4: * call functions (type getpid(), which just extracts a field from
5: * current-task
6: */
7: #include <linux/sched.h>
8: #include <linux/kernel.h>
9: #include <signal.h>
10: #include <linux/sys.h>
11: #include <asm/system.h>
12: #include <asm/io.h>
13: #include <asm/segment.h>
14:
15: #define LATCH (1193180/HZ)
16:
17: extern void mem_use(void);
18:
19: extern int timer_interrupt(void);
20: extern int system_call(void);
21:
22: union task_union {
23: struct task_struct task;
24: char stack[PAGE_SIZE];
25: };
26:
27: static union task_union init_task = {INIT_TASK,};
28:
29: long volatile jiffies=0;
30: long startup_time=0;
31: struct task_struct *current = &(init_task.task), *last_task_used_math = NULL;
32:
33: struct task_struct * task[NR_TASKS] = {&(init_task.task), };
34:
35: long user_stack [ PAGE_SIZE>>2 ] ;
36:
37: struct {
38: long * a;
39: short b;
40: } stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };
41: /*
42: * 'math_state_restore()' saves the current math information in the
43: * old math state array, and gets the new ones from the current task
44: */
45: void math_state_restore()
46: {
47: if (last_task_used_math)
48: __asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));
49: if (current->used_math)
50: __asm__("frstor %0"::"m" (current->tss.i387));
51: else {
52: __asm__("fninit"::);
53: current->used_math=1;
54: }
55: last_task_used_math=current;
56: }
57:
58: /*
59: * 'schedule()' is the scheduler function. This is GOOD CODE! There
60: * probably won't be any reason to change this, as it should work well
61: * in all circumstances (ie gives IO-bound processes good response etc).
62: * The one thing you might take a look at is the signal-handler code here.
63: *
64: * NOTE!! Task 0 is the 'idle' task, which gets called when no other
65: * tasks can run. It can not be killed, and it cannot sleep. The 'state'
66: * information in task[0] is never used.
67: */
68: void schedule(void)
69: {
70: int i,next,c;
71: struct task_struct ** p;
72:
73: /* check alarm, wake up any interruptible tasks that have got a signal */
74:
75: for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
76: if (*p) {
77: if ((*p)->alarm && (*p)->alarm < jiffies) {
78: (*p)->signal |= (1<<(SIGALRM-1));
79: (*p)->alarm = 0;
80: }
81: if ((*p)->signal && (*p)->state==TASK_INTERRUPTIBLE)
82: (*p)->state=TASK_RUNNING;
83: }
84:
85: /* this is the scheduler proper: */
86:
87: while (1) {
88: c = -1;
89: next = 0;
90: i = NR_TASKS;
91: p = &task[NR_TASKS];
92: while (--i) {
93: if (!*--p)
94: continue;
95: if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
96: c = (*p)->counter, next = i;
97: }
98: if (c) break;
99: for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
100: if (*p)
101: (*p)->counter = ((*p)->counter >> 1) +
102: (*p)->priority;
103: }
104: switch_to(next);
105: }
106:
107: int sys_pause(void)
108: {
109: current->state = TASK_INTERRUPTIBLE;
110: schedule();
111: return 0;
112: }
113:
114: void sleep_on(struct task_struct **p)
115: {
116: struct task_struct *tmp;
117:
118: if (!p)
119: return;
120: if (current == &(init_task.task))
121: panic("task[0] trying to sleep");
122: tmp = *p;
123: *p = current;
124: current->state = TASK_UNINTERRUPTIBLE;
125: schedule();
126: if (tmp)
127: tmp->state=0;
128: }
129:
130: void interruptible_sleep_on(struct task_struct **p)
131: {
132: struct task_struct *tmp;
133:
134: if (!p)
135: return;
136: if (current == &(init_task.task))
137: panic("task[0] trying to sleep");
138: tmp=*p;
139: *p=current;
140: repeat: current->state = TASK_INTERRUPTIBLE;
141: schedule();
142: if (*p && *p != current) {
143: (**p).state=0;
144: goto repeat;
145: }
146: *p=NULL;
147: if (tmp)
148: tmp->state=0;
149: }
150:
151: void wake_up(struct task_struct **p)
152: {
153: if (p && *p) {
154: (**p).state=0;
155: *p=NULL;
156: }
157: }
158:
159: void do_timer(long cpl)
160: {
161: if (cpl)
162: current->utime++;
163: else
164: current->stime++;
165: if ((--current->counter)>0) return;
166: current->counter=0;
167: if (!cpl) return;
168: schedule();
169: }
170:
171: int sys_alarm(long seconds)
172: {
173: current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;
174: return seconds;
175: }
176:
177: int sys_getpid(void)
178: {
179: return current->pid;
180: }
181:
182: int sys_getppid(void)
183: {
184: return current->father;
185: }
186:
187: int sys_getuid(void)
188: {
189: return current->uid;
190: }
191:
192: int sys_geteuid(void)
193: {
194: return current->euid;
195: }
196:
197: int sys_getgid(void)
198: {
199: return current->gid;
200: }
201:
202: int sys_getegid(void)
203: {
204: return current->egid;
205: }
206:
207: int sys_nice(long increment)
208: {
209: if (current->priority-increment>0)
210: current->priority -= increment;
211: return 0;
212: }
213:
214: int sys_signal(long signal,long addr,long restorer)
215: {
216: long i;
217:
218: switch (signal) {
219: case SIGHUP: case SIGINT: case SIGQUIT: case SIGILL:
220: case SIGTRAP: case SIGABRT: case SIGFPE: case SIGUSR1:
221: case SIGSEGV: case SIGUSR2: case SIGPIPE: case SIGALRM:
222: case SIGCHLD:
223: i=(long) current->sig_fn[signal-1];
224: current->sig_fn[signal-1] = (fn_ptr) addr;
225: current->sig_restorer = (fn_ptr) restorer;
226: return i;
227: default: return -1;
228: }
229: }
230:
231: void sched_init(void)
232: {
233: int i;
234: struct desc_struct * p;
235:
236: set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));
237: set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));
238: p = gdt+2+FIRST_TSS_ENTRY;
239: for(i=1;i<NR_TASKS;i++) {
240: task[i] = NULL;
241: p->a=p->b=0;
242: p++;
243: p->a=p->b=0;
244: p++;
245: }
246: ltr(0);
247: lldt(0);
248: outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */
249: outb_p(LATCH & 0xff , 0x40); /* LSB */
250: outb(LATCH >> 8 , 0x40); /* MSB */
251: set_intr_gate(0x20,&timer_interrupt);
252: outb(inb_p(0x21)&~0x01,0x21);
253: set_system_gate(0x80,&system_call);
254: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.