source: bootcd/isolinux/syslinux-6.03/core/thread/schedule.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 2.0 KB
Line 
1#include <klibc/compiler.h>
2#include <sys/cpu.h>
3#include "thread.h"
4#include "core.h"
5#include <dprintf.h>
6
7void (*sched_hook_func)(void);
8
9/*
10 * __schedule() should only be called with interrupts locked out!
11 */
12void __schedule(void)
13{
14    static bool in_sched_hook;
15    struct thread *curr = current();
16    struct thread *st, *nt, *best;
17
18#if DEBUG
19    if (__unlikely(irq_state() & 0x200)) {
20        dprintf("In __schedule with interrupts on!\n");
21        kaboom();
22    }
23#endif
24
25    /*
26     * Are we called from inside sched_hook_func()?  If so we'll
27     * schedule anyway on the way out.
28     */
29    if (in_sched_hook)
30        return;
31
32    dprintf("Schedule ");
33
34    /* Possibly update the information on which we make
35     * scheduling decisions.
36     */
37    if (sched_hook_func) {
38        in_sched_hook = true;
39        sched_hook_func();
40        in_sched_hook = false;
41    }
42
43    /*
44     * The unusual form of this walk is because we have to start with
45     * the thread *following* curr, and curr may not actually be part
46     * of the list anymore (in the case of __exit_thread).
47     */
48    best = NULL;
49    nt = st = container_of(curr->list.next, struct thread, list);
50    do {
51        if (__unlikely(nt->thread_magic != THREAD_MAGIC)) {
52            dprintf("Invalid thread on thread list %p magic = 0x%08x\n",
53                    nt, nt->thread_magic);
54            kaboom();
55        }
56
57        dprintf("Thread %p (%s) ", nt, nt->name);
58        if (!nt->blocked) {
59            dprintf("runnable priority %d\n", nt->prio);
60            if (!best || nt->prio < best->prio)
61                best = nt;
62        } else {
63            dprintf("blocked\n");
64        }
65        nt = container_of(nt->list.next, struct thread, list);
66    } while (nt != st);
67
68    if (!best)
69        kaboom();               /* No runnable thread */
70
71    if (best != curr) {
72        uint64_t tsc;
73       
74        asm volatile("rdtsc" : "=A" (tsc));
75       
76        dprintf("@ %llu -> %p (%s)\n", tsc, best, best->name);
77        __switch_to(best);
78    } else {
79        dprintf("no change\n");
80    }
81}
82
83/*
84 * This can be called from "normal" code...
85 */
86void thread_yield(void)
87{
88    irq_state_t irq = irq_save();
89    __schedule();
90    irq_restore(irq);
91}
Note: See TracBrowser for help on using the repository browser.