|
|
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.