Answer this question using the answer sheet -- do not answer it here.
a. | Interrupt vector. |
b. | Information about open files. |
c. | Register state. |
d. | Timer interrupt. |
e. | Control status register. |
f. | Console interrupt. |
g. | Memory management information (e.g. main_memory pointer). |
h. | Kernel/User mode bit. |
i. | Context switches. |
j. | Information about CPU speed. |
k. | The process' cache. |
l. | The PC location of the process' next instruction. |
m. | Turnaround time. |
n. | Disk controller information. |
When the scheduler determines that it is time to schedule this new thread, detail for me exactly how it does so, from the time that the scheduler is called by a blocking thread to the time that the new thread is executing its procedure and arguments.
Merit raises are going to be decided next week, and you have just been given a very nice opportunity to make sure that you, and not Freddy, get that merit raise. You need to be a positive thinker, validating that Freddy has the seeds of a good point, but then you need to demonstrate to your boss that Freddy is being shortsighted. What do you say to your boss?
typedef struct { int instance; char *name; Semaphore *s; } Resource; |
In our system, resources are uniquely identified by the combination of their names and instance numbers.
Here are implementations of procedures called lock_multiple() and unlock_multiple(), which processes use to lock and unlock multiple resources:
void lock_multiple(Dllist resources) { Dllist tmp; Resource *r; dll_traverse(tmp, resources) { r = (Resource *) tmp->val.v; P(r->s); } return; } void unlock_multiple(Dllist resources) { Dllist tmp; Resource *r; dll_traverse(tmp, resources) { r = (Resource *) tmp->val.v; V(r->s); } return; } |
Clearly, if resources may be any list of resources, lock_multiple() and unlock_multiple() can deadlock. Rewrite them so that they cannot deadlock so long as:
You may not add any global variables to the system, and you may not augment the definition of a Resource. You also may not look at a semaphore's value.
CPU-A UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-B UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-C UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-D UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-E UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-F UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-G UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-H UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-I UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE CPU-J UNI 0 0 SERIAL UNI 10 10 UNI 0 0 UNI 180000000 180000000 UNI 1 1 CONSOLE VI-1 EXP 1800 20 SERIAL EXP 900 10 EXP 2 .2 EXP 500 0 UNI 1 1 CONSOLE VI-2 EXP 1800 20 SERIAL EXP 900 10 EXP 2 .2 EXP 500 0 UNI 1 1 CONSOLE WAV UNI 0 0 SERIAL NORM 300 0 UNI 1 1 UNI 100 100 UNI .168 .168 CD-ROM |
This job file has 10-CPU-bound processes, each of which runs for 10 iterations of 180 seconds of CPU time before pausing for trivial IO. It also has two VI processes, which feature very large sleep times, emulating a user typing at a vi console, and a WAV process which simulates a CD player. When this is simulated on a machine with a 50 millisecond timer interrupt and a context switch overhead of 200 microseconds, we see the following usage statistics:
ss-fcfsp job-10-cpu-vi-wav.txt machine-2.txt 100 100 QUIT=1000000
Time: 1000000.000000Job Stats (Averages unless specified)
Overall Stats
|
Answer the following questions:
typedef struct dllist { struct dllist *flink; struct dllist *blink; Jval val; } *Dllist; extern Dllist new_dllist(); extern void free_dllist(Dllist); extern void dll_append(Dllist, Jval); extern void dll_prepend(Dllist, Jval); extern void dll_insert_b(Dllist, Jval); extern void dll_insert_a(Dllist, Jval); extern void dll_delete_node(Dllist); extern int dll_empty(Dllist); extern Jval dll_val(Dllist); #define dll_traverse(ptr, list) \ for (ptr = list->flink; ptr != list; ptr = ptr->flink) #define dll_rtraverse(ptr, list) \ for (ptr = list->blink; ptr != list; ptr = ptr->blink) typedef struct jrb_node { unsigned char red; unsigned char internal; unsigned char left; unsigned char roothead; /* (bit 1 is root, bit 2 is head) */ struct jrb_node *flink; struct jrb_node *blink; struct jrb_node *parent; Jval key; Jval val; } *JRB; extern JRB make_jrb(); /* Creates a new rb-tree */ extern JRB jrb_insert_str(JRB tree, char *key, Jval val); extern JRB jrb_insert_int(JRB tree, int ikey, Jval val); extern JRB jrb_insert_dbl(JRB tree, double dkey, Jval val); extern JRB jrb_insert_gen(JRB tree, Jval key, Jval val, int (*func)(Jval,Jval)); extern JRB jrb_find_str(JRB root, char *key); extern JRB jrb_find_int(JRB root, int ikey); extern JRB jrb_find_dbl(JRB root, double dkey); extern JRB jrb_find_gen(JRB root, Jval, int (*func)(Jval, Jval)); extern void jrb_delete_node(JRB node); extern void jrb_free_tree(JRB root); #define jrb_traverse(ptr, lst) \ for (ptr = list->flink; ptr != list; ptr = ptr->flink) #define jrb_rtraverse(ptr, lst) \ for (ptr = list->blink; ptr != list; ptr = ptr->blink) typedef union { int i; double d; void *v; char *s; char c; ... } Jval; extern Jval new_jval_i(int); extern Jval new_jval_d(double); extern Jval new_jval_v(/* void */); extern Jval new_jval_s(char *); extern Jval new_jval_c(char); ... extern int jval_i(Jval); extern double jval_d(Jval); extern void *jval_v(Jval); extern char *jval_s(Jval); extern char jval_c(Jval); ...