No longer uses num_vcores() to determine _M (XCC)
[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 <resource.h>
20 #include <sys/queue.h>
21
22 // This could be useful for making scheduling decisions.  
23 /* Physical coremap: each index is a physical core id, with a proc ptr for
24  * whoever *should be or is* running.  Very similar to current, which is what
25  * process is *really* running there. */
26 struct proc *pcoremap[MAX_NUM_CPUS];
27
28 void schedule_init(void)
29 {
30         TAILQ_INIT(&proc_runnablelist);
31         return;
32 }
33
34 void schedule_proc(struct proc *p)
35 {
36         /* up the refcnt since we are storing the reference */
37         proc_incref(p, 1);
38         spin_lock_irqsave(&runnablelist_lock);
39         printd("Scheduling PID: %d\n", p->pid);
40         TAILQ_INSERT_TAIL(&proc_runnablelist, p, proc_link);
41         spin_unlock_irqsave(&runnablelist_lock);
42         return;
43 }
44
45 /* TODO: race here.  it's possible that p was already removed from the
46  * list (by schedule()), while proc_destroy is trying to remove it from the
47  * list.  schedule()'s proc_run() won't actually run it (since it's DYING), but
48  * this code will probably fuck up.  Having TAILQ_REMOVE not hurt will help. */
49 void deschedule_proc(struct proc *p)
50 {
51         spin_lock_irqsave(&runnablelist_lock);
52         printd("Descheduling PID: %d\n", p->pid);
53         TAILQ_REMOVE(&proc_runnablelist, p, proc_link);
54         spin_unlock_irqsave(&runnablelist_lock);
55         /* down the refcnt, since its no longer stored */
56         proc_decref(p);
57         return;
58 }
59
60 /*
61  * FIFO - just pop the head from the list and run it.
62  * Using irqsave spinlocks for now, since this could be called from a timer
63  * interrupt handler (though ought to be in a bottom half or something).
64  */
65 void schedule(void)
66 {
67         struct proc *p;
68         
69         spin_lock_irqsave(&runnablelist_lock);
70         p = TAILQ_FIRST(&proc_runnablelist);
71         if (p) {
72                 TAILQ_REMOVE(&proc_runnablelist, p, proc_link);
73                 spin_unlock_irqsave(&runnablelist_lock);
74                 printd("PID of proc i'm running: %d\n", p->pid);
75                 /* We can safely read is_mcp without locking (i think). */
76                 if (__proc_is_mcp(p)) {
77                         /* _Ms need to get some cores, which will call proc_run() internally
78                          * (for now) */
79                         if (core_request(p) <= 0)
80                                 schedule_proc(p);       /* got none, put it back on the queue */
81                 } else {
82                         /* _S proc, just run it */
83                         proc_run(p);
84                 }
85                 /* proc_run will either eat the ref, or we'll decref manually. */
86                 proc_decref(p);
87         } else {
88                 spin_unlock_irqsave(&runnablelist_lock);
89         }
90         return;
91 }
92
93 void dump_proclist(struct proc_list *list)
94 {
95         struct proc *p;
96         TAILQ_FOREACH(p, list, proc_link)
97                 printk("PID: %d\n", p->pid);
98         return;
99 }