JAVA-BASED REAL-TIME PROGRAMMING
JAVA-BASED REAL-TIME PROGRAMMING
JAVA-BASED REAL-TIME PROGRAMMING
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
give<br />
give<br />
give<br />
3.2. Resources and mutual exclusion – Semaphores<br />
T1 signal<br />
T2<br />
take<br />
take<br />
take<br />
take<br />
Figure 3.2: A thread T1 signaling to thread T2 via a counting semaphore. The<br />
counter is assumed to be initialized to zero, resulting in the first call of take<br />
blocking its caller. For each give, one take can be called without blocking.<br />
of give but T2 never runs in advance of T1. This type of semaphore is referred<br />
to as a counting semaphore.<br />
Sometimes we do not want the signaled thread, T2 in this case, to catch<br />
up when give has been called multiple times. That can be accomplished by<br />
using a boolean instead of a counter as the state variable of the semaphore.<br />
That corresponds to the counter being one binary digit, and such a semaphore<br />
is therefore usually called a binary semaphore.<br />
A less usual type of semaphore is the multistep semaphore, which is useful<br />
when we want successive calls of take to be atomic. For instance, a producing<br />
thread signals whenever a byte of data is put in a buffer, but the consuming<br />
thread is reading a unicode (two bytes per character) string. We then want<br />
to call take(2) to only get unblocked when there are two bytes available. One<br />
can always solve the problem without such a multistep feature, but using a<br />
multistep semaphore can be more convenient and efficient.<br />
Mutual exclusion<br />
Perhaps the most well-known usage of semaphores is for mutual exclusion.<br />
Any of the semaphore types used for signaling can be used for mutual exclusion,<br />
but there are reasons for providing a special mutual exclusion semaphore.<br />
Such a semaphore is sometimes referred to as a ’mutex’. We will call it a mutex<br />
semaphore. As depicted in Figure 3.3, the very same thread that has called<br />
mutex.take(), thereafter having exclusive access to the shared data, should call<br />
mutex.give() when the critical section is left. Any one activity not following<br />
this protocol, for instance by calling give one extra time before take, would<br />
damage the whole application. Therefore, it is a good idea to have a dedicated<br />
59