Putting Processes to Sleep

Sleeping Processes

There are two system calls in XINU that put a process to sleep:

These calls put the calling process to sleep for N tenths of a second or N seconds respectively. Essentially the call blocks for that long.

The implementation is interesting. Sleeping processes are put on something called a delta queue. Processes are placed on the sleeping process delta queue (called the clockq) in order of when they are to awaken. The key for each process on this queue is the number of clock ticks after which this process should be woken once all the processes ahead of it are woken. For example, given the delta queue below:

process 5 will be woken 7 time units after the current time, process 2 3 time units later (10 time units from now), and process 9 5 time units after that (15 time units from now). There is a routine, insertd, which inserts a process into a delta queue, given a key. The actual key value will likely be decremented as it is put into the queue. For example, adding a process (4) that is to sleep for 11 time units into the above list would place it after process two, and would give it a key value of 1 as shown below. Notice that if there is a process in the queue after the inserted one, its delta must be adjusted in order that its total time be maintained. Insertd takes care of this.

Sleep10(N)

So what does sleep10() do? It:

The setting of slnempty and sltop are designed to minimize the work that has to be done by the clock ISR. Again - the clock ISR is called so frequently that anything we can do to minimize the processing it has to do will be a significant help to overall system performance.

Aside

As an aside, XINU was designed to be able to run on a system that does not generate clock ISRs. In that case, making a process sleep is impossible. Sleep10() actually first checks a global variable called clkruns to be sure this system has a clock. On system startup, there is an assembly routine (called setclkr) that determines if there is a system clock, and sets clkruns appropriately. It does so by looping for a short time while waiting for a clock interrupt. If none occurs during the loop, it is assumed that there is no clock and clkruns is set to 0. If an interrupt does occur, clkruns is set to 1.

Sleep(N)

Sleep(N) is quite simple. It puts a process to sleep for the specified number of seconds. There is really no reason for this routine except, perhaps, convenience. Sleep() simply multiplies its argument by 10 and then calls sleep10(). The only problem is that for large values of n, multiplying by 10 would produce arithmetic overflow. Therefore, if the argument to sleep() is large, sleep() will loop calling sleep10() the appropriate number of times.

1