|     Final Exam (Thurs., May 6, 9:30-11:20)     |     25%     |
|     1st Segment Test (Wed., Feb. 11)     |     15%     |
|     2nd Segment Test (Mon., Mar. 15)     |     15%     |
|     3nd Segment Test (Wed., Apr. 21)     |     15%     |
|     Projects, HW, quizzes, participation     |     30%     |
|     Chapter One     |     Exercises 2, 3, 4, 6, 8, 12, 13, 15, and the following:
What happens when the code         for (i=0; i<3; i++) fork(); is execute? How many processes will be created?     |
    Due: 1/26     |
|     Chapter Two, First Batch     |     Exercises 2 (give two different reasons), 28, 30, 31,
32 ("starve" means stuck forever in the ready queue without running),
38 (handwritten code is OK - indicate where to insert it),
plus the following:
|
    Due: 2/9     |
|     Chapter Two and Chapter Three     |     Exercises 2.5, 2.8, 2.9, 2.10, 2.11, 2.16, 2.17, 3.11, 3.13, 3.14, 3.16, 3.17, 3.19     |     Due: 3/10     |
|     Chapter Four     |     Exercises 2, 4, 7, 8, 11, 13, 14, 16, 20, 22     |     Due: 4/14     |
|     Chapter Five     |     3, 7, 8, 10   plus
|
    (not collected)    |
