Loading [MathJax]/jax/input/TeX/config.js
CS350 COS
COS
All Data Structures Files Functions Variables Typedefs Macros
sched.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/syscall.h>
#include <sys/kassert.h>
#include <sys/kconfig.h>
#include <sys/kdebug.h>
#include <sys/kmem.h>
#include <sys/ktime.h>
#include <sys/mp.h>
#include <sys/spinlock.h>
#include <sys/thread.h>
#include <machine/trap.h>
#include <machine/pmap.h>
Include dependency graph for sched.c:

Go to the source code of this file.

Functions

ThreadSched_Current ()
 
void Sched_SetRunnable (Thread *thr)
 
void Sched_SetWaiting (Thread *thr)
 
void Sched_SetZombie (Thread *thr)
 
static void Sched_Switch (Thread *oldthr, Thread *newthr)
 
void Sched_Scheduler ()
 

Variables

Spinlock schedLock
 
ThreadQueue waitQueue
 
ThreadQueue runnableQueue
 
ThreadcurProc [MAX_CPUS]
 

Function Documentation

◆ Sched_Current()

Thread * Sched_Current ( )

Sched_Current()

Get the currently executing thread. This function retains a reference count and you must release the reference by calling Thread_Release.

Returns
Returns the current thread.

Definition at line 56 of file sched.c.

57{
59
60 Thread *thr = curProc[CPU()];
61 Thread_Retain(thr);
62
64
65 return thr;
66}
#define CPU
Definition: mp.h:7
void Thread_Retain(Thread *thr)
Definition: thread.c:253
Thread * curProc[MAX_CPUS]
Definition: sched.c:41
Spinlock schedLock
Definition: sched.c:29
void Spinlock_Unlock(Spinlock *lock) __UNLOCK_EX(*lock)
Definition: spinlock.c:109
void Spinlock_Lock(Spinlock *lock) __LOCK_EX(*lock)
Definition: spinlock.c:75
Definition: thread.h:31
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Sched_Scheduler()

void Sched_Scheduler ( )

Sched_Scheduler –

Run our round robin scheduler to find the process and switch to it.

Definition at line 189 of file sched.c.

190{
191 Thread *prev;
192 Thread *next;
193
195
196 // Select next thread
197 next = TAILQ_FIRST(&runnableQueue);
198 if (!next) {
199 /*
200 * There may be no other runnable processes on this core. This is a
201 * good opportunity to migrate threads. We should never hit this case
202 * once the OS is up and running because of the idle threads, but just
203 * in case we should assert that we never return to a zombie or waiting
204 * thread.
205 */
206 ASSERT(curProc[CPU()]->schedState == SCHED_STATE_RUNNING);
208 return;
209 }
211 TAILQ_REMOVE(&runnableQueue, next, schedQueue);
212
213 prev = curProc[CPU()];
214 curProc[CPU()] = next;
216 next->ctxSwitches++;
217
218 if (prev->schedState == SCHED_STATE_RUNNING) {
220 TAILQ_INSERT_TAIL(&runnableQueue, prev, schedQueue);
221 }
222
223 Sched_Switch(prev, next);
224
226}
#define SCHED_STATE_RUNNING
Definition: thread.h:27
#define SCHED_STATE_RUNNABLE
Definition: thread.h:26
#define ASSERT(_x)
Definition: kassert.h:8
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:641
#define TAILQ_FIRST(head)
Definition: queue.h:555
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:659
ThreadQueue runnableQueue
Definition: sched.c:37
static void Sched_Switch(Thread *oldthr, Thread *newthr)
Definition: sched.c:175
uint64_t ctxSwitches
Definition: thread.h:51
int schedState
Definition: thread.h:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Sched_SetRunnable()

void Sched_SetRunnable ( Thread thr)

Sched_SetRunnable –

Set the thread to the runnable state and move it from the wait queue if necessary to the runnable queue.

Parameters
[in]thrThread to be set as runnable.

Definition at line 77 of file sched.c.

78{
80
81 if (thr->proc->procState == PROC_STATE_NULL)
83
84 if (thr->schedState == SCHED_STATE_WAITING) {
85 thr->waitTime += KTime_GetEpochNS() - thr->waitStart;
86 thr->waitStart = 0;
87 TAILQ_REMOVE(&waitQueue, thr, schedQueue);
88 }
90 TAILQ_INSERT_TAIL(&runnableQueue, thr, schedQueue);
91
93}
#define PROC_STATE_READY
Definition: thread.h:62
#define SCHED_STATE_WAITING
Definition: thread.h:28
#define PROC_STATE_NULL
Definition: thread.h:61
UnixEpochNS KTime_GetEpochNS()
Definition: ktime.c:194
ThreadQueue waitQueue
Definition: sched.c:33
int procState
Definition: thread.h:75
struct Process * proc
Definition: thread.h:39
uint64_t waitTime
Definition: thread.h:54
uint64_t waitStart
Definition: thread.h:55
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Sched_SetWaiting()

