signal.c File Reference

IPC signals implementation. More...

#include "signal.h"
#include "cfg/cfg_timer.h"
#include <cfg/debug.h>
#include <cfg/depend.h>
#include <cpu/irq.h>
#include <kern/proc.h>
#include <kern/proc_p.h>
#include <drv/timer.h>

Go to the source code of this file.

Functions

sigmask_t sig_check (sigmask_t sigs)
 Check if any of the signals in sigs has occurred and clear them.
sigmask_t sig_wait (sigmask_t sigs)
 Sleep until any of the signals in sigs occurs.
sigmask_t sig_waitTimeout (sigmask_t sigs, ticks_t timeout)
 Sleep until any of the signals in sigs or timeout ticks elapse.
void sig_send (Process *proc, sigmask_t sigs)
 Send the signals sigs to the process proc and immeditaly dispatch it for execution.
void sig_post (Process *proc, sigmask_t sigs)
 Send the signals sigs to the process proc.

Detailed Description

IPC signals implementation.

Signals are a low-level IPC primitive. A process receives a signal when some external event has happened. Like interrupt requests, signals do not carry any additional information. If processing a specific event requires additional data, the process must obtain it through some other mechanism.

Despite the name, one shouldn't confuse these signals with POSIX signals. POSIX signals are usually executed synchronously, like software interrupts.

Signals are very low overhead. Using them exclusively to wait for multiple asynchronous events results in very simple dispatch logic with low processor and resource usage.

The "event" module is a higher-level interface that can optionally deliver signals to processes. Messages provide even higher-level IPC services built on signals. Semaphore arbitration is also implemented using signals.

In this implementation, each process has a limited set of signal bits (usually 32) and can wait for multiple signals at the same time using sig_wait(). Signals can also be polled using sig_check(), but a process spinning on its signals usually defeats their purpose of providing a multitasking-friendly infrastructure for event-driven applications.

Signals are like flags: they are either active or inactive. After an external event has delivered a particular signal, it remains raised until the process acknowledges it using either sig_wait() or sig_check(). Counting signals is not a reliable way to count how many times a particular event has occurred, because the same signal may be delivered twice before the process can notice.

Signals can be delivered synchronously via sig_send() or asynchronously via sig_post().

In the synchronous case the process is awakened if it was waiting for any signal and immediately dispatched for execution via a direct context switch, if its priority is greater than the running process.

  • Synchronous-signal delivery:
     [P1]____sig_send()____proc_wakeup()____[P2]
 

In the asynchronous case, the process is scheduled for execution as a consequence of the delivery, but it will be dispatched by the scheduler as usual, according to the scheduling policy.

  • Asynchronous-signal delivery:
     [P1]____sig_post()____[P1]____proc_schedule()____[P2]
 

In this way, any execution context, including an interrupt handler, can deliver a signal to a process. However, synchronous signal delivery from a non-sleepable context (like an interrupt handler) is forbidden in order to avoid potential deadlock conditions. Instead, sig_post() can be used from any context, expecially from interrupt context or when the preemption is disabled.

Multiple independent signals may be delivered at once with a single invocation of sig_send() or sig_post(), although this is rarely useful.

Signal Allocation

There's no hardcoded mapping of specific events to signal bits. The meaning of a particular signal bit is defined by an agreement between the delivering entity and the receiving process. For instance, a terminal driver may be designed to deliver a signal bit called SIG_INT when it reads the CTRL-C sequence from the keyboard, and a process may react to it by quitting.

SIG_SINGLE

The SIG_SINGLE bit is reserved as a convenient shortcut in those simple scenarios where a process needs to wait on just one event synchronously. By using SIG_SINGLE, there's no need to allocate a specific signal from the free pool. The constraints for safely accessing SIG_SINGLE are:

  • The process MUST sig_wait() exclusively on SIG_SINGLE
  • SIG_SIGNAL MUST NOT be left pending after use (sig_wait() will reset it automatically)
  • Do not sleep between starting the asynchronous task that will fire SIG_SINGLE, and the call to sig_wait().
  • Do not call system functions that may implicitly sleep, such as timer_delayTicks().
Version:
Id
signal.c 3296 2010-03-29 13:55:34Z batt
Author:
Bernie Innocenti <bernie@codewiz.org>

Definition in file signal.c.


Function Documentation

sigmask_t sig_check ( sigmask_t  sigs  ) 

Check if any of the signals in sigs has occurred and clear them.

Returns:
the signals that have occurred.

Definition at line 150 of file signal.c.

void sig_post ( Process *  proc,
sigmask_t  sigs 
)

Send the signals sigs to the process proc.

The process will be awoken if it was waiting for any of them.

Note:
This call is interrupt safe.

Definition at line 299 of file signal.c.

void sig_send ( Process *  proc,
sigmask_t  sigs 
)

Send the signals sigs to the process proc and immeditaly dispatch it for execution.

The process will be awoken if it was waiting for any of them and immediately dispatched for execution.

Note:
This function can't be called from IRQ context, use sig_post() instead.

Definition at line 284 of file signal.c.

sigmask_t sig_wait ( sigmask_t  sigs  ) 

Sleep until any of the signals in sigs occurs.

Returns:
the signal(s) that have awoken the process.

Definition at line 168 of file signal.c.

sigmask_t sig_waitTimeout ( sigmask_t  sigs,
ticks_t  timeout 
)

Sleep until any of the signals in sigs or timeout ticks elapse.

If the timeout elapse a SIG_TIMEOUT is added to the received signal(s).

Returns:
the signal(s) that have awoken the process.
Note:
Caller must check return value to check which signal awoke the process.

Definition at line 224 of file signal.c.