Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does cooperative multitasking work?

I read this Wikipedia text slice:

Because a cooperatively multitasked system relies on each process regularly giving up time to other processes on the system, one poorly designed program can consume all of the CPU time for itself or cause the whole system to hang.

Out of curiosity, how does one give up that time? Is this some sort of OS call? Let's think about non-preemptive cases like fibers or evented IO that do cooperative multitasking. How do they give up that time?

Take this NodeJS example:

var fs = require('fs');
fs.readFile('/path/to/file', function(err, data) {});

It is obvious to me that the process does nothing while it's waiting for the data, but how does V8 in this case give up time for other processes?

Let's assume Linux/Windows as our OS.

Edit: I found out how Google is doing this with their V8.

On Windows they basically sleep zero time:

void Thread::YieldCPU() {
  Sleep(0);
}

And on Linux they make an OS call:

void Thread::YieldCPU() {
  sched_yield();
}

of sched.h.

like image 305
Tower Avatar asked Jun 29 '11 13:06

Tower


2 Answers

Yes, every program participates in the scheduling decisions of the OS, so you have to call a particular syscall that tells the kernel to take back over. Often this was called yield(). If you imagine how difficult it is to guarantee that a paticular line of code is called at regular, short intervals, or even at all, you get an idea of why cooperative multitasking is a suboptimal solution.

In your example, it is the javascript engine itself is interrupted by the OS scheduler, if it's a preemptive OS. If it's a cooperative one, then no, the engine gets no work done, and neither does any other process. As a result, such systems are usually not suitable for real-time (or even serious) workloads.

like image 189
Kilian Foth Avatar answered Nov 17 '22 20:11

Kilian Foth


An example of such an OS is NetWare. In that system, it was necessary to call a specific function (I think it is called ThreadSwitch or maybe ThreadSwitchWithDelay). And it was always a guess as to how often it was needed. In every single CPU-intensive loop in the product it was necessary to call one of those functions periodically.

But in that system other calls would result in allowing other threads to run. In particular (and germane to the question) is that I/O calls resulted in giving the OS the opportunity to run other threads. Basically any system call that gave control to the OS was sufficient to allow other threads to run (mutex/semaphore calls being important ones).

like image 28
Mark Wilkins Avatar answered Nov 17 '22 21:11

Mark Wilkins