]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - doc/html/ref/kernel-semaphores.html
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / doc / html / ref / kernel-semaphores.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 >Semaphores</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="Condition Variables"
26 HREF="kernel-condition-variables.html"><LINK
27 REL="NEXT"
28 TITLE="Mail boxes"
29 HREF="kernel-mail-boxes.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-condition-variables.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-mail-boxes.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-SEMAPHORES">Semaphores</H1
83 ><DIV
84 CLASS="REFNAMEDIV"
85 ><A
86 NAME="AEN1330"
87 ></A
88 ><H2
89 >Name</H2
90 >cyg_semaphore_init, cyg_semaphore_destroy, cyg_semaphore_wait, cyg_semaphore_timed_wait, cyg_semaphore_post, cyg_semaphore_peek&nbsp;--&nbsp;Synchronization primitive</DIV
91 ><DIV
92 CLASS="REFSYNOPSISDIV"
93 ><A
94 NAME="AEN1338"><H2
95 >Synopsis</H2
96 ><DIV
97 CLASS="FUNCSYNOPSIS"
98 ><A
99 NAME="AEN1339"><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_semaphore_init</CODE
119 >(cyg_sem_t* sem, cyg_count32 val);</CODE
120 ></P
121 ><P
122 ><CODE
123 ><CODE
124 CLASS="FUNCDEF"
125 >void cyg_semaphore_destroy</CODE
126 >(cyg_sem_t* sem);</CODE
127 ></P
128 ><P
129 ><CODE
130 ><CODE
131 CLASS="FUNCDEF"
132 >cyg_bool_t cyg_semaphore_wait</CODE
133 >(cyg_sem_t* sem);</CODE
134 ></P
135 ><P
136 ><CODE
137 ><CODE
138 CLASS="FUNCDEF"
139 >cyg_bool_t cyg_semaphore_timed_wait</CODE
140 >(cyg_sem_t* sem, cyg_tick_count_t abstime);</CODE
141 ></P
142 ><P
143 ><CODE
144 ><CODE
145 CLASS="FUNCDEF"
146 >cyg_bool_t cyg_semaphore_trywait</CODE
147 >(cyg_sem_t* sem);</CODE
148 ></P
149 ><P
150 ><CODE
151 ><CODE
152 CLASS="FUNCDEF"
153 >void cyg_semaphore_post</CODE
154 >(cyg_sem_t* sem);</CODE
155 ></P
156 ><P
157 ><CODE
158 ><CODE
159 CLASS="FUNCDEF"
160 >void cyg_semaphore_peek</CODE
161 >(cyg_sem_t* sem, cyg_count32* val);</CODE
162 ></P
163 ><P
164 ></P
165 ></DIV
166 ></DIV
167 ><DIV
168 CLASS="REFSECT1"
169 ><A
170 NAME="KERNEL-SEMAPHORES-DESCRIPTION"
171 ></A
172 ><H2
173 >Description</H2
174 ><P
175 >Counting semaphores are a <A
176 HREF="kernel-overview.html#KERNEL-OVERVIEW-SYNCH-PRIMITIVES"
177 >synchronization
178 primitive</A
179 > that allow threads to wait until an event has
180 occurred. The event may be generated by a producer thread, or by a DSR
181 in response to a hardware interrupt. Associated with each semaphore is
182 an integer counter that keeps track of the number of events that have
183 not yet been processed. If this counter is zero, an attempt by a
184 consumer thread to wait on the semaphore will block until some other
185 thread or a DSR posts a new event to the semaphore. If the counter is
186 greater than zero then an attempt to wait on the semaphore will
187 consume one event, in other words decrement the counter, and return
188 immediately. Posting to a semaphore will wake up the first thread that
189 is currently waiting, which will then resume inside the semaphore wait
190 operation and decrement the counter again.
191       </P
192 ><P
193 >Another use of semaphores is for certain forms of resource management.
194 The counter would correspond to how many of a certain type of resource
195 are currently available, with threads waiting on the semaphore to
196 claim a resource and posting to release the resource again. In
197 practice <A
198 HREF="kernel-condition-variables.html"
199 >condition
200 variables</A
201 > are usually much better suited for operations like
202 this.
203       </P
204 ><P
205 ><TT
206 CLASS="FUNCTION"
207 >cyg_semaphore_init</TT
208 > is used to initialize a
209 semaphore. It takes two arguments, a pointer to a
210 <SPAN
211 CLASS="STRUCTNAME"
212 >cyg_sem_t</SPAN
213 > structure and an initial value for
214 the counter. Note that semaphore operations, unlike some other parts
215 of the kernel API, use pointers to data structures rather than
216 handles. This makes it easier to embed semaphores in a larger data
217 structure. The initial counter value can be any number, zero, positive
218 or negative, but typically a value of zero is used to indicate that no
219 events have occurred yet.
220       </P
221 ><P
222 ><TT
223 CLASS="FUNCTION"
224 >cyg_semaphore_wait</TT
225 > is used by a consumer thread
226 to wait for an event. If the current counter is greater than 0, in
227 other words if the event has already occurred in the past, then the
228 counter will be decremented and the call will return immediately.
229 Otherwise the current thread will be blocked until there is a
230 <TT
231 CLASS="FUNCTION"
232 >cyg_semaphore_post</TT
233 > call.
234       </P
235 ><P
236 ><TT
237 CLASS="FUNCTION"
238 >cyg_semaphore_post</TT
239 > is called when an event has
240 occurs. This increments the counter and wakes up the first thread
241 waiting on the semaphore (if any). Usually that thread will then
242 continue running inside <TT
243 CLASS="FUNCTION"
244 >cyg_semaphore_wait</TT
245 > and
246 decrement the counter again. However other scenarioes are possible.
247 For example the thread calling <TT
248 CLASS="FUNCTION"
249 >cyg_semaphore_post</TT
250 >
251 may be running at high priority, some other thread running at medium
252 priority may be about to call <TT
253 CLASS="FUNCTION"
254 >cyg_semaphore_wait</TT
255 >
256 when it next gets a chance to run, and a low priority thread may be
257 waiting on the semaphore. What will happen is that the current high
258 priority thread continues running until it is descheduled for some
259 reason, then the medium priority thread runs and its call to
260 <TT
261 CLASS="FUNCTION"
262 >cyg_semaphore_wait</TT
263 > succeeds immediately, and
264 later on the low priority thread runs again, discovers a counter value
265 of 0, and blocks until another event is posted. If there are multiple
266 threads blocked on a semaphore then the configuration option
267 <TT
268 CLASS="VARNAME"
269 >CYGIMP_KERNEL_SCHED_SORTED_QUEUES</TT
270 > determines which
271 one will be woken up by a post operation.
272       </P
273 ><P
274 ><TT
275 CLASS="FUNCTION"
276 >cyg_semaphore_wait</TT
277 > returns a boolean. Normally it
278 will block until it has successfully decremented the counter, retrying
279 as necessary, and return success. However the wait operation may be
280 aborted by a call to <A
281 HREF="kernel-thread-control.html"
282 ><TT
283 CLASS="FUNCTION"
284 >cyg_thread_release</TT
285 ></A
286 >,
287 and <TT
288 CLASS="FUNCTION"
289 >cyg_semaphore_wait</TT
290 > will then return false.
291       </P
292 ><P
293 ><TT
294 CLASS="FUNCTION"
295 >cyg_semaphore_timed_wait</TT
296 > is a variant of
297 <TT
298 CLASS="FUNCTION"
299 >cyg_semaphore_wait</TT
300 >. It can be used to wait until
301 either an event has occurred or a number of clock ticks have happened.
302 The function returns success if the semaphore wait operation
303 succeeded, or false if the operation timed out or was aborted by
304 <TT
305 CLASS="FUNCTION"
306 >cyg_thread_release</TT
307 >. If support for the real-time
308 clock has been removed from the current configuration then this
309 function will not be available.
310 <TT
311 CLASS="FUNCTION"
312 >cyg_semaphore_trywait</TT
313 > is another variant which
314 will always return immediately rather than block, again returning
315 success or failure.
316       </P
317 ><P
318 ><TT
319 CLASS="FUNCTION"
320 >cyg_semaphore_peek</TT
321 > can be used to get hold of the
322 current counter value. This function is rarely useful except for
323 debugging purposes since the counter value may change at any time if
324 some other thread or a DSR performs a semaphore operation.
325       </P
326 ></DIV
327 ><DIV
328 CLASS="REFSECT1"
329 ><A
330 NAME="KERNEL-SEMAPHORES-CONTEXT"
331 ></A
332 ><H2
333 >Valid contexts</H2
334 ><P
335 ><TT
336 CLASS="FUNCTION"
337 >cyg_semaphore_init</TT
338 > is normally called during
339 initialization but may also be called from thread context.
340 <TT
341 CLASS="FUNCTION"
342 >cyg_semaphore_wait</TT
343 > and
344 <TT
345 CLASS="FUNCTION"
346 >cyg_semaphore_timed_wait</TT
347 > may only be called from
348 thread context because these operations may block.
349 <TT
350 CLASS="FUNCTION"
351 >cyg_semaphore_trywait</TT
352 >,
353 <TT
354 CLASS="FUNCTION"
355 >cyg_semaphore_post</TT
356 > and
357 <TT
358 CLASS="FUNCTION"
359 >cyg_semaphore_peek</TT
360 > may be called from thread or
361 DSR context.
362       </P
363 ></DIV
364 ><DIV
365 CLASS="NAVFOOTER"
366 ><HR
367 ALIGN="LEFT"
368 WIDTH="100%"><TABLE
369 SUMMARY="Footer navigation table"
370 WIDTH="100%"
371 BORDER="0"
372 CELLPADDING="0"
373 CELLSPACING="0"
374 ><TR
375 ><TD
376 WIDTH="33%"
377 ALIGN="left"
378 VALIGN="top"
379 ><A
380 HREF="kernel-condition-variables.html"
381 ACCESSKEY="P"
382 >Prev</A
383 ></TD
384 ><TD
385 WIDTH="34%"
386 ALIGN="center"
387 VALIGN="top"
388 ><A
389 HREF="ecos-ref.html"
390 ACCESSKEY="H"
391 >Home</A
392 ></TD
393 ><TD
394 WIDTH="33%"
395 ALIGN="right"
396 VALIGN="top"
397 ><A
398 HREF="kernel-mail-boxes.html"
399 ACCESSKEY="N"
400 >Next</A
401 ></TD
402 ></TR
403 ><TR
404 ><TD
405 WIDTH="33%"
406 ALIGN="left"
407 VALIGN="top"
408 >Condition Variables</TD
409 ><TD
410 WIDTH="34%"
411 ALIGN="center"
412 VALIGN="top"
413 ><A
414 HREF="kernel.html"
415 ACCESSKEY="U"
416 >Up</A
417 ></TD
418 ><TD
419 WIDTH="33%"
420 ALIGN="right"
421 VALIGN="top"
422 >Mail boxes</TD
423 ></TR
424 ></TABLE
425 ></DIV
426 ></BODY
427 ></HTML
428 >