|
|
1.1 root 1: disk I/O thread - qlock conditions
2:
3: work to do (ALL threads should wake up and run main loop once) when
4: anything is added to either q (q_disk, q_nodisk), or
5: -diskPresent needs to wakeup I/O thread to tell it "disk present"
6:
7: another way:
8: work to do when
9: q_nodisk non-empty, or
10: ((!queue_empty(q_disk)) &&
11: (lastReadyState != RS_NODISK) &&
12: (lastReadyState != RS_EJECTING) &&
13: (!ejectPending))
14:
15: threads sleep when
16: q_disk and q_nodisk empty
17: q_nodisk empty && no disk present
18:
19: Update condition variable (WORK_TO_DO/NO_WORK_TO_DO):
20: -- enqueueIoBuf - set uncond to WORK_TO_DO
21: -- ioThreadWakeup - set uncond to WORK_TO_DO
22: -- in I/O thread - before sleeping (to end of loop, at final unlock).
23:
24: @interface NXCondition
25: {
26:
27: }
28:
29: - signal;
30: - broadcast;
31: - wait;
32:
33: ...IOThread:
34: {
35: while(1) {
36: service q_nodisk;
37: service q_disk if appropriate;
38: cal volCheckRequest if appropriate;
39: [NXcondition wait];
40: }
41: }
42:
43: enqueueIoBuf:
44: {
45: [qlock lock];
46: enqueue IOBuf;
47: [NXCondition broadcast]; // need a lock for this too?
48: [qlock unlock];
49: }
50: ..............
51:
52: How about NXConditionLock..
53: in IOQueue:
54: int workToDo;
55:
56: This is the "thread-work quanta" to do. Each IOBuf enqueued
57:
58: enqueueIoBuf
59: {
60: [qlock lock];
61: enqueue IOBuf;
62: workToDo += numThreads;
63: [qlock unlockWith:WORK_TO_DO];
64: }
65:
66: IOThread
67: {
68: while(1) {
69: [qlock lockWhen:WORK_TO_DO];
70: workToDo--;
71: if(workToDo == 0)
72: [qlock unlockWith:NO_WORK_TO_DO];
73: else
74: [qlock unlock];
75: service queues;
76: // all other unlocks leave condition variable alone.
77: }
78: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.