1 <!-- Copyright (C) 2003 Red Hat, Inc. -->
2 <!-- This material may be distributed only subject to the terms -->
3 <!-- and conditions set forth in the Open Publication License, v1.0 -->
4 <!-- or later (the latest version is presently available at -->
5 <!-- http://www.opencontent.org/openpub/). -->
6 <!-- Distribution of the work or derivative of the work in any -->
7 <!-- standard (paper) book form is prohibited unless prior -->
8 <!-- permission is obtained from the copyright holder. -->
12 >Condition Variables</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
19 TITLE="eCos Reference Manual"
20 HREF="ecos-ref.html"><LINK
22 TITLE="The eCos Kernel"
23 HREF="kernel.html"><LINK
26 HREF="kernel-mutexes.html"><LINK
29 HREF="kernel-semaphores.html"></HEAD
40 SUMMARY="Header navigation table"
49 >eCos Reference Manual</TH
57 HREF="kernel-mutexes.html"
71 HREF="kernel-semaphores.html"
82 NAME="KERNEL-CONDITION-VARIABLES">Condition Variables</H1
90 >cyg_cond_init, cyg_cond_destroy, cyg_cond_wait, cyg_cond_timed_wait, cyg_cond_signal, cyg_cond_broadcast -- Synchronization primitive</DIV
92 CLASS="REFSYNOPSISDIV"
108 CLASS="FUNCSYNOPSISINFO"
109 >#include <cyg/kernel/kapi.h>
118 >void cyg_cond_init</CODE
119 >(cyg_cond_t* cond, cyg_mutex_t* mutex);</CODE
125 >void cyg_cond_destroy</CODE
126 >(cyg_cond_t* cond);</CODE
132 >cyg_bool_t cyg_cond_wait</CODE
133 >(cyg_cond_t* cond);</CODE
139 >cyg_bool_t cyg_cond_timed_wait</CODE
140 >(cyg_cond_t* cond, cyg_tick_count_t abstime);</CODE
146 >void cyg_cond_signal</CODE
147 >(cyg_cond_t* cond);</CODE
153 >void cyg_cond_broadcast</CODE
154 >(cyg_cond_t* cond);</CODE
163 NAME="KERNEL-CONDITION-VARIABLES-DESCRIPTION"
168 >Condition variables are used in conjunction with mutexes to implement
169 long-term waits for some condition to become true. For example
170 consider a set of functions that control access to a pool of
180 CLASS="PROGRAMLISTING"
181 > cyg_mutex_t res_lock;
182 res_t res_pool[RES_MAX];
183 int res_count = RES_MAX;
187 cyg_mutex_init(&res_lock);
188 <fill pool with resources>
191 res_t res_allocate(void)
195 cyg_mutex_lock(&res_lock); // lock the mutex
197 if( res_count == 0 ) // check for free resource
198 res = RES_NONE; // return RES_NONE if none
201 res_count--; // allocate a resources
202 res = res_pool[res_count];
205 cyg_mutex_unlock(&res_lock); // unlock the mutex
210 void res_free(res_t res)
212 cyg_mutex_lock(&res_lock); // lock the mutex
214 res_pool[res_count] = res; // free the resource
217 cyg_mutex_unlock(&res_lock); // unlock the mutex
224 >These routines use the variable <TT
228 track of the resources available. If there are none then
236 which the caller must check for and take appropriate error handling
240 >Now suppose that we do not want to return
244 > when there are no resources, but want to
245 wait for one to become available. This is where a condition variable
255 CLASS="PROGRAMLISTING"
256 > cyg_mutex_t res_lock;
258 res_t res_pool[RES_MAX];
259 int res_count = RES_MAX;
263 cyg_mutex_init(&res_lock);
264 cyg_cond_init(&res_wait, &res_lock);
265 <fill pool with resources>
268 res_t res_allocate(void)
272 cyg_mutex_lock(&res_lock); // lock the mutex
274 while( res_count == 0 ) // wait for a resources
275 cyg_cond_wait(&res_wait);
277 res_count--; // allocate a resource
278 res = res_pool[res_count];
280 cyg_mutex_unlock(&res_lock); // unlock the mutex
285 void res_free(res_t res)
287 cyg_mutex_lock(&res_lock); // lock the mutex
289 res_pool[res_count] = res; // free the resource
292 cyg_cond_signal(&res_wait); // wake up any waiting allocators
294 cyg_mutex_unlock(&res_lock); // unlock the mutex
301 >In this version of the code, when <TT
305 detects that there are no resources it calls
309 >. This does two things: it unlocks
310 the mutex, and puts the calling thread to sleep on the condition
314 > is eventually called, it
315 puts a resource back into the pool and calls
319 > to wake up any thread waiting on
320 the condition variable. When the waiting thread eventually gets to run again,
321 it will re-lock the mutex before returning from
328 >There are two important things to note about the way in which this
329 code works. The first is that the mutex unlock and wait in
333 > are atomic: no other thread can run
334 between the unlock and the wait. If this were not the case then a call
338 > by that thread would release the
339 resource but the call to <TT
343 lost, and the first thread would end up waiting when there were
347 >The second feature is that the call to
355 loop and not a simple <TT
358 > statement. This is because
359 of the need to re-lock the mutex in <TT
363 when the signalled thread reawakens. If there are other threads
364 already queued to claim the lock then this thread must wait. Depending
365 on the scheduler and the queue order, many other threads may have
366 entered the critical section before this one gets to run. So the
367 condition that it was waiting for may have been rendered false. Using
368 a loop around all condition variable wait operations is the only way
369 to guarantee that the condition being waited for is still true after
373 >Before a condition variable can be used it must be initialized with a
378 arguments, memory for the data structure and a pointer to an existing
379 mutex. This mutex will not be initialized by
383 >, instead a separate call to
387 > is required. If a condition
388 variable is no longer required and there are no threads waiting on it
391 >cyg_cond_destroy</TT
395 >When a thread needs to wait for a condition to be satisfied it can
399 >. The thread must have already
400 locked the mutex that was specified in the
404 > call. This mutex will be unlocked
405 and the current thread will be suspended in an atomic operation. When
406 some other thread performs a signal or broadcast operation the current
407 thread will be woken up and automatically reclaim ownership of the mutex
408 again, allowing it to examine global state and determine whether or
409 not the condition is now satisfied. The kernel supplies a variant of
412 >cyg_cond_timed_wait</TT
414 used to wait on the condition variable or until some number of clock
415 ticks have occurred. The mutex will always be reclaimed before
418 >cyg_cond_timed_wait</TT
419 > returns, regardless of
420 whether it was a result of a signal operation or a timeout.
425 >cyg_cond_trywait</TT
427 this would not serve any purpose. If a thread has locked the mutex and
428 determined that the condition is satisfied, it can just release the
429 mutex and return. There is no need to perform any operation on the
433 >When a thread changes shared state that may affect some other thread
434 blocked on a condition variable, it should call either
441 >cyg_cond_broadcast</TT
442 >. These calls do not require
443 ownership of the mutex, but usually the mutex will have been claimed
444 before updating the shared state. A signal operation only wakes up the
445 first thread that is waiting on the condition variable, while a
446 broadcast wakes up all the threads. If there are no threads waiting on
447 the condition variable at the time, then the signal or broadcast will
448 have no effect: past signals are not counted up or remembered in any
449 way. Typically a signal should be used when all threads will check the
450 same condition and at most one thread can continue running. A
451 broadcast should be used if threads check slightly different
452 conditions, or if the change to the global state might allow multiple
459 NAME="KERNEL-CONDITION-VARIABLES-CONTEXT"
467 > is typically called during system
468 initialization but may also be called in thread context. The same
479 >cyg_cond_timedwait</TT
480 > may only be called from thread
481 context since they may block. <TT
487 >cyg_cond_broadcast</TT
488 > may be called from thread or
497 SUMMARY="Footer navigation table"
508 HREF="kernel-mutexes.html"
526 HREF="kernel-semaphores.html"