07207 /*===========================================================================*
07208 * ready *
07209 *===========================================================================*/
07210 PRIVATE void ready(rp)
07211 register struct proc *rp; /* this process is now runnable */
07212 {
07213 /* Add 'rp' to the end of one of the queues of runnable processes. Three
07214 * queues are maintained:
07215 * TASK_Q - (highest priority) for runnable tasks
07216 * SERVER_Q - (middle priority) for MM and FS only
07217 * USER_Q - (lowest priority) for user processes
07218 */
07219
07220 if (istaskp(rp)) {
07221 if (rdy_head[TASK_Q] != NIL_PROC)
07222 /* Add to tail of nonempty queue. */
MQR rp->p_previousready = rdy_tail[TASK_Q];
07223 rdy_tail[TASK_Q]->p_nextready = rp;
07224 else {
MQR rp->p_previousready = NIL_PROC;
07225 proc_ptr = /* run fresh task next */
07226 rdy_head[TASK_Q] = rp; /* add to empty queue */
07227 }
07228 rdy_tail[TASK_Q] = rp;
07229 rp->p_nextready = NIL_PROC; /* new entry has no successor */
07230 return;
07231 }
07232 if (!isuserp(rp)) { /* others are similar */
07233 if (rdy_head[SERVER_Q] != NIL_PROC)
MQR rp->p_previousready = rdy_tail[SERVER_Q];
07234 rdy_tail[SERVER_Q]->p_nextready = rp;
07235 else
MQR rp->p_previousready = NIL_PROC;
07236 rdy_head[SERVER_Q] = rp;
07237 rdy_tail[SERVER_Q] = rp;
07238 rp->p_nextready = NIL_PROC;
07239 return;
07240 }
07241 if (rdy_head[USER_Q] == NIL_PROC)
07242 rdy_tail[USER_Q] = rp;
07243 rp->p_nextready = rdy_head[USER_Q];
07244 rdy_head[USER_Q] = rp;
MQR rp->p_previousready = NIL_PROC; /* adding at head here, so .... */
07245 /*
07246 if (rdy_head[USER_Q] != NIL_PROC)
07247 rdy_tail[USER_Q]->p_nextready = rp;
07248 else
07249 rdy_head[USER_Q] = rp;
07250 rdy_tail[USER_Q] = rp;
07251 rp->p_nextready = NIL_PROC;
07252 */
07253 }
while (TRUE) {
read_command(command, parameters);
if ( fork() != 0 ) {
if ("&" not in parameter list)
waitpid(-1, & status, 0);
} else {
execve(command, parameters, 0);
}
}
if (rdy_head[TASK_Q] == NIL_PROC) {
proc_ptr = rdy_tail[TASK_Q] = rp;
} else {
rp->p_nextready = rdy_head[TASK_Q]->p_nextready;
rdy_tail[TASK_Q]->p_nextready = rdy_head[TASK_Q];
rdy_tail[TASK_Q] = rdy_head[TASK_Q];
}
rdy_tail[TASK_Q]->p_nextready = NIL_PROC;
rdy_head[TASK_Q] = rp;
return;
A 4 0 1 1
B 0 1 0 0
C 1 1 1 0
D 1 1 0 1
E 0 0 0 0
and would change the Resources Still (Potentially) Needed table to
A 0 1 0 0
B 0 1 1 2
C 3 1 0 0
D 0 0 1 0
E 2 1 1 0 and would result in P = (6 3 2 2) and A = (0 0 2 0).
This situation is SAFE. D could be allowed to make all its requests,
and run to completion. At that point the Resources Assigned table would be
A 4 0 1 1
B 0 1 0 0
C 1 1 1 0
E 0 0 0 0
The Resources Still Needed table would be
A 0 1 0 0
B 0 1 1 2
C 3 1 0 0
E 2 1 1 0
Would also have P = (5 2 2 1) and A = (1 1 2 1).
It is now OK to let Process A run to completion since its maximum
possible requests can be fulfilled. After A terminates, the
Resources Assigned table will be
B 0 1 0 0
C 1 1 1 0
E 0 0 0 0
The Resources Still Needed table would be
B 0 1 1 2
C 3 1 0 0
E 2 1 1 0
Would also have P = (1 2 1 0) and A = (5 1 3 2).
It's pretty easy from here, since you can let anybody run to completion now.
doswrite -a /dev/fd0 liberty.txt < life.c
DRAKE UNIVERSITY CONFERENCE ON UNDERGRADUATE RESEARCH IN THE SCIENCES Drake University science and mathematics students and their faculty mentors are making significant contributions in many different fields of scientific inquiry. To celebrate this, a conference showcasing the results of scientific research at Drake will be held on Friday April 9 in Olmsted Parents Hall on the Drake University Campus. The conference will allow students and faculty to communicate their results to other researchers in the Drake community. This is part of a broader effort to develop a culture of research that will foster opportunities for students and faculty to engage in new and more ambitious projects. The conference will feature student oral presentations (15 minutes each) and student and faculty poster presentations on current research projects. There will also be a chance for students to show off their knowledge of science and mathematics in the form of a quiz-bowl style competition. A schedule for the meeting is given below: 8:00 - 8:30 Poster Set-up 8:15 - 8:45 Registration 8:45 Welcome 8:55 Dean John Burney, Arts and Sciences 9:15 Oral Presentation: Luke Freml 9:30 Oral Presentation: Drew Fustin 9:45 Oral Presentation: Brian Rinner 10:00 Oral Presentation: Andy Windsperger 10:15-11:30 Poster Session 1* 11:30-12:15 Lunch (provided for authors) 12:15-1:00 Poster Session 2* 1:00 Oral Presentation: Eric Gorman 1:15 Oral Presentation: Kavitha Pundi 1:30 Oral Presentation: Elizabeth Carr 1:45 Oral Presentation: Nathan Walters 2:00 - 2:15 Break 2:15 - 2:45 Science/Math Quiz Bowl 2:45 - 2:55 Awards and Closing Remarks
Notice the use of mem_vid_copy and vid_vid_copy in the console.c code. There are several instances of these. Use mem_vid_copy(BLANK_MEM, ..... ) to blank out one of the console buffer spaces (c_ramqueue). Use vid_vid_copy( ... , ... , ... ) to copy a portion of one buffer to another buffer. The parameters are start of source, start of destination, number of characters to copy.