Multitasking Systems: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
(Added link to scheduling algorithms, because I keep looking for it here.)
(Add Real-Time multitasking)
 
(8 intermediate revisions by 4 users not shown)
Line 1: Line 1:
Multitasking Systems are operating systems (or even system extensions) which divide available processor time between several tasks automatically, creating the illusion that the tasks are running simultaneously.
Multitasking Systems are operating systems (or even system extensions) which share available processor time between multiple tasks automatically.


==Types of Multitasking Systems==
==Types of Multitasking Systems==
Line 6: Line 6:
===Cooperative Multitasking===
===Cooperative Multitasking===


This concept runs an application until it exits or yields control back to the OS. Examples for cooperative multitasking systems are pre-X MacOS, or Windows 3.x.
For [[Cooperative_Multitasking|cooperative multitasking]], a task uses the CPU until it voluntarily gives up the CPU (e.g. yields or exits). Examples of cooperative multitasking systems are pre-X MacOS, or Windows 3.x.


In some single language cooperative multitasking systems, such as Oberon and ruby, the compiler/interpreter automatically ensures that the code will periodically yield control; it allows such program to run in multi-threading on non-preemptive OS such as DOS. As yielding isn't necessary anymore, I'm not sure if we can still say it's cooperative multitasking.
In some single language cooperative multitasking systems, such as Oberon and ruby, the compiler/interpreter automatically ensures that the code will periodically yield control; it allows such program to run multiple threads on operating systems such as DOS.


===Preemptive Multitasking===
===Preemptive Multitasking===


In a preemptive multitasking system, the OS can take away control from (preempt) an application after a time slice is used up or a signal occurred. An example would be e.g. Linux, *BSD, post-3.x Windows, BeOS, or AmigaOS.
In a [[Preemptive_Multitasking|preemptive multitasking]] system, some task switches are not caused by the currently running task voluntarily giving up the CPU, and are done for one or more reasons (including when the task consumed the time it was given and/or when a higher priority task needed the CPU).


Examples include almost all modern operating systems - e.g. Linux, *BSD, post-3.x Windows, BeOS, AmigaOS.
You can further subdivide these systems into those who can preempt applications, and those who can preempt ''the kernel itself''. Linux (pre-2.6 kernel) is an example of the former, while e.g. AmigaOS is an example for the latter. This is a major concern for multimedia applications or any "soft" [Real-Time Systems] because a non-preemptive kernel introduces latencies that can ruin such "near real-time" performance.


You can further subdivide these systems into those who can preempt tasks, and those who can preempt ''the kernel itself''. Linux (pre-2.6 kernel) is an example of the former, while e.g. AmigaOS is an example for the latter. This is a major concern for multimedia applications or any "soft" [Real-Time Systems] because a non-preemptive kernel introduces latencies that can ruin such "near real-time" performance.
==How does it work==


===Real-Time Multitasking===
You have programs running. Each program has some binary code to be executed by the processor and an execution context made of e.g. registers state, [[stack]] content, etc.


In a Real-Time Operating System (RTOS), the scheduler works in a specific kind of [[Preemptive_Multitasking|preemptive multitasking]] system. It is designed for applications requiring responses within a fixed time window and tight time constraints. These systems are crucial in fields where delay can result in failure of the application.
Since you have a single CPU, you have a single program executed at a given moment and its execution context is the state of the cpu's registers while you may have plenty of programs sleeping, waiting for their turn with their context saved in OS's datastructures, right ?


Real-Time is defined by its determinism and high responsiveness ('''not always!''', a RTOS can be slow as long as the task change is performed within a fixed interval), operating under strict timing constraints to ensure predictable operation and rapid task switching. It is crucial for applications that cannot tolerate delays, such as avionics and aerospace systems, embedded medical devices or automotive controls.
Now, the OS has set up a timer interrupt, which causes the OS call a specific interrupt service routine at regular interval. When the timeslot for the current program runs out, the routine will save the current CPU context into a datastructure, select a new program to be run for the next timeslot, and load the CPU registers with the values that were saved in that process's datastructure.