void Sched_SetWaiting ( Thread thr)

Sched_SetWaiting –

Set the thread to the waiting state and move it to the wait queue. The thread should be currently running.

Parameters
[in]thrThread to be set as waiting.

Definition at line 104 of file sched.c.

105{
107
109
111 TAILQ_INSERT_TAIL(&waitQueue, thr, schedQueue);
113
115}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Sched_SetZombie()

void Sched_SetZombie ( Thread thr)

Sched_SetZombie –

Set the thread to the zombie state and move it to the parent processes's zombie process queue. The thread should be currently running.

Parameters
[in]thrThread to be set as zombie.

Definition at line 126 of file sched.c.

127{
128 Process *proc = thr->proc;
129
130 /*
131 * Do not go to sleep holding spinlocks.
132 */
133 ASSERT(Critical_Level() == 0);
134
135 if (proc->threads == 1) {
136 // All processes have parents except 'init' and 'kernel'
137 ASSERT(proc->parent != NULL);
139 Spinlock_Lock(&proc->parent->lock); // Guards child list
141 TAILQ_REMOVE(&proc->parent->childrenList, proc, siblingList);
142 TAILQ_INSERT_TAIL(&proc->parent->zombieProc, proc, siblingList);
143 Spinlock_Unlock(&proc->parent->lock);
144 CV_Signal(&proc->zombieProcPCV);
146 }
147
148 /*
149 * Set as zombie just before releasing the zombieProcLock in case we had to
150 * sleep to acquire the zombieProcLock.
151 */
155
156 Spinlock_Lock(&proc->lock);
157 TAILQ_INSERT_TAIL(&proc->zombieQueue, thr, schedQueue);
158 Spinlock_Unlock(&proc->lock);
159
160 if (proc->threads == 1)
162}
uint32_t Critical_Level()
Definition: critical.c:45
void CV_Signal(CV *cv)
Definition: cv.c:59
#define PROC_STATE_ZOMBIE
Definition: thread.h:63
#define SCHED_STATE_ZOMBIE
Definition: thread.h:29
#define NULL
Definition: stddef.h:6
Definition: thread.h:65
Spinlock lock
Definition: thread.h:68
ProcessQueue zombieProc
Definition: thread.h:81
ThreadQueue zombieQueue
Definition: thread.h:89
uint64_t threads
Definition: thread.h:86
Process * parent
Definition: thread.h:78
CV zombieProcPCV
Definition: thread.h:84
Mutex zombieProcLock
Definition: thread.h:82
CV zombieProcCV
Definition: thread.h:83
ProcessQueue childrenList
Definition: thread.h:80
void Mutex_Unlock(Mutex *mtx)
Definition: mutex.c:83
void Mutex_Lock(Mutex *mtx)
Definition: mutex.c:52
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Sched_Switch()

static void Sched_Switch ( Thread oldthr,
Thread newthr 
)
static

Sched_Switch –

Switch between threads. During the creation of kernel threads (and by proxy user threads) we may not return through this code path and thus the kernel thread initialization function must release the scheduler lock.

Parameters
[in]oldthrCurrent thread we are switching from.
[in]newthrThread to switch to.

Definition at line 175 of file sched.c.

176{
177 // Load AS
178 PMap_LoadAS(newthr->space);
179
180 Thread_SwitchArch(oldthr, newthr);
181}
void Thread_SwitchArch(Thread *oldthr, Thread *newthr)
Definition: thread.c:84
void PMap_LoadAS(AS *space)
Definition: pmap.c:182
AS * space
Definition: thread.h:33
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ curProc

Thread* curProc[MAX_CPUS]

Current thread executing on a given CPU.

Definition at line 41 of file sched.c.

◆ runnableQueue

ThreadQueue runnableQueue

All runnable threads.

Definition at line 37 of file sched.c.

◆ schedLock

Spinlock schedLock

Scheduler lock that protects all queues.

Definition at line 29 of file sched.c.

◆ waitQueue

ThreadQueue waitQueue

All threads currently waiting.

Definition at line 33 of file sched.c.