Annotation of linux/kernel/sched.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.