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_signal (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.
Any execution context, including an interrupt handler, can deliver a signal to a process using sig_signal(). Multiple independent signals may be delivered at once with a single invocation of sig_signal(), 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 2506 2009-04-15 08:29:07Z duplo
Definition in file signal.c.
Function Documentation
| void sig_signal | ( | Process * | proc, | |
| sigmask_t | sigs | |||
| ) |
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.
