Imported upstream version 1.20
[fw/openalt] / FreeRTOS / include / semphr.h
1 /*
2         FreeRTOS.org V4.4.0 - Copyright (C) 2003-2007 Richard Barry.
3
4         This file is part of the FreeRTOS.org distribution.
5
6         FreeRTOS.org is free software; you can redistribute it and/or modify
7         it under the terms of the GNU General Public License as published by
8         the Free Software Foundation; either version 2 of the License, or
9         (at your option) any later version.
10
11         FreeRTOS.org is distributed in the hope that it will be useful,
12         but WITHOUT ANY WARRANTY; without even the implied warranty of
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14         GNU General Public License for more details.
15
16         You should have received a copy of the GNU General Public License
17         along with FreeRTOS.org; if not, write to the Free Software
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20         A special exception to the GPL can be applied should you wish to distribute
21         a combined work that includes FreeRTOS.org, without being obliged to provide
22         the source code for any proprietary components.  See the licensing section 
23         of http://www.FreeRTOS.org for full details of how and when the exception
24         can be applied.
25
26         ***************************************************************************
27         See http://www.FreeRTOS.org for documentation, latest information, license 
28         and contact details.  Please ensure to read the configuration and relevant 
29         port sections of the online documentation.
30
31         Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
32         with commercial development and support options.
33         ***************************************************************************
34 */
35
36 #include "queue.h"
37
38 #ifndef SEMAPHORE_H
39 #define SEMAPHORE_H
40
41 typedef xQueueHandle xSemaphoreHandle;
42
43 #define semBINARY_SEMAPHORE_QUEUE_LENGTH        ( ( unsigned portCHAR ) 1 )
44 #define semSEMAPHORE_QUEUE_ITEM_LENGTH          ( ( unsigned portCHAR ) 0 )
45 #define semGIVE_BLOCK_TIME                                      ( ( portTickType ) 0 )
46
47
48 /**
49  * semphr. h
50  * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
51  *
52  * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
53  * The queue length is 1 as this is a binary semaphore.  The data size is 0
54  * as we don't want to actually store any data - we just want to know if the
55  * queue is empty or full.
56  *
57  * @param xSemaphore Handle to the created semaphore.  Should be of type xSemaphoreHandle.
58  *
59  * Example usage:
60  <pre>
61  xSemaphoreHandle xSemaphore;
62
63  void vATask( void * pvParameters )
64  {
65     // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
66     // This is a macro so pass the variable in directly.
67     vSemaphoreCreateBinary( xSemaphore );
68
69     if( xSemaphore != NULL )
70     {
71         // The semaphore was created successfully.
72         // The semaphore can now be used.  
73     }
74  }
75  </pre>
76  * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
77  * \ingroup Semaphores
78  */
79 #define vSemaphoreCreateBinary( xSemaphore )            {                                                                                                                                                                                       \
80                                                                                                                 xSemaphore = xQueueCreate( ( unsigned portCHAR ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH );   \
81                                                                                                                 if( xSemaphore != NULL )                                                                                                                                \
82                                                                                                                 {                                                                                                                                                                               \
83                                                                                                                         xSemaphoreGive( xSemaphore );                                                                                                           \
84                                                                                                                 }                                                                                                                                                                               \
85                                                                                                         }
86
87 /**
88  * semphr. h
89  * xSemaphoreTake( 
90  *                   xSemaphoreHandle xSemaphore, 
91  *                   portTickType xBlockTime 
92  *               )</pre>
93  *
94  * <i>Macro</i> to obtain a semaphore.  The semaphore must of been created using 
95  * vSemaphoreCreateBinary ().
96  *
97  * @param xSemaphore A handle to the semaphore being obtained.  This is the
98  * handle returned by vSemaphoreCreateBinary ();
99  *
100  * @param xBlockTime The time in ticks to wait for the semaphore to become
101  * available.  The macro portTICK_RATE_MS can be used to convert this to a
102  * real time.  A block time of zero can be used to poll the semaphore.
103  *
104  * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime
105  * expired without the semaphore becoming available.
106  *
107  * Example usage:
108  <pre>
109  xSemaphoreHandle xSemaphore = NULL;
110
111  // A task that creates a semaphore.
112  void vATask( void * pvParameters )
113  {
114     // Create the semaphore to guard a shared resource.
115     vSemaphoreCreateBinary( xSemaphore );
116  }
117
118  // A task that uses the semaphore.
119  void vAnotherTask( void * pvParameters )
120  {
121     // ... Do other things.
122
123     if( xSemaphore != NULL )
124     {
125         // See if we can obtain the semaphore.  If the semaphore is not available
126         // wait 10 ticks to see if it becomes free.     
127         if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
128         {
129             // We were able to obtain the semaphore and can now access the
130             // shared resource.
131
132             // ...
133
134             // We have finished accessing the shared resource.  Release the 
135             // semaphore.
136             xSemaphoreGive( xSemaphore );
137         }
138         else
139         {
140             // We could not obtain the semaphore and can therefore not access
141             // the shared resource safely.
142         }
143     }
144  }
145  </pre>
146  * \defgroup xSemaphoreTake xSemaphoreTake
147  * \ingroup Semaphores
148  */
149 #define xSemaphoreTake( xSemaphore, xBlockTime )        xQueueReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime )
150
151 /**
152  * semphr. h
153  * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
154  *
155  * <i>Macro</i> to release a semaphore.  The semaphore must of been created using 
156  * vSemaphoreCreateBinary (), and obtained using sSemaphoreTake ().
157  *
158  * This must not be used from an ISR.  See xSemaphoreGiveFromISR () for
159  * an alternative which can be used from an ISR.
160  *
161  * @param xSemaphore A handle to the semaphore being released.  This is the
162  * handle returned by vSemaphoreCreateBinary ();
163  *
164  * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.
165  * Semaphores are implemented using queues.  An error can occur if there is
166  * no space on the queue to post a message - indicating that the 
167  * semaphore was not first obtained correctly.
168  *
169  * Example usage:
170  <pre>
171  xSemaphoreHandle xSemaphore = NULL;
172
173  void vATask( void * pvParameters )
174  {
175     // Create the semaphore to guard a shared resource.
176     vSemaphoreCreateBinary( xSemaphore );
177
178     if( xSemaphore != NULL )
179     {
180         if( xSemaphoreGive( xSemaphore ) != pdTRUE )
181         {
182             // We would expect this call to fail because we cannot give
183             // a semaphore without first "taking" it!
184         }
185
186         // Obtain the semaphore - don't block if the semaphore is not
187         // immediately available.
188         if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
189         {
190             // We now have the semaphore and can access the shared resource.
191
192             // ...
193
194             // We have finished accessing the shared resource so can free the
195             // semaphore.
196             if( xSemaphoreGive( xSemaphore ) != pdTRUE )
197             {
198                 // We would not expect this call to fail because we must have
199                 // obtained the semaphore to get here.
200             }
201         }
202     }
203  }
204  </pre>
205  * \defgroup xSemaphoreGive xSemaphoreGive
206  * \ingroup Semaphores
207  */
208 #define xSemaphoreGive( xSemaphore )                            xQueueSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME )
209
210 /**
211  * semphr. h
212  * <pre>
213  xSemaphoreGiveFromISR( 
214                           xSemaphoreHandle xSemaphore, 
215                           portSHORT sTaskPreviouslyWoken 
216                       )</pre>
217  *
218  * <i>Macro</i> to  release a semaphore.  The semaphore must of been created using 
219  * vSemaphoreCreateBinary (), and obtained using xSemaphoreTake ().
220  *
221  * This macro can be used from an ISR.
222  *
223  * @param xSemaphore A handle to the semaphore being released.  This is the
224  * handle returned by vSemaphoreCreateBinary ();
225  *
226  * @param sTaskPreviouslyWoken This is included so an ISR can make multiple calls
227  * to xSemaphoreGiveFromISR () from a single interrupt.  The first call
228  * should always pass in pdFALSE.  Subsequent calls should pass in
229  * the value returned from the previous call.  See the file serial .c in the
230  * PC port for a good example of using xSemaphoreGiveFromISR ().
231  *
232  * @return pdTRUE if a task was woken by releasing the semaphore.  This is 
233  * used by the ISR to determine if a context switch may be required following
234  * the ISR.
235  *
236  * Example usage:
237  <pre>
238  #define LONG_TIME 0xffff
239  #define TICKS_TO_WAIT  10
240  xSemaphoreHandle xSemaphore = NULL;
241
242  // Repetitive task.
243  void vATask( void * pvParameters )
244  {
245     for( ;; )
246     {
247         // We want this task to run every 10 ticks or a timer.  The semaphore 
248         // was created before this task was started
249
250         // Block waiting for the semaphore to become available.
251         if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
252         {
253             // It is time to execute.
254
255             // ...
256
257             // We have finished our task.  Return to the top of the loop where
258             // we will block on the semaphore until it is time to execute 
259             // again.
260         }
261     }
262  }
263
264  // Timer ISR
265  void vTimerISR( void * pvParameters )
266  {
267  static unsigned portCHAR ucLocalTickCount = 0;
268
269     // A timer tick has occurred.
270
271     // ... Do other time functions.
272
273     // Is it time for vATask () to run?
274     ucLocalTickCount++;
275     if( ucLocalTickCount >= TICKS_TO_WAIT )
276     {
277         // Unblock the task by releasing the semaphore.
278         xSemaphoreGive( xSemaphore );
279
280         // Reset the count so we release the semaphore again in 10 ticks time.
281         ucLocalTickCount = 0;
282     }
283  }
284  </pre>
285  * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
286  * \ingroup Semaphores
287  */
288 #define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken )                       xQueueSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken )
289
290
291 #endif
292