[BACK]Return to kern_sched.c CVS log [TXT][DIR] Up to [local] / funnyos / kern

Annotation of funnyos/kern/kern_sched.c, Revision 1.3

1.1       nbrk        1: /*
1.3     ! nbrk        2:  * $Id: kern_sched.c,v 1.2 2007/11/20 16:07:24 nbrk Exp $
1.1       nbrk        3:  */
                      4: #include <sys/types.h>
                      5: #include <sys/kern_sched.h>
1.2       nbrk        6: #include <sys/kern_time.h> /* for HZ */
                      7: #include <sys/mem.h>
1.1       nbrk        8:
                      9: #include <libkern/printf.h>
                     10:
1.3     ! nbrk       11: /* #define SCHED_DEBUG */
        !            12: /* #define SCHED_REGDEBUG */
        !            13:
        !            14: #ifdef SCHED_DEBUG
        !            15: #define DPRINTF(x...)  do { printf(x); } while (0)
        !            16: #else
        !            17: #define DPRINTF(x...)  { }
        !            18: #endif
        !            19:
        !            20: #ifdef SCHED_REGDEBUG
        !            21: #define DRPRINTF(x...)         do { printf(x); } while (0)
        !            22: #else
        !            23: #define DRPRINTF(x...)         { }
        !            24: #endif
        !            25:
1.2       nbrk       26:
                     27: /* config.c gives us tasks that we'll schedule */
                     28: extern struct u_task config_tasklist[];
                     29:
                     30: /* list of k_tasks */
                     31: struct k_task *ktasklist;
                     32:
1.3     ! nbrk       33: /* current running task */
        !            34: struct k_task *curktask;
        !            35:
1.2       nbrk       36: /* pcb of running task; we will save context there when enter irq_mode */
1.3     ! nbrk       37: struct pcb *curpcb;
        !            38:
        !            39: /* interrupt frame */
        !            40: extern struct pcb *iframep;
