Go to the first, previous, next, last section, table of contents.

Job Queues

Every live job is in exactly one job queue at any given moment. In addition, all live jobs are in the `.ps' propdir.

  Jobs ready to run: .etc.run queue.
  'sleep'ing jobs:   .etc.doz queue.
  'pause'd   jobs:   .etc.poz queue.
  Stopped    jobs:   .etc.stp queue.

Dead jobs are not actually in any queue (being in a queue would keep them from ever being garbage-collected), but their q_this entry points to `.etc.ded', to make their status well-defined.

All other jobs are in a queue associated with the resource for which they are waiting:

  Jobs waiting to read from an empty message stream are in its q_in.
  Jobs waiting to write to  a  full  message stream are in its q_out.

The `.etc.doz' queue for sleeping jobs is sorted by time waited-for; all other queues rotate chronologically, with jobs inserted at the prev end and removed from the next end.

A job queue (joq) is a 4-vector with the logical structure:

struct joq {
   Vm_Obj next;  // Next job in queue.
   Vm_Obj prev;  // Prev job in queue.
   Vm_Obj owner; // Owner of    queue.
   Vm_Obj name;  // Queue name: "in" "out" "run" "doz" "poz" "stp" ...

Jobs are doubly linked into their queue via their q_next and q_prev fields. In an empty queue, next and prev point to the queue itself.

The currently running job is always next in the run queue. The run queue can be empty, in which case nothing much will happen until some external event wakes a job from some queue -- network I/O unblocking a job waiting on a message stream, say, or clock timing waking an `.etc.doz' job.

Go to the first, previous, next, last section, table of contents.