AROS Vision
Modern and free Amiga-Compatible Experience on Amiga and PC
Article 11: Amiga Multitasking – Tasks, Processes, Signals and Message Ports
One of the features that made the Amiga remarkable from the beginning was its preemptive multitasking operating system.
Even on an Amiga with a Motorola 68000 running at around 7 MHz, several programs can appear to run simultaneously. You can copy files, play music, use the Shell and work with another application without having to wait for each program to finish.
But how does this work?
At the center of the Amiga's multitasking architecture is Exec, the small but extremely important core of AmigaOS.
To understand Amiga multitasking, we need to examine four fundamental concepts:
Tasks
Processes
Signals
Message ports
Together they form the communication and scheduling infrastructure behind much of AmigaOS.
1. Exec – The Heart of Multitasking
We have already encountered:
exec.library
in previous articles.
Exec provides fundamental operating-system services such as:
task scheduling
memory allocation
interrupts
signals
message ports
message passing
libraries
devices
Exec is therefore much more than an ordinary application library.
It provides the fundamental environment in which many other parts of AmigaOS operate.
A simplified picture looks like this:
Applications
|
v
Processes / Tasks
|
v
Exec
|
+-- Scheduler
+-- Signals
+-- Message Ports
+-- Memory
+-- Devices
|
v
Hardware
Understanding Exec is one of the keys to understanding AmigaOS internally.
2. What Is Multitasking?
A CPU such as the Motorola 68000 can normally execute only one instruction stream at a time.
So how can several programs run at once?
The operating system rapidly gives different tasks opportunities to execute.
Conceptually:
Time →
Task A ███ ███
Task B ███ ███
Task C ███ ███
At one moment Task A is running.
Shortly afterwards, Task B may be running.
Then Task C.
Because these transitions happen quickly, the user experiences several programs running concurrently.
This is multitasking.
3. Preemptive Multitasking
AmigaOS uses preemptive multitasking.
This is an important distinction.
In a purely cooperative system, a running program must voluntarily give other programs opportunities to run.
In a preemptive system, the operating system's scheduler can suspend a task and allow another eligible task to execute.
Conceptually:
Task A running
|
v
Scheduler selects Task B
|
v
Task B running
|
v
Scheduler selects Task C
|
v
Task C
running
Applications therefore do not have exclusive ownership of the CPU merely because they are currently executing.
Exec manages which task receives CPU time.
4. The Task
The fundamental unit of execution managed by Exec is a Task.
A task contains information Exec needs in order to manage an independently executing piece of code.
Conceptually, this includes things such as:
Task
|
+-- execution state
+-- stack
+-- priority
+-- signal information
+-- scheduling information
When another task runs, the CPU state associated with the current task must be preserved so that execution can later continue.
From the program's perspective, it appears as if it continues from where it left off.
5. Task States
A task does not have to be executing all the time.
For our purposes, it is useful to imagine three basic conditions:
RUNNING
READY
WAITING
Running
The task currently owns the CPU.
Ready
The task could run but another task is currently executing.
Waiting
The task is waiting for something to happen.
For example, it might be waiting for:
a message
an I/O operation
a signal
some other event
The important point is that a waiting task does not need to constantly consume CPU time checking whether something has happened.
6. Why Waiting Matters
Imagine a program waiting for data from the serial port.
A poor design would repeatedly ask:
Is data available?
No.
Is data available?
No.
Is data available?
No.
This is called busy waiting or polling.
It wastes CPU time.
A better model is:
Request data
|
v
Wait
|
| CPU can run other tasks
|
v
Event occurs
|
v
Wake up
This fits naturally into the Amiga's multitasking architecture.
A task can sleep while another part of the system performs work.
7. The Scheduler
Exec contains the mechanisms responsible for deciding which task should run.
Tasks have priorities.
Conceptually:
Task A priority 5
Task B priority 0
Task C priority -5
Priority influences which task is selected when multiple tasks are ready.
Higher-priority work can therefore take precedence over lower-priority tasks.
However, this must be used carefully.
A badly designed task with an inappropriate priority can interfere with the responsiveness of other software.
8. Context Switching
Suppose Task A is running and Exec decides that Task B should run.
The system has to switch execution contexts.
In simplified terms:
Task A
|
| save processor state
v
Exec Scheduler
|
| restore Task B state
v
Task B
Later the process can be reversed.
From Task A's perspective, execution continues from its previous point.
This operation is known as a context switch.
Context switching is fundamental to preemptive multitasking.
9. But What Is a Process?
AmigaOS also uses another term:
Process
A Process is closely related to a Task, but they are not exactly the same thing in AmigaOS terminology.
A useful beginner-level description is:
Every AmigaDOS Process includes an Exec Task, but not every Exec Task is an AmigaDOS Process.
A basic Exec Task provides the mechanisms necessary for execution and scheduling.
An AmigaDOS Process extends this with information required by DOS.
Conceptually:
Process
+-----------+
| DOS data |
| |
| Task |
+-----------+
A Process can therefore participate naturally in the AmigaDOS environment.
10. Why the Difference Matters
Imagine a low-level operating-system component that merely needs to execute code and exchange Exec messages.
It may only need to be a Task.
A Shell command, on the other hand, normally operates inside the AmigaDOS environment.
It may need things such as:
filesystem access
input
output
command-line information
DOS-specific state
For this reason, AmigaDOS works with Processes built around Exec Tasks.
This illustrates another principle of AmigaOS:
Exec
|
+-- Task
|
+-- AmigaDOS adds additional information
|
v
Process
Higher layers of AmigaOS build functionality on top of lower-level Exec services.
11. Tasks Need to Communicate
Multitasking alone would not be enough.
Imagine an operating system containing dozens of independent tasks that could never communicate.
That would not be very useful.
Tasks therefore need mechanisms for coordinating their work.
AmigaOS makes extensive use of:
signals
message ports
messages
These mechanisms are deeply integrated into Exec.
12. Signals
A signal is a lightweight mechanism used to notify a task that something has happened.
Conceptually:
Task A
|
| signal
v
Task B
Task B may be waiting for that signal.
Instead of constantly checking for the event, it can sleep until the appropriate signal arrives.
For example:
Task B
|
v
Wait()
|
| sleeping
|
Signal arrives
|
v
Task
becomes ready
This allows tasks to cooperate efficiently.
13. Signals Are Notifications
An important concept is that a signal is primarily a notification.
Conceptually, a signal can mean:
"Something happened."
It does not necessarily contain detailed information about what happened.
This leads us to another mechanism.
If tasks need to exchange actual information rather than merely indicate an event, they can use messages.
14. Message Ports
Exec provides message ports.
A message port gives a task a place where messages can be delivered.
Think of it as a mailbox:
Message Port
+-----------+
Task A ---> | Message 1 |
Task C ---> | Message 2 |
| Message 3 |
+-----------+
|
v
Task B
Other tasks can send messages to the port.
The receiving task can retrieve and process the messages.
This is one of the most fundamental communication concepts in AmigaOS.
15. Messages
A message is a data structure used to exchange information between tasks.
The basic communication model becomes:
Task A
|
| PutMsg()
v
Message Port
|
| signal receiver
v
Task B
|
| GetMsg()
v
Message
The receiving task can inspect the message and perform the appropriate operation.
If necessary, the message can later be returned to the sender.
16. Sending and Replying
A typical message exchange can conceptually look like this:
Task A
|
| Create request
|
v
Send Message
|
v
Task B
|
| Process request
|
v
Reply Message
|
v
Task A
This gives us a request-and-response mechanism.
Rather than Task A directly manipulating the internal data belonging to Task B, it can ask Task B to perform an operation.
This reduces the need for tightly connected components.
17. PutMsg(), GetMsg() and ReplyMsg()
At the programming level, important Exec functions associated with message communication include:
PutMsg()
GetMsg()
ReplyMsg()
WaitPort()
Conceptually:
PutMsg()
Places a message in another message port.
PutMsg(port, message)
GetMsg()
Retrieves a message from a port.
message = GetMsg(port)
ReplyMsg()
Returns a processed message.
ReplyMsg(message)
WaitPort()
Allows a task to wait until a message becomes available at a port.
Together these operations form a powerful communication mechanism.
18. Waiting for a Message
Consider a task that provides some service.
It might conceptually behave like this:
Wait for message
|
v
Receive message
|
v
Perform operation
|
v
Reply
|
v
Wait for next message
Notice what happens while there are no requests.
The task does not have to run continuously.
It can wait.
Exec can then use the CPU for other tasks.
This event-driven style contributes greatly to the efficiency of the Amiga operating system.
19. Message Ports and Signals
Work Together
Signals and message ports are closely connected.
A message port can use a signal to notify its owning task that a message has arrived.
Conceptually:
Sender
|
| PutMsg()
v
Message Port
|
+---- message placed in queue
|
+---- signal receiver
|
v
Waiting Task
|
v
GetMsg()
The signal tells the task:
Something is waiting for you.
The message contains the actual information.
This distinction is extremely useful.
Signal
= notification
Message
= information
20. Why Message Passing Suits the Amiga
The Amiga was designed as a multitasking computer.
Message passing fits this architecture extremely well.
Rather than building the operating system around components that constantly manipulate each other's internal state, different components can communicate through defined requests.
Conceptually:
Component A
|
| request
v
Component B
|
| response
v
Component A
This creates a modular system.
We have already encountered this idea without necessarily recognizing it.
21. Devices Revisited
Remember the .device components from Article 7?
Examples included:
serial.device
timer.device
audio.device
trackdisk.device
Programs can send I/O requests to devices.
Now we can understand why this architecture works so naturally with Exec.
A simplified asynchronous I/O operation looks like:
Application
|
| I/O request
v
Device
|
| operation performed
|
v
Request completed
|
| signal/message
v
Application
The application can potentially perform other work while the I/O operation is taking place.
This is a much better fit for multitasking than simply blocking the entire computer until the operation finishes.
22. DOS Handlers
Revisited
The same basic architectural philosophy also appears in AmigaDOS.
In Article 7 we encountered handlers.
For example:
RAM:
CON:
SER:
AmigaDOS can communicate with handlers using message-based mechanisms commonly described in terms of DOS packets.
Conceptually:
AmigaDOS Process
|
| DOS Packet
v
Handler Process
|
v
Resource
Again, the system consists of cooperating components exchanging requests.
This is why message passing is so important to understanding AmigaOS.
23. Intuition
Also Uses Messages
The idea appears again in the graphical user interface.
Suppose you create a window.
The user may:
move the mouse
press a button
select a menu item
resize the window
close the window
Your application needs to know that these events occurred.
Amiga applications commonly receive user-interface events through Intuition messages, often called IntuiMessage structures.
Conceptually:
User
|
v
Intuition
|
| IntuiMessage
v
Application's message port
|
v
Application
The application can wait for events instead of continuously polling the mouse and keyboard itself.
Once again:
Wait
↓
Event
↓
Message
↓
Process event
↓
Wait
The same architectural style appears throughout the operating system.
24. Example: Waiting for a Window Event
Imagine a program containing a window.
Instead of doing this:
Check mouse
Check keyboard
Check window
Check mouse
Check keyboard
Check window
...
the application can wait for an event.
Conceptually:
Application
|
v
Wait for signal
|
| application sleeps
|
v
User clicks mouse
|
v
Intuition message arrives
|
v
Application wakes
|
v
Process message
When nothing is happening, another task can use the CPU.
This is an important reason event-driven programming and multitasking work so well together.
25. Waiting for Several Events
A program may need to monitor more than one source.
For example, imagine a terminal program.
It may need to respond to:
Window events
Serial data
Timer events
Conceptually:
Application
|
v
Wait
+--------+--------+
| | |
v v v
Window Serial Timer
signal signal signal
The program can sleep until one of the events occurs.
It then determines which event caused it to wake up and processes that event.
This is a powerful model for writing responsive applications without wasting CPU time.
26. Multitasking and the Custom Chips
There is another important dimension to Amiga multitasking.
Not all work has to be performed by the CPU.
The Amiga custom chips can perform various operations independently or semi-independently.
For example:
CPU
|
+---- application code
|
+---- operating-system tasks
Agnus / Alice
|
+---- DMA coordination
+---- Copper
+---- Blitter access
Paula
|
+---- audio DMA
+---- disk-related functions
+---- serial functions
While the CPU executes tasks, DMA-capable hardware can move certain types of data without requiring the CPU to perform every individual transfer.
This hardware architecture complements the multitasking operating system very well.
27. Multitasking Is Not Multiple CPUs
It is important not to confuse multitasking with multiprocessing.
A classic Amiga with one 68000 has one main CPU executing ordinary CPU instructions.
Exec rapidly schedules different tasks on that CPU.
From the user's perspective:
Program A running
Program B running
Program C
running
Internally, CPU execution is being shared over time.
At the same time, specialized chips and DMA engines can perform their own work.
This combination contributes to the characteristic behaviour of the Amiga.
28. A Simplified Real-World Example
Imagine that you are using the Amiga to download data while writing text and playing music.
Conceptually, the system might involve:
Editor Process
|
+---- waits for user input
Communication Process
|
+---- waits for serial events
Music Player
|
+---- prepares audio data
audio.device / hardware
|
+---- audio playback
Exec
|
+---- schedules CPU tasks
+---- handles signals
+---- manages message passing
When the editor is waiting for you to press a key, there is no reason for it to consume all available processor time.
Other tasks can run.
When new serial data arrives, the communication software can be notified.
Meanwhile, audio hardware can continue playing prepared sound data.
This is where the complete Amiga architecture begins to make sense.
29. Why a Slow Amiga Can Still Feel Responsive
Looking only at CPU speed can be misleading.
An original Amiga 500's 68000 processor runs at only around 7 MHz, which sounds extremely slow by modern standards.
But the machine was designed as a system in which responsibilities are distributed.
Several factors contribute:
Preemptive multitasking
+
Event-driven software
+
Message passing
+
Asynchronous I/O
+
DMA
+
Custom processors
The CPU does not necessarily have to perform every operation itself.
Good Amiga software can wait when it has nothing to do and allow other tasks to use processor time.
The result can feel remarkably responsive considering the modest CPU performance.
30. Cooperative Components
Perhaps the best mental model for AmigaOS is not:
One large operating system
but:
Many cooperating components
For example:
Exec
|
+---------+---------+
| | |
Task Task Task
| | |
+---- messages -----+
|
+-------+-------+
| |
Devices AmigaDOS
|
Handlers
|
Resources
Signals notify tasks.
Messages transfer information.
Message ports provide destinations.
The scheduler decides which ready task should execute.
Devices and handlers provide services.
Libraries provide shared functionality.
These mechanisms work together rather than existing as isolated operating-system features.
31. Task vs Process vs Signal vs Message Port
For beginners, the following mental model is useful.
Task
A unit of execution managed by Exec.
Think:
Something that Exec can schedule.
Process
A Task extended with AmigaDOS-related information.
Think:
A task that can operate naturally in the DOS environment.
Signal
A lightweight notification.
Think:
Something happened.
Message
Information sent between tasks.
Think:
Here is a request or some information.
Message Port
A destination and queue for messages.
Think:
A mailbox for a task.
Together:
Task A
|
| Message
v
Message Port
|
| Signal
v
Task B
|
| Process message
v
Reply
This simple model explains a surprising amount of AmigaOS.
32. Connecting the Previous Articles
We can now connect almost everything we have learned.
At the hardware level:
CPU + Custom Chips + DMA
Above this sits Exec:
Exec
|
+-- Tasks
+-- Scheduling
+-- Signals
+-- Messages
+-- Memory
+-- Devices
AmigaDOS builds additional functionality on top:
AmigaDOS
|
+-- Processes
+-- Files
+-- Handlers
+-- Assigns
+-- Shell
And the graphical environment adds:
Intuition
|
+-- Screens
+-- Windows
+-- Gadgets
+-- User-interface events
Finally, the user sees:
Workbench
Applications
Shell
This produces a layered view of the system:
User
↓
Applications / Workbench / Shell
↓
Intuition / AmigaDOS / Libraries
↓
Exec
↓
Devices / Drivers
↓
Hardware
Although simplified, this is a useful mental map of the Amiga operating system.
33. Why This Architecture Was So Important
The Amiga's design made multitasking a fundamental property of the operating system.
Applications were not supposed to assume that they were the only software running.
Operating-system components could communicate through defined mechanisms rather than relying entirely on direct calls and shared global state.
This encouraged software built around:
events
messages
asynchronous operations
shared system libraries
independent tasks
These concepts remain fundamental in modern operating-system and application design.
The terminology may differ, but the underlying ideas are very familiar today.
Conclusion
Exec's multitasking architecture is one of the most important parts of AmigaOS.
The central ideas are surprisingly elegant:
Tasks are scheduled.
Processes extend tasks into the AmigaDOS world.
Signals notify tasks.
Message ports receive messages.
Messages carry information.
Waiting tasks do not needlessly consume CPU time.
What makes the Amiga particularly interesting is how consistently these ideas appear throughout the operating system.
They are used in communication with devices, AmigaDOS handlers, graphical applications and other system components.
This gives us a much deeper understanding of something we have encountered repeatedly throughout this course:
AmigaOS is not simply a collection of programs. It is a collection of cooperating, concurrently executing components.
And once we understand that, we are ready to explore perhaps the most famous part of the Amiga's software environment.
Next: Article 12 – Intuition, Screens, Windows and Workbench
In Article 12, we will look underneath the graphical interface and examine Intuition, including screens, windows, gadgets, IntuiMessage, public and custom screens, and the relationship between Intuition, Workbench and graphics.library.