Annotation of linux/kernel/sched.c, revision 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.