Question

Many operating systems references say that with cooperative (as opposed to preemptive) multitasking, a process keeps the CPU until it explicitly voluntarily suspends itself. If a running process performs an I/O request that cannot be immediately satisfied (e.g., requests a key stroke that is not yet available), does the scheduler suspend it, or does it really keep the CPU until the request can be serviced?

[Edited to replace "blocks on i/o" with "performs an I/O request that cannot be immediately satisfied."]

Was it helpful?

Solution

In a truly "cooperative" setting, and if there was no hardware protection, a process could certainly block on I/O and not relinquish control until the I/O was done (or never relinquish control at all). For example, Windows 3.1 was this way: if a single user process wanted to take over the entire computer, and prevent anything else from running, it could.

But on a system with multitasking you expect the system API I/O commands to relinquish control of the processor when they are called. So when a running process blocks on I/O, assuming that the process uses the normal system APIs, other processes will be allowed to run until the I/O is complete, and eventually the original process will resume once the I/O is done. In other words, calling a blocking I/O function is one way that a process on a cooperative system can voluntarily suspend itself.

OTHER TIPS

If a running process blocks on i/o

Blocking on IO is pretty much equivalent to suspending your process. In the context of the linux kernel, executing some IO system call such as read() will cause a sysenter or interrupt handler to trigger to look after that IO, calling do_sys_read() ultimately. Here, if the current request cannot immediately be satisfied, the function calls sched() which then may execute another process.

In the context of a co-operative system, I would expect that when you make a system call for some IO reason, if the request cannot be satisfied the kernel picks another task and executes that. This document provides some background - basically, if you waited on IO, you could be hung forever waiting for that IO. The idea of co-operative scheduling being that you frequently call sched() or the equvalent relinquish-the-cpu method, if doing CPU-intensive tasks.

Kernel-mode considerations get more interesting. On architectures where they are available such as certain embedded platforms, interrupts handlers will still be invoked in response to hardware or software interrupts. It is usually possible, implementation-wise, to disable interrupt handling, but that also has drawbacks.

In the cooperative scheduling (preferably cooperative multitasking) model, there is no concept of a scheduler in a sense that the operating system does not have any control of how long the process runs.

An application programmed correctly would voluntarily give up the CPU on I/O. But, badly written applications might just keep waiting on I/O, thereby blocking other processes.

PS: This approach was later given up by most of the OS in favor of preemptive-scheduling (which had an external scheduler) and now we have all sorts of different scheduling algorithms used by different OS.

EDIT: My answer was based on the scheduling as described in its original form (years ago :P). As Gilles commented some systems still use cooperative scheduling. And there is a scheduler. I am not sure if those systems use COS in its pure and original form.

Co-operative multitasking implies that an executing context must explicitly relinquish control to the scheduler, and if it wishes, can prevent a context switch from occurring.

Most implementations explicitly perform a context switch for any system call that does not return promptly, and often even if they do, to increase the fairness of processor allocation.

Usually it is only possible for failed processes (or intentionally denying service to the remainder of the system) to prevent frequent task-switching.

Pre-emption, as explained by Gilles, is a limitation of the architecture of the system that prevents timed interruption of the active task and forced context switches.

Licensed under: CC-BY-SA with attribution
Not affiliated with cs.stackexchange
scroll top