The 31 least-significant bits of the 32-bit signal word each specify a different signal; the most-significant bit is used for errors. Eight of the signal bits (0 to 7) are reserved by the kernel for system signals; the other 23 bits (8 to 30) are left for custom user-task signals.
AllocSignal()
call,
which returns a 32-bit value containing the next unused user signal bit (the 32-bit value is called a signal mask). The task can send its signal mask to other tasks; they can then send a signal back to the task, using the user signal bit set in its signal mask.
All tasks can receive system signals at any time. The lower-8 signal bits are reserved for this purpose. For example, the system sends a task a signal (SIGF_DEADTASK
) whenever one of its child threads or task dies.
SendSignal()
call to specify the item number of the task it wants to signal and passes along the signal mask. The kernel logically ORs the signal mask into the receiving task's TCB. Bits set in the t_SigBits
field of the TCB indicate signals that the task has received, but not yet acknowledged.
WaitSignal()
call. The kernel checks to see if any of the bits in the task's signal mask match the bit mask passed WaitSignal()
, indicating that a signal has been received on that bit. If so, WaitSignal()
clears the bits that match and immediately returns, letting the task act on any signals it has received. If there are no received signals in the signal mask, the task is put in the wait queue until it receives a signal it wants.
FreeSignal()
call to pass along a free signal mask. The free signal mask should have a 1 in each bit where the signal bit is to be freed (that is, set to 0 in the signal mask) and a 0 where the signal bit remains as it is.
A message won't work without two message ports: one created by the task receiving the message and another created by the task sending the message. The message port is an item that sets a user signal bit for incoming message notification. It includes a message queue that receives and stores incoming messages.
CreateMsg()
, CreateSmallMsg()
, and CreateBufferedMsg()
. These functions accept a string of text as the message's name, a priority for the message, and the item number of the reply port for replies to the message. It returns the item number of the newly created message for working with the message later.
CreateMsgPort()
call,
which it provides with a string of text as a message port name. The kernel creates a message queue in system RAM for the message port, automatically assigns a user-task signal bit for the message port, and gives the message port an item number. The task is now ready to receive messages at the port.
FindMsgPort()
call to find the item number.) The sending task then uses either SendMsg()
or SendSmallMsg()
to fill out a message, providing a destination message port item number and some message data to pass. The kernel inserts the message, according to priority, into the destination port message queue, then signals the receiving task that a message has arrived at its message port.
GetMsg()
call
to check the message port and retrieve the top message in the list if there are any messages. If there are no messages, the task resumes execution.
WaitPort()
call to wait for a message. This puts the task into wait state until it receives a message at its message port. The task
then retrieves the message and resumes execution.
ReplyMsg()
or ReplySmallMsg()
to return the same message to the reply port with a 4-byte reply written into the message (stored in the 4-byte msg_Result
field of the Message
structure). The sending task receives the reply and reads the 4-byte reply.