ad6a0943a1b586024e87ff84773d0cdc949c8dec
[akaros.git] / kern / src / schedule.c
1 /*
2  * Copyright (c) 2009 The Regents of the University of California
3  * Barret Rhoden <brho@cs.berkeley.edu>
4  * See LICENSE for details.
5  *
6  * Scheduling and dispatching.
7  */
8
9 #ifdef __SHARC__
10 #pragma nosharc
11 #endif
12
13 #include <schedule.h>
14 #include <process.h>
15 #include <monitor.h>
16 #include <stdio.h>
17 #include <assert.h>
18 #include <atomic.h>
19 #include <sys/queue.h>
20
21 // This could be useful for making scheduling decisions.  
22 /* Physical coremap: each index is a physical core id, with a proc ptr for
23  * whoever *should be or is* running.  Very similar to current, which is what
24  * process is *really* running there. */
25 struct proc *pcoremap[MAX_NUM_CPUS];
26
27 void schedule_init(void)
28 {
29         TAILQ_INIT(&proc_runnablelist);
30         return;
31 }
32
33 void schedule_proc(struct proc *p)
34 {
35         /* up the refcnt since we are storing the reference */
36         kref_get(&p->kref, 1);
37         spin_lock_irqsave(&runnablelist_lock);
38         printd("Scheduling PID: %d\n", p->pid);
39         TAILQ_INSERT_TAIL(&proc_runnablelist, p, proc_link);
40         spin_unlock_irqsave(&runnablelist_lock);
41         return;
42 }
43
44 /* TODO: race here.  it's possible that p was already removed from the
45  * list (by schedule()), while proc_destroy is trying to remove it from the
46  * list.  schedule()'s proc_run() won't actually run it (since it's DYING), but
47  * this code will probably fuck up.  Having TAILQ_REMOVE not hurt will help. */
48 void deschedule_proc(struct proc *p)
49 {
50         spin_lock_irqsave(&runnablelist_lock);
51         printd("Descheduling PID: %d\n", p->pid);
52         TAILQ_REMOVE(&proc_runnablelist, p, proc_link);
53         spin_unlock_irqsave(&runnablelist_lock);
54         /* down the refcnt, since its no longer stored */
55         kref_put(&p->kref);
56         return;
57 }
58
59 /*
60  * FIFO - just pop the head from the list and run it.
61  * Using irqsave spinlocks for now, since this could be called from a timer
62  * interrupt handler (though ought to be in a bottom half or something).
63  */
64 void schedule(void)
65 {
66         struct proc *p;
67         
68         spin_lock_irqsave(&runnablelist_lock);
69         p = TAILQ_FIRST(&proc_runnablelist);
70         if (p) {
71                 TAILQ_REMOVE(&proc_runnablelist, p, proc_link);
72                 spin_unlock_irqsave(&runnablelist_lock);
73                 printd("PID of proc i'm running: %d\n", p->pid);
74                 /* proc_run will either eat the ref, or we'll decref manually. */
75                 proc_run(p);
76                 kref_put(&p->kref);
77         } else {
78                 spin_unlock_irqsave(&runnablelist_lock);
79         }
80         return;
81 }
82
83 void dump_proclist(struct proc_list *list)
84 {
85         struct proc *p;
86         TAILQ_FOREACH(p, list, proc_link)
87                 printk("PID: %d\n", p->pid);
88         return;
89 }