1.2       nbrk       41:
                     42: /* total tasks; used to TID generation */
                     43: uint8_t ntasks;
                     44:
                     45: /* "idle" task exists forever and occupy cpu when there is no other task pretending. */
                     46: const struct u_task idle_utask = {"idle", 0, NULL};
                     47:
                     48:
                     49: void
                     50: sched_init(void)
                     51: {
                     52:        /*
                     53:         * Create struct k_task for each u_task that user described in config_tasklist.
                     54:         */
                     55:        struct u_task *utaskp;
                     56:        struct k_task *ktaskp, *oldktaskp;
                     57:
                     58:        ntasks = 0;
                     59:
                     60:        /*
                     61:         * Create an "idle" task which always has TID 0.
                     62:         */
                     63:        ktaskp = kmalloc(sizeof(struct k_task));
                     64:
                     65:        if (ktaskp == NULL)
                     66:                panic("can't allocate memory for idle task\n");
                     67:
                     68:        /* link u_task for idle task */
                     69:        ktaskp->kt_utask = (struct u_task *)&idle_utask;
                     70:
                     71:        /* TID (always 0) */
                     72:        ktaskp->kt_tid = 0;
                     73:
                     74:        /* idle task is always in state READY (or RUNNING, if on processor now) */
                     75:        ktaskp->kt_state = TASK_READY;
                     76:
                     77:        /* next task in list isn't up yet (and prev too) */
                     78:        ktaskp->kt_next = NULL;
                     79:
                     80:        /* make "idle" task first task in ktasklist, system k_task list */
                     81:        ktasklist = ktaskp;
                     82:
                     83:        /* bump ntasks to 1 */
                     84:        ntasks = 1;
                     85:
                     86:        /* preserve pointer to this k_task so we can link-in next task */
                     87:        oldktaskp = ktaskp;
                     88:
                     89:        /*
                     90:         * Idle task set up completed.
                     91:         * Configure all other system tasks,
                     92:         */
                     93:
                     94:        /* look through tasklist */
                     95:        utaskp = config_tasklist;
                     96:        while(utaskp->ut_name != NULL) {
                     97:
                     98:                /* try to allocate memory for ktask */
                     99:                ktaskp = kmalloc(sizeof(struct k_task));
                    100:
                    101:                if (ktaskp == NULL)
                    102:                        panic("can't allocate memory for task '%s'\n", utaskp->ut_name);
                    103:
                    104:                /*
                    105:                 * Successfully allocated new ktask.
                    106:                 */
                    107:
                    108:                /* link u_task */
                    109:                ktaskp->kt_utask = utaskp;
                    110:
                    111:                /* set TID (Task Identificator) */
                    112:                ktaskp->kt_tid = oldktaskp->kt_tid + 1;
                    113:
                    114:                /* state */
                    115:                ktaskp->kt_state = TASK_READY;
                    116:
1.3     ! nbrk      117:                /* set intitial entry point (initial pc) to task_enter */
        !           118:                ktaskp->kt_pcb.p_pc = (uint32_t)ktaskp->kt_utask->ut_enter;
        !           119:
1.2       nbrk      120:                /* link current task in previous task's structure */
                    121:                oldktaskp->kt_next = ktaskp;
                    122:
                    123:                /* NULLify kt_next of current task */
                    124:                ktaskp->kt_next = NULL;
                    125:
                    126:                /* save current ktask for use with next ktask */
                    127:                oldktaskp = ktaskp;
                    128:
                    129:                /* bump ntasks */
                    130:                ntasks++;
                    131:
                    132:                /* shift to next element in config_tasklist[] */
                    133:                utaskp++;
                    134:        }
                    135:
                    136:        /* make this list circularly linked (e.g point list's last->next node into first) */
                    137:        ktaskp->kt_next = ktasklist;
                    138:
1.3     ! nbrk      139:        DPRINTF("kern_sched: created %d tasks:", ntasks);
1.2       nbrk      140:
                    141:        /* print tasks' names */
                    142:        ktaskp = ktasklist + 1; /* skip (first) "idle" task (display it as the end of circularly list) */
                    143:        do {
1.3     ! nbrk      144:                DPRINTF(" %s", ktaskp->kt_utask->ut_name);
1.2       nbrk      145:
                    146:                if (ktaskp->kt_tid == NULL) /* that was an "idle" task */
                    147:                        break;
                    148:
                    149:                ktaskp = ktaskp->kt_next;
                    150:        } while(1);
                    151:
1.3     ! nbrk      152:        DPRINTF("; HZ=%d\n", HZ);
        !           153:
        !           154:        /*
        !           155:         * Run "idle" task in NOSCHED, so it will not schedule after first context siwtch;
        !           156:         */
        !           157:        ktasklist->kt_state = TASK_NOSCHED;
        !           158:        curktask = ktasklist; /* ktasklist always points to "idle" task */
        !           159:
        !           160:        /* point curpcb */
        !           161:        curpcb = &ktasklist->kt_pcb;
        !           162: }
        !           163:
        !           164:
        !           165: void
        !           166: sched_tick(void)
        !           167: {
        !           168:        /*
        !           169:         * Schedule next task that will occupy cpu (if any).
        !           170:         * Remember that we are in IRQ_mode here.
        !           171:         */
        !           172:
        !           173:        /*
        !           174:         * All we need to do now is:
        !           175:         *  - see if context switch is required
        !           176:         *   - if so, save iframe into curpcb (save hardware context)
        !           177:         *   - select next task to run
        !           178:         *   - point curpcb to pcb of new task
        !           179:         *   - point curktask to k_task of new task
        !           180:         *   - copy curpcb into iframep (so we'll continue in another task when we exit irq_mode)
        !           181:         *  - if context switch is not required
        !           182:         *   - XXX we will not copy curpcb into iframep? (cause we end up in same task at next irq)
        !           183:         *  - anyway, account time, etc..
        !           184:         */
        !           185:
        !           186:        /* XXX use pre-emtive multitasking to simplify things for now! */
        !           187:
        !           188:        /* save hardware state of interrupted task */
        !           189:        *curpcb = *iframep;
        !           190:
        !           191:        /* "suspend" interrupted task */
        !           192:        if(curktask->kt_state == TASK_RUNNING) /* XXX ugly hack to skip "idle" which is NOSCHED */
        !           193:                curktask->kt_state = TASK_READY;
        !           194:
        !           195:        DPRINTF("sched_tick: task tid=%d (\"%s\") suspended\n", curktask->kt_tid, curktask->kt_utask->ut_name);
        !           196:        DRPRINTF("r0=0x%x\n", iframep->p_r0);
        !           197:        DRPRINTF("r1=0x%x\n", iframep->p_r1);
        !           198:        DRPRINTF("r2=0x%x\n", iframep->p_r2);
        !           199:        DRPRINTF("r3=0x%x\n", iframep->p_r3);
        !           200:        DRPRINTF("r4=0x%x\n", iframep->p_r4);
        !           201:        DRPRINTF("r5=0x%x\n", iframep->p_r5);
        !           202:        DRPRINTF("r6=0x%x\n", iframep->p_r6);
        !           203:        DRPRINTF("r7=0x%x\n", iframep->p_r7);
        !           204:        DRPRINTF("r8=0x%x\n", iframep->p_r8);
        !           205:        DRPRINTF("r9=0x%x\n", iframep->p_r9);
        !           206:        DRPRINTF("r10=0x%x\n", iframep->p_r10);
        !           207:        DRPRINTF("r11=0x%x\n", iframep->p_r11);
        !           208:        DRPRINTF("r12=0x%x\n", iframep->p_r12);
        !           209:        DRPRINTF("pc=0x%x\n", iframep->p_pc);
        !           210:
        !           211:        /* round-robin select next task in circlelist */
        !           212:        curktask = curktask->kt_next;
        !           213:
        !           214:        /* look for next ready task */
        !           215:        while(curktask->kt_state != TASK_READY)
        !           216:                curktask = curktask->kt_next;
        !           217:
        !           218:        /* run selected task */
        !           219:        curktask->kt_state = TASK_RUNNING;
        !           220:
        !           221:        /* point curpcb into selected task's pcb */
        !           222:        curpcb = &curktask->kt_pcb;
        !           223:
        !           224:        /* restore selected task's hardware context into an IRQ stack */
        !           225:        *iframep = *curpcb;
        !           226:
        !           227:        DPRINTF("sched_tick: task tid=%d (\"%s\") resumed\n", curktask->kt_tid, curktask->kt_utask->ut_name);
        !           228:        DRPRINTF("r0=0x%x\n", iframep->p_r0);
        !           229:        DRPRINTF("r1=0x%x\n", iframep->p_r1);
        !           230:        DRPRINTF("r2=0x%x\n", iframep->p_r2);
        !           231:        DRPRINTF("r3=0x%x\n", iframep->p_r3);
        !           232:        DRPRINTF("r4=0x%x\n", iframep->p_r4);
        !           233:        DRPRINTF("r5=0x%x\n", iframep->p_r5);
        !           234:        DRPRINTF("r6=0x%x\n", iframep->p_r6);
        !           235:        DRPRINTF("r7=0x%x\n", iframep->p_r7);
        !           236:        DRPRINTF("r8=0x%x\n", iframep->p_r8);
        !           237:        DRPRINTF("r9=0x%x\n", iframep->p_r9);
        !           238:        DRPRINTF("r10=0x%x\n", iframep->p_r10);
        !           239:        DRPRINTF("r11=0x%x\n", iframep->p_r11);
        !           240:        DRPRINTF("r12=0x%x\n", iframep->p_r12);
        !           241:        DRPRINTF("pc=0x%x\n", iframep->p_pc);
1.2       nbrk      242:
                    243: }
1.1       nbrk      244:

CVSweb