]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - doc/html/ref/kernel-condition-variables.html
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / doc / html / ref / kernel-condition-variables.html
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.               -->
9 <HTML
10 ><HEAD
11 ><TITLE
12 >Condition Variables</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
14 <META
15 NAME="GENERATOR"
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
17 "><LINK
18 REL="HOME"
19 TITLE="eCos Reference Manual"
20 HREF="ecos-ref.html"><LINK
21 REL="UP"
22 TITLE="The eCos Kernel"
23 HREF="kernel.html"><LINK
24 REL="PREVIOUS"
25 TITLE="Mutexes"
26 HREF="kernel-mutexes.html"><LINK
27 REL="NEXT"
28 TITLE="Semaphores"
29 HREF="kernel-semaphores.html"></HEAD
30 ><BODY
31 CLASS="REFENTRY"
32 BGCOLOR="#FFFFFF"
33 TEXT="#000000"
34 LINK="#0000FF"
35 VLINK="#840084"
36 ALINK="#0000FF"
37 ><DIV
38 CLASS="NAVHEADER"
39 ><TABLE
40 SUMMARY="Header navigation table"
41 WIDTH="100%"
42 BORDER="0"
43 CELLPADDING="0"
44 CELLSPACING="0"
45 ><TR
46 ><TH
47 COLSPAN="3"
48 ALIGN="center"
49 >eCos Reference Manual</TH
50 ></TR
51 ><TR
52 ><TD
53 WIDTH="10%"
54 ALIGN="left"
55 VALIGN="bottom"
56 ><A
57 HREF="kernel-mutexes.html"
58 ACCESSKEY="P"
59 >Prev</A
60 ></TD
61 ><TD
62 WIDTH="80%"
63 ALIGN="center"
64 VALIGN="bottom"
65 ></TD
66 ><TD
67 WIDTH="10%"
68 ALIGN="right"
69 VALIGN="bottom"
70 ><A
71 HREF="kernel-semaphores.html"
72 ACCESSKEY="N"
73 >Next</A
74 ></TD
75 ></TR
76 ></TABLE
77 ><HR
78 ALIGN="LEFT"
79 WIDTH="100%"></DIV
80 ><H1
81 ><A
82 NAME="KERNEL-CONDITION-VARIABLES">Condition Variables</H1
83 ><DIV
84 CLASS="REFNAMEDIV"
85 ><A
86 NAME="AEN1232"
87 ></A
88 ><H2
89 >Name</H2
90 >cyg_cond_init, cyg_cond_destroy, cyg_cond_wait, cyg_cond_timed_wait, cyg_cond_signal, cyg_cond_broadcast&nbsp;--&nbsp;Synchronization primitive</DIV
91 ><DIV
92 CLASS="REFSYNOPSISDIV"
93 ><A
94 NAME="AEN1240"><H2
95 >Synopsis</H2
96 ><DIV
97 CLASS="FUNCSYNOPSIS"
98 ><A
99 NAME="AEN1241"><P
100 ></P
101 ><TABLE
102 BORDER="5"
103 BGCOLOR="#E0E0F0"
104 WIDTH="70%"
105 ><TR
106 ><TD
107 ><PRE
108 CLASS="FUNCSYNOPSISINFO"
109 >#include &lt;cyg/kernel/kapi.h&gt;
110         </PRE
111 ></TD
112 ></TR
113 ></TABLE
114 ><P
115 ><CODE
116 ><CODE
117 CLASS="FUNCDEF"
118 >void cyg_cond_init</CODE
119 >(cyg_cond_t* cond, cyg_mutex_t* mutex);</CODE
120 ></P
121 ><P
122 ><CODE
123 ><CODE
124 CLASS="FUNCDEF"
125 >void cyg_cond_destroy</CODE
126 >(cyg_cond_t* cond);</CODE
127 ></P
128 ><P
129 ><CODE
130 ><CODE
131 CLASS="FUNCDEF"
132 >cyg_bool_t cyg_cond_wait</CODE
133 >(cyg_cond_t* cond);</CODE
134 ></P
135 ><P
136 ><CODE
137 ><CODE
138 CLASS="FUNCDEF"
139 >cyg_bool_t cyg_cond_timed_wait</CODE
140 >(cyg_cond_t* cond, cyg_tick_count_t abstime);</CODE
141 ></P
142 ><P
143 ><CODE
144 ><CODE
145 CLASS="FUNCDEF"
146 >void cyg_cond_signal</CODE
147 >(cyg_cond_t* cond);</CODE
148 ></P
149 ><P
150 ><CODE
151 ><CODE
152 CLASS="FUNCDEF"
153 >void cyg_cond_broadcast</CODE
154 >(cyg_cond_t* cond);</CODE
155 ></P
156 ><P
157 ></P
158 ></DIV
159 ></DIV
160 ><DIV
161 CLASS="REFSECT1"
162 ><A
163 NAME="KERNEL-CONDITION-VARIABLES-DESCRIPTION"
164 ></A
165 ><H2
166 >Description</H2
167 ><P
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
171 resources:
172       </P
173 ><TABLE
174 BORDER="5"
175 BGCOLOR="#E0E0F0"
176 WIDTH="70%"
177 ><TR
178 ><TD
179 ><PRE
180 CLASS="PROGRAMLISTING"
181 >&#13;cyg_mutex_t res_lock;
182 res_t res_pool[RES_MAX];
183 int res_count = RES_MAX;
184
185 void res_init(void)
186 {
187     cyg_mutex_init(&amp;res_lock);
188     &lt;fill pool with resources&gt;
189 }
190
191 res_t res_allocate(void)
192 {
193     res_t res;
194
195     cyg_mutex_lock(&amp;res_lock);               // lock the mutex
196
197     if( res_count == 0 )                     // check for free resource
198         res = RES_NONE;                      // return RES_NONE if none
199     else
200     {
201         res_count--;                         // allocate a resources
202         res = res_pool[res_count];
203     }
204
205     cyg_mutex_unlock(&amp;res_lock);             // unlock the mutex
206
207     return res;
208 }
209
210 void res_free(res_t res)
211 {
212     cyg_mutex_lock(&amp;res_lock);               // lock the mutex
213
214     res_pool[res_count] = res;               // free the resource
215     res_count++;
216
217     cyg_mutex_unlock(&amp;res_lock);             // unlock the mutex
218 }
219       </PRE
220 ></TD
221 ></TR
222 ></TABLE
223 ><P
224 >These routines use the variable <TT
225 CLASS="VARNAME"
226 >res_count</TT
227 > to keep
228 track of the resources available. If there are none then
229 <TT
230 CLASS="FUNCTION"
231 >res_allocate</TT
232 > returns <TT
233 CLASS="LITERAL"
234 >RES_NONE</TT
235 >,
236 which the caller must check for and take appropriate error handling
237 actions.
238       </P
239 ><P
240 >Now suppose that we do not want to return
241 <TT
242 CLASS="LITERAL"
243 >RES_NONE</TT
244 > when there are no resources, but want to
245 wait for one to become available. This is where a condition variable
246 can be used:
247       </P
248 ><TABLE
249 BORDER="5"
250 BGCOLOR="#E0E0F0"
251 WIDTH="70%"
252 ><TR
253 ><TD
254 ><PRE
255 CLASS="PROGRAMLISTING"
256 >&#13;cyg_mutex_t res_lock;
257 cyg_cond_t res_wait;
258 res_t res_pool[RES_MAX];
259 int res_count = RES_MAX;
260
261 void res_init(void)
262 {
263     cyg_mutex_init(&amp;res_lock);
264     cyg_cond_init(&amp;res_wait, &amp;res_lock);
265     &lt;fill pool with resources&gt;
266 }
267
268 res_t res_allocate(void)
269 {
270     res_t res;
271
272     cyg_mutex_lock(&amp;res_lock);               // lock the mutex
273
274     while( res_count == 0 )                  // wait for a resources
275         cyg_cond_wait(&amp;res_wait);
276
277     res_count--;                             // allocate a resource
278     res = res_pool[res_count];
279
280     cyg_mutex_unlock(&amp;res_lock);             // unlock the mutex
281
282     return res;
283 }
284
285 void res_free(res_t res)
286 {
287     cyg_mutex_lock(&amp;res_lock);               // lock the mutex
288
289     res_pool[res_count] = res;               // free the resource
290     res_count++;
291
292     cyg_cond_signal(&amp;res_wait);              // wake up any waiting allocators
293
294     cyg_mutex_unlock(&amp;res_lock);             // unlock the mutex
295 }
296       </PRE
297 ></TD
298 ></TR
299 ></TABLE
300 ><P
301 >In this version of the code, when <TT
302 CLASS="FUNCTION"
303 >res_allocate</TT
304 >
305 detects that there are no resources it calls
306 <TT
307 CLASS="FUNCTION"
308 >cyg_cond_wait</TT
309 >. This does two things: it unlocks
310 the mutex, and puts the calling thread to sleep on the condition
311 variable. When <TT
312 CLASS="FUNCTION"
313 >res_free</TT
314 > is eventually called, it
315 puts a resource back into the pool and calls
316 <TT
317 CLASS="FUNCTION"
318 >cyg_cond_signal</TT
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
322 <TT
323 CLASS="FUNCTION"
324 >cyg_cond_wait</TT
325 >.
326       </P
327 ><P
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
330 <TT
331 CLASS="FUNCTION"
332 >cyg_cond_wait</TT
333 > are atomic: no other thread can run
334 between the unlock and the wait. If this were not the case then a call
335 to <TT
336 CLASS="FUNCTION"
337 >res_free</TT
338 > by that thread would release the
339 resource but the call to <TT
340 CLASS="FUNCTION"
341 >cyg_cond_signal</TT
342 > would be
343 lost, and the first thread would end up waiting when there were
344 resources available.
345       </P
346 ><P
347 >The second feature is that the call to
348 <TT
349 CLASS="FUNCTION"
350 >cyg_cond_wait</TT
351 > is in a <TT
352 CLASS="LITERAL"
353 >while</TT
354 >
355 loop and not a simple <TT
356 CLASS="LITERAL"
357 >if</TT
358 > statement. This is because
359 of the need to re-lock the mutex in <TT
360 CLASS="FUNCTION"
361 >cyg_cond_wait</TT
362 >
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
370 waiting.
371       </P
372 ><P
373 >Before a condition variable can be used it must be initialized with a
374 call to <TT
375 CLASS="FUNCTION"
376 >cyg_cond_init</TT
377 >. This requires two
378 arguments, memory for the data structure and a pointer to an existing
379 mutex. This mutex will not be initialized by
380 <TT
381 CLASS="FUNCTION"
382 >cyg_cond_init</TT
383 >, instead a separate call to
384 <TT
385 CLASS="FUNCTION"
386 >cyg_mutex_init</TT
387 > is required. If a condition
388 variable is no longer required and there are no threads waiting on it
389 then <TT
390 CLASS="FUNCTION"
391 >cyg_cond_destroy</TT
392 > can be used.
393       </P
394 ><P
395 >When a thread needs to wait for a condition to be satisfied it can
396 call <TT
397 CLASS="FUNCTION"
398 >cyg_cond_wait</TT
399 >. The thread must have already
400 locked the mutex that was specified in the
401 <TT
402 CLASS="FUNCTION"
403 >cyg_cond_init</TT
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
410 this function, <TT
411 CLASS="FUNCTION"
412 >cyg_cond_timed_wait</TT
413 >, which can be
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
416 <TT
417 CLASS="FUNCTION"
418 >cyg_cond_timed_wait</TT
419 > returns, regardless of
420 whether it was a result of a signal operation or a timeout.
421       </P
422 ><P
423 >There is no <TT
424 CLASS="FUNCTION"
425 >cyg_cond_trywait</TT
426 > function because
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
430 condition variable.
431       </P
432 ><P
433 >When a thread changes shared state that may affect some other thread
434 blocked on a condition variable, it should call either
435 <TT
436 CLASS="FUNCTION"
437 >cyg_cond_signal</TT
438 > or
439 <TT
440 CLASS="FUNCTION"
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
453 threads to proceed.
454       </P
455 ></DIV
456 ><DIV
457 CLASS="REFSECT1"
458 ><A
459 NAME="KERNEL-CONDITION-VARIABLES-CONTEXT"
460 ></A
461 ><H2
462 >Valid contexts</H2
463 ><P
464 ><TT
465 CLASS="FUNCTION"
466 >cyg_cond_init</TT
467 > is typically called during system
468 initialization but may also be called in thread context. The same
469 applies to <TT
470 CLASS="FUNCTION"
471 >cyg_cond_delete</TT
472 >.
473 <TT
474 CLASS="FUNCTION"
475 >cyg_cond_wait</TT
476 > and
477 <TT
478 CLASS="FUNCTION"
479 >cyg_cond_timedwait</TT
480 > may only be called from thread
481 context since they may block. <TT
482 CLASS="FUNCTION"
483 >cyg_cond_signal</TT
484 > and
485 <TT
486 CLASS="FUNCTION"
487 >cyg_cond_broadcast</TT
488 > may be called from thread or
489 DSR context.
490       </P
491 ></DIV
492 ><DIV
493 CLASS="NAVFOOTER"
494 ><HR
495 ALIGN="LEFT"
496 WIDTH="100%"><TABLE
497 SUMMARY="Footer navigation table"
498 WIDTH="100%"
499 BORDER="0"
500 CELLPADDING="0"
501 CELLSPACING="0"
502 ><TR
503 ><TD
504 WIDTH="33%"
505 ALIGN="left"
506 VALIGN="top"
507 ><A
508 HREF="kernel-mutexes.html"
509 ACCESSKEY="P"
510 >Prev</A
511 ></TD
512 ><TD
513 WIDTH="34%"
514 ALIGN="center"
515 VALIGN="top"
516 ><A
517 HREF="ecos-ref.html"
518 ACCESSKEY="H"
519 >Home</A
520 ></TD
521 ><TD
522 WIDTH="33%"
523 ALIGN="right"
524 VALIGN="top"
525 ><A
526 HREF="kernel-semaphores.html"
527 ACCESSKEY="N"
528 >Next</A
529 ></TD
530 ></TR
531 ><TR
532 ><TD
533 WIDTH="33%"
534 ALIGN="left"
535 VALIGN="top"
536 >Mutexes</TD
537 ><TD
538 WIDTH="34%"
539 ALIGN="center"
540 VALIGN="top"
541 ><A
542 HREF="kernel.html"
543 ACCESSKEY="U"
544 >Up</A
545 ></TD
546 ><TD
547 WIDTH="33%"
548 ALIGN="right"
549 VALIGN="top"
550 >Semaphores</TD
551 ></TR
552 ></TABLE
553 ></DIV
554 ></BODY
555 ></HTML
556 >