Event (signal) handling. More...
Functions | |
| void | BZ_EventClear (int mask) |
| Clear a set of pending events. | |
| int | BZ_EventPost (int pid, int event) |
| Post one or more event(s). | |
| int | BZ_EventRead (void) |
| Read all pending events. | |
| int | BZ_EventWait (int mask) |
| Wait for an event. | |
Event (signal) handling.
Events or signals are just fancy names for bits which can be set by a thread or interrupt routine. In addition, a thread can wait for a bit to become set. Each thread has 31 such bits (32, but one bit is always set). A few of these bits are used by the kernel, the rest is available for the user code. A thread or an interrupt routine can set one or more bits in the set of any thread (that is, it can post events to the thread) and a thread can wait for any bit of a sepcified subset of its event bits to become set. When a thread waiting for events wakes up, it gets a bitmap that indicates which events that it was waiting for became active and those bits in its set will also be cleared.
While it is a very simple mechanism, it is also pretty efficient. The event posting overhead is very small and waiting for multiple events simultaneously is also very simple, since the thread's 32 event bits are in fact a single integer word and bitwise operations can work on the bits in parallel.
For that reason the kernel uses the event mechanism as a basis for every other interprocess communication and synchronisation mechanism. The two basic operations, posting and waiting, can be described by these pseudo procedures, assuming atomic operations:
post( thread, event_bits )
thread.events |= event_bits
wait( event_mask )
while ( self.events & event_mask == 0 ) sleep()
self.events &= ~event_mask
Naturally, signals can get lost. If a bit is already set and you set it again, there's no indication that you acted on it twice. So these bits indicate that an event occured at least once since you checked them last time. You have to keep that in mind when you design your system.
| void BZ_EventClear | ( | int | mask | ) |
Clear a set of pending events.
This call removes the specified events from the caller's pending event list. It does not suspend the caller.
| mask | The events to clear |
| int BZ_EventPost | ( | int | pid, | |
| int | event | |||
| ) |
Post one or more event(s).
The function delivers one or more events to a process. The event(s) will be added to the pending events of the process and this function returns immediately. This function can be called from an interrupt routine.
If the events to post contain events that are reserved for kernel internal operations (i.e. they have a bit position BZ_EVENT_MAX or larger), these will be deleted from the event set.
| pid | The ID of the process to send the events to. If the pid is BZ_PID_BCAST then the event(s) will be delivered to every thread. | |
| event | The bit mask of the event(s) to post. |
| BZ_ILLEGAL_PID | The specified process does not exist. | |
| 0 | Success. |
| int BZ_EventRead | ( | void | ) |
Read all pending events.
This call returns the current pending event bitmap of the caller. It does not suspend the caller.
| int BZ_EventWait | ( | int | mask | ) |
Wait for an event.
Waits until at least one event in the event mask becomes set for the thread. The mask can not be empty; if it is, then BZ_EVENT_ALWAYS is returned without anything else being done. Otherwise, this call will cause a scheduling round even if the caller specifies the BZ_EVENT_ALWAYS event in the mask. Thus it can be used as a courtesy call to allow other threads to run even if the caller does not really want to wait for anything. The returned value is a bitmask of events that were both set in the mask and were pending at the time when the call returns. These events are deleted from the caller's pending event list.
| mask | The events to wait for |
| BZ_EVENT_ALWAYS | The mask was empty. | |
| 0 | The caller specified BZ_EVENT_ALWAYS and there were no pending events that matched the the mask. | |
| >0 | The bitmap of pending events that matched the mask. |
1.7.1