[[Category:Task Models]]
If you still want to figure out, imagine a machine with an accumulator and a stack pointer. You can save the machine state, switch and restore another machine state with
[[Category:Multitasking]]


<pre>
PUSH ;; put the accumulator's content on stack
LOAD [current_pid] ;; load the current PID in the accumulator
STORE_SP [context_table+ACC] ;; save the stack of the suspended task

;; get somehow the PID for the next task into ACC, without using the stack

LOAD_SP [context_table+ACC] ;; load the stack of the chosen task
STORE [current_pid] ;; store it's PID
POP ;; get back the accumulator's content
IRET ;; end of interrupt
</pre>

Now imagine two programs on that machine, e.g.

<pre>
IMM 0 ;; into accumulator
here:
INC ;; accumulator++
JMP here
</pre>

and

<pre>
IMM 0
there:
DEC ;; accumulator --
JMP there
</pre>

Sketch on a papersheet the memory of the machine, with the pid_table, the two stacks , the current_pid variable, and then go. You should be able to emulate the behavior of that machine if --say-- you have a interrupt every 10+some_number_you_get_by_rolling_a_dice machine instructions.

And you'll see it can continue working on program 1 after it has been interrupted for 10+ instructions by program 2.

Of course "10+dice" is not enough to get decent performances. On modern systems, your timeslice is usually of a few milliseconds, which makes millions of instructions! Moreover, you don't always switch when the timer arise (because you might want the system clock more accurate than the switching rate) and you can switch on other events (e.g. because a program needs to wait for something or because something important like the end of a disk request happened).


==See Also==
==See Also==
Line 68: Line 33:
*[[Monotasking Systems]]
*[[Monotasking Systems]]
*[[Scheduling Algorithms]]
*[[Scheduling Algorithms]]
*[[Kernel Multitasking]]

===Threads===
*[[Topic:9669|Designing a kernel to be preemptible]]
*[[Topic:812|Making a fully preemptible kernel]]


=== External Links ===
=== External Links ===
Line 77: Line 39:


[[Category:Task Models]]
[[Category:Task Models]]
[[Category:Multitasking]]

Latest revision as of 13:40, 26 April 2024

Multitasking Systems are operating systems (or even system extensions) which share available processor time between multiple tasks automatically.

Types of Multitasking Systems

There are many ways multitasking can be achieved.

Cooperative Multitasking

For cooperative multitasking, a task uses the CPU until it voluntarily gives up the CPU (e.g. yields or exits). Examples of cooperative multitasking systems are pre-X MacOS, or Windows 3.x.

In some single language cooperative multitasking systems, such as Oberon and ruby, the compiler/interpreter automatically ensures that the code will periodically yield control; it allows such program to run multiple threads on operating systems such as DOS.

Preemptive Multitasking

In a preemptive multitasking system, some task switches are not caused by the currently running task voluntarily giving up the CPU, and are done for one or more reasons (including when the task consumed the time it was given and/or when a higher priority task needed the CPU).

Examples include almost all modern operating systems - e.g. Linux, *BSD, post-3.x Windows, BeOS, AmigaOS.

You can further subdivide these systems into those who can preempt tasks, and those who can preempt the kernel itself. Linux (pre-2.6 kernel) is an example of the former, while e.g. AmigaOS is an example for the latter. This is a major concern for multimedia applications or any "soft" [Real-Time Systems] because a non-preemptive kernel introduces latencies that can ruin such "near real-time" performance.

Real-Time Multitasking

In a Real-Time Operating System (RTOS), the scheduler works in a specific kind of preemptive multitasking system. It is designed for applications requiring responses within a fixed time window and tight time constraints. These systems are crucial in fields where delay can result in failure of the application.

Real-Time is defined by its determinism and high responsiveness (not always!, a RTOS can be slow as long as the task change is performed within a fixed interval), operating under strict timing constraints to ensure predictable operation and rapid task switching. It is crucial for applications that cannot tolerate delays, such as avionics and aerospace systems, embedded medical devices or automotive controls.


See Also

Articles

External Links