Esempio n. 1
0
void sched_run()
{
    sched_context_switch_request = 0;

    tcb_t *my_active_thread = (tcb_t *)active_thread;

    if (my_active_thread) {
        if (my_active_thread->status == STATUS_RUNNING) {
            my_active_thread->status = STATUS_PENDING;
        }

#ifdef SCHED_TEST_STACK

        if (*((unsigned int *)my_active_thread->stack_start) != (unsigned int) my_active_thread->stack_start) {
            printf("scheduler(): stack overflow detected, task=%s pid=%u\n", my_active_thread->name, my_active_thread->pid);
        }

#endif

    }

#ifdef SCHEDSTATISTICS
    unsigned long time = hwtimer_now();

    if (my_active_thread && (pidlist[my_active_thread->pid].laststart)) {
        pidlist[my_active_thread->pid].runtime_ticks += time - pidlist[my_active_thread->pid].laststart;
    }

#endif

    DEBUG("\nscheduler: previous task: %s\n", (my_active_thread == NULL) ? "none" : my_active_thread->name);

    if (num_tasks == 0) {
        DEBUG("scheduler: no tasks left.\n");

        while (!num_tasks) {
            /* loop until a new task arrives */
            ;
        }

        DEBUG("scheduler: new task created.\n");
    }

    my_active_thread = NULL;

    while (!my_active_thread) {
        int nextrq = number_of_lowest_bit(runqueue_bitcache);
        clist_node_t next = *(runqueues[nextrq]);
        DEBUG("scheduler: first in queue: %s\n", ((tcb_t *)next.data)->name);
        clist_advance(&(runqueues[nextrq]));
        my_active_thread = (tcb_t *)next.data;
        thread_pid = (volatile int) my_active_thread->pid;
#if SCHEDSTATISTICS
        pidlist[my_active_thread->pid].laststart = time;
        pidlist[my_active_thread->pid].schedules++;
        if ((sched_cb) && (my_active_thread->pid != last_pid)) {
            sched_cb(hwtimer_now(), my_active_thread->pid);
            last_pid = my_active_thread->pid;
        }
#endif
#ifdef MODULE_NSS

        if (active_thread && active_thread->pid != last_pid) {
            last_pid = active_thread->pid;
        }

#endif
    }

    DEBUG("scheduler: next task: %s\n", my_active_thread->name);

    if (my_active_thread != active_thread) {
        if (active_thread != NULL) {  /* TODO: necessary? */
            if (active_thread->status ==  STATUS_RUNNING) {
                active_thread->status =  STATUS_PENDING ;
            }
        }

        sched_set_status((tcb_t *)my_active_thread,  STATUS_RUNNING);
    }

    active_thread = (volatile tcb_t *) my_active_thread;

    DEBUG("scheduler: done.\n");
}
Esempio n. 2
0
int sched_run(void)
{
    sched_context_switch_request = 0;

    thread_t *active_thread = (thread_t *)sched_active_thread;

    /* The bitmask in runqueue_bitcache is never empty,
     * since the threading should not be started before at least the idle thread was started.
     */
    int nextrq = bitarithm_lsb(runqueue_bitcache);
    thread_t *next_thread = clist_get_container(sched_runqueues[nextrq], thread_t, rq_entry);

    DEBUG("sched_run: active thread: %" PRIkernel_pid ", next thread: %" PRIkernel_pid "\n",
          (active_thread == NULL) ? KERNEL_PID_UNDEF : active_thread->pid,
          next_thread->pid);

    if (active_thread == next_thread) {
        DEBUG("sched_run: done, sched_active_thread was not changed.\n");
        return 0;
    }

#ifdef MODULE_SCHEDSTATISTICS
    unsigned long time = xtimer_now();
#endif

    if (active_thread) {
        if (active_thread->status == STATUS_RUNNING) {
            active_thread->status = STATUS_PENDING;
        }

#ifdef SCHED_TEST_STACK
        if (*((uintptr_t *) active_thread->stack_start) != (uintptr_t) active_thread->stack_start) {
            LOG_WARNING("scheduler(): stack overflow detected, pid=%" PRIkernel_pid "\n", active_thread->pid);
        }
#endif

#ifdef MODULE_SCHEDSTATISTICS
        schedstat *active_stat = &sched_pidlist[active_thread->pid];
        if (active_stat->laststart) {
            active_stat->runtime_ticks += time - active_stat->laststart;
        }
#endif
    }

#ifdef MODULE_SCHEDSTATISTICS
    schedstat *next_stat = &sched_pidlist[next_thread->pid];
    next_stat->laststart = time;
    next_stat->schedules++;
    if (sched_cb) {
        sched_cb(time, next_thread->pid);
    }
#endif

    next_thread->status = STATUS_RUNNING;
    sched_active_pid = next_thread->pid;
    sched_active_thread = (volatile thread_t *) next_thread;

    DEBUG("sched_run: done, changed sched_active_thread.\n");

    return 1;
}