-
Notifications
You must be signed in to change notification settings - Fork 0
/
scheduler.c
153 lines (115 loc) · 2.26 KB
/
scheduler.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
** SCCS ID: @(#)scheduler.c 1.1 4/5/12
**
** File: scheduler.c
**
** Author: 4003-506 class of 20113
**
** Contributor:
**
** Description: Scheduler module
*/
#define __KERNEL__20113__
#include "headers.h"
#include "c_io.h"
#include "scheduler.h"
/*
** PRIVATE DEFINITIONS
*/
/*
** PRIVATE DATA TYPES
*/
/*
** PRIVATE GLOBAL VARIABLES
*/
/*
** PUBLIC GLOBAL VARIABLES
*/
Pcb *_current; // the current process
// the array of ready queues for our MLQ structure
// must be public so that the clock ISR can check it
Queue *_ready[ N_READYQ ];
/*
** PRIVATE FUNCTIONS
*/
/*
** PUBLIC FUNCTIONS
*/
/*
** _sched_init()
**
** initialize the scheduler module
*/
void _sched_init( void ) {
int i;
Status status;
for( i = 0; i < N_READYQ; ++i ) {
status = _q_alloc( &_ready[i], NULL );
if( status != SUCCESS ) {
_kpanic( "_sched_init",
"readyq alloc status %s",
status );
}
}
_current = NULL;
c_puts( " scheduler" );
}
/*
** _sched(pcb)
**
** schedule a process for execution according to is priority
**
** returns the status of the insertion into the ready queue
*/
Status _sched( Pcb *pcb ) {
Prio p;
Key key;
if( pcb == NULL ) {
return( BAD_PARAM );
}
// Insert into one of the N ready queues
// according to the priority of the process
p = pcb->priority;
if( p >= N_READYQ ) {
return( BAD_PRIO );
}
key.u = pcb->pid;
pcb->state = READY;
return( _q_insert( _ready[p], (void *) pcb, key ) );
}
/*
** _dispatch()
**
** give the CPU to a process
*/
void _dispatch( void ) {
int i;
Status status;
// select a process from the highest-priority
// ready queue that is not empty
for( i = 0; i < N_READYQ; ++i ) {
do {
if( _q_empty(_ready[i]) ) {
break;
}
// found one - make it the currently-running process
status = _q_remove( _ready[i], (void **) &_current );
if( status == SUCCESS ) {
// check to see if it needs to be cleaned up
if( _current->state == KILLED ) {
// yes - deallocate it
_cleanup( _current );
// go back and re-check this queue
continue;
}
_current->state = RUNNING;
_current->quantum = STD_QUANTUM;
return;
} else {
_kpanic( "_dispatch", "readyq deque status %s",
status );
}
} while( 1 );
}
_kpanic( "_dispatch", "no non-empty readyq", EMPTY_QUEUE );
}