]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_aquosa/fosa_mutexes_and_condvars.c
Split FOSA opaque types to multiple files based on platform name
[frescor/fosa.git] / src_aquosa / fosa_mutexes_and_condvars.c
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
3 //
4 //    Universidad de Cantabria,              SPAIN
5 //    University of York,                    UK
6 //    Scuola Superiore Sant'Anna,            ITALY
7 //    Kaiserslautern University,             GERMANY
8 //    Univ. Politécnica  Valencia,           SPAIN
9 //    Czech Technical University in Prague,  CZECH REPUBLIC
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org for a link to partners' websites
17 //
18 //           FRESCOR project (FP6/2005/IST/5-034026) is funded
19 //        in part by the European Union Sixth Framework Programme
20 //        The European Union is not liable of any use that may be
21 //        made of this code.
22 //
23 //
24 //  based on previous work (FSF) done in the FIRST project
25 //
26 //   Copyright (C) 2005  Mälardalen University, SWEDEN
27 //                       Scuola Superiore S.Anna, ITALY
28 //                       Universidad de Cantabria, SPAIN
29 //                       University of York, UK
30 //
31 //   FSF API web pages: http://marte.unican.es/fsf/docs
32 //                      http://shark.sssup.it/contrib/first/docs/
33 //
34 //   This file is part of FOSA (Frsh Operating System Adaption)
35 //
36 //  FOSA is free software; you can redistribute it and/or modify it
37 //  under terms of the GNU General Public License as published by the
38 //  Free Software Foundation; either version 2, or (at your option) any
39 //  later version.  FOSA is distributed in the hope that it will be
40 //  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
41 //  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 //  General Public License for more details. You should have received a
43 //  copy of the GNU General Public License along with FOSA; see file
44 //  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
45 //  Cambridge, MA 02139, USA.
46 //
47 //  As a special exception, including FOSA header files in a file,
48 //  instantiating FOSA generics or templates, or linking other files
49 //  with FOSA objects to produce an executable application, does not
50 //  by itself cause the resulting executable application to be covered
51 //  by the GNU General Public License. This exception does not
52 //  however invalidate any other reasons why the executable file might be
53 //  covered by the GNU Public License.
54 // -----------------------------------------------------------------------
55 //fosa_mutexes_and_condvars.h
56 //==============================================
57 //  ********  ******    ********  **********
58 //  **///// /**    **  **//////  /**     /**
59 //  **      /**    ** /**        /**     /**
60 //  ******* /**    ** /********* /**********
61 //  **////  /**    ** ////////** /**//////**
62 //  **      /**    **        /** /**     /**
63 //  **      /**    **  ********  /**     /**
64 //  //       /******/  ////////   //      // 
65 //
66 // FOSA(Frescor Operating System Adaptation layer)
67 //================================================
68
69 #include "fosa_time.h"
70 #include "fosa_configuration_parameters.h"
71 #include "fosa_mutexes_and_condvars.h"
72
73 #ifdef OMK_FOR_USER             /* If compiled by OMK, use the config */
74 #include "fosa_config.h"
75 #endif
76
77 /*******************************************************
78  * Mutexes with priority/bandwidth inheritance
79  ******************************************************/
80
81 /**
82  * fosa_mutex_init()
83  *
84  * Initialize a frsh mutex
85  *
86  * The mutex pointed to by mutex is initialized as a mutex using
87  * the priority ceiling protocol. A priority ceiling of prioceiling
88  * is assigned to this mutex.
89  *
90  * Returns 0 if successful; otherwise it returns an error code:
91  *    EINVAL: the value of prioceiling is invalid
92  *    EAGAIN: the system lacked the necessary resources to create the mutex
93  *    ENOMEM: Insufficient memory exists to initialize the mutex
94  *    EBUSY:  The system has detected an attempt to reinitialize the mutex
95  **/
96 int fosa_mutex_init(fosa_mutex_t *mutex, int prioceiling)
97 {
98         int ret;
99         pthread_mutexattr_t attr;
100
101         ret = pthread_mutexattr_init(&attr);
102         if (ret) return errno;
103
104 #ifndef CONFIG_NO_PRIO_INHERIT  /* Valgrind doesn't support this attribute */
105         ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
106         if (ret) return errno;
107 #endif
108
109         ret = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
110         if (ret) return errno;
111
112         return pthread_mutex_init(mutex, &attr);
113 }
114
115 /**
116  * fosa_mutex_destroy()
117  *
118  * Destroy a frsh mutex
119  *
120  * The mutex pointed to by mutex is destroyed
121  *
122  * Returns 0 if successful; otherwise it returns an error code:
123  *    EINVAL: the value of mutex is invalid
124  *    EBUSY:  The mutex is in use (is locked)
125  **/
126 int fosa_mutex_destroy(fosa_mutex_t *mutex)
127 {
128         return pthread_mutex_destroy(mutex);
129 }
130
131 /**
132  * fosa_mutex_set_prioceiling()
133  *
134  * Dynamically set the priority ceiling of a mutex
135  *
136  * Since in this implementation we use BandWidth Inheritance defining the
137  * ceiling of a mutex is meaningless, and so the function always returns
138  * EINVAL
139  **/
140 int fosa_mutex_set_prioceiling(fosa_mutex_t *mutex,
141                                int new_ceiling,
142                                int *old_ceiling)
143 {
144         return FOSA_EINVAL;
145 }
146
147 /**
148  * fosa_mutex_get_prioceiling()
149  *
150  * Dynamically get the priority ceiling of a mutex
151  *
152  * Since in this implementation we use BandWidth Inheritance defining the
153  * ceiling of a mutex is meaningless, and so the function always returns
154  * EINVAL
155  **/
156 int fosa_mutex_get_prioceiling(const fosa_mutex_t *mutex, int *ceiling)
157 {
158         return FOSA_EINVAL;
159 }
160
161 /**
162  * fosa_mutex_lock()
163  *
164  * Lock a mutex
165  *
166  * This function locks the mutex specified by mutex. If it is already
167  * locked, the calling thread blocks until the mutex becomes
168  * available. The operation returns with the mutex in the locked
169  * state, with the calling thread as its owner.
170  *
171  * Returns 0 if successful; otherwise it returns an error code:
172  *    EINVAL: the value of mutex is invalid, or the priority of the
173  *            calling thread is higher than the priority ceiling of the mutex
174  *    EDEADLK: the current thread already owns this mutex
175  **/
176 int fosa_mutex_lock(fosa_mutex_t *mutex)
177 {
178         return pthread_mutex_lock(mutex);
179 }
180
181 /**
182  * fosa_mutex_trylock()
183  *
184  * Try locking a mutex
185  *
186  * This function is identical to fosa_mutex_lock() except that if the
187  * mutex is already locked the call returns immediately with an error
188  * indication.
189  *
190  * Returns 0 if successful; otherwise it returns an error code:
191  *    EINVAL: the value of mutex is invalid, or the priority of the
192  *            calling thread is higher than the priority ceiling of the mutex
193  *    EBUSY: the mutex was already locked
194  **/
195 int fosa_mutex_trylock(fosa_mutex_t *mutex)
196 {
197         return pthread_mutex_trylock(mutex);
198 }
199
200 /**
201  * fosa_mutex_unlock()
202  *
203  * Unlock a mutex
204  *
205  * This function must be called by the owner of the mutex referenced
206  * by mutex, to unlock it. If there are threads blocked on the mutex
207  * the mutex becomes available and the highest priority thread is
208  * awakened to acquire the mutex.
209  *
210  * Returns 0 if successful; otherwise it returns an error code:
211  *     EINVAL: the value of mutex is invalid
212  *     EPERM: the calling thread is not the owner of the mutex
213  **/
214 int fosa_mutex_unlock(fosa_mutex_t *mutex)
215 {
216         return pthread_mutex_unlock(mutex);
217 }
218
219 /**********************
220  * Condition variables
221  *********************/
222
223 /**
224  * fosa_cond_init()
225  *
226  * Initiatize a condition variable
227  *
228  * The condition variable referenced by cond is initialized with
229  * the attributes required by the FOSA implementation.
230  *
231  *  Returns 0 if successful; otherwise it returns an error code:
232  *     EAGAIN: the system lacked the necessary resources to create the
233  *             condition variable
234  *     ENOMEM: Insufficient memory exists to initialize the condition variable
235  *     EBUSY:  The system has detected an attempt to reinitialize the
236  *             condition variable
237  **/
238 int fosa_cond_init(fosa_cond_t *cond)
239 {
240         int ret;
241         pthread_condattr_t attr;
242
243         ret = pthread_condattr_init(&attr);
244         if (ret) return errno;
245
246         ret = pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
247         if (ret) return errno;
248
249         return pthread_cond_init(cond, &attr);
250 }
251
252 /**
253  * fosa_cond_destroy()
254  *
255  * Destroy a condition variable
256  *
257  * The condition variable pointed to by cond is destroyed
258  *
259  * Returns 0 if successful; otherwise it returns an error code:
260  *     EINVAL: the value of cond is invalid
261  *     EBUSY:  The condition variable is in use (a thread is waiting on it)
262  **/
263 int fosa_cond_destroy(fosa_cond_t *cond)
264 {
265         return pthread_cond_destroy(cond);
266 }
267
268 /**
269  * fosa_cond_signal()
270  *
271  * Signal a condition variable
272  *
273  * This call unblocks at least one of the threads that are waiting on
274  * the condition variable referenced by cond. If there are no threads
275  * waiting, the function has no effect
276  *
277  * Returns 0 if successful; otherwise it returns an error code:
278  *     EINVAL: the value of cond is invalid
279  **/
280 int fosa_cond_signal(fosa_cond_t *cond)
281 {
282         return pthread_cond_signal(cond);
283 }
284
285 /**
286  * fosa_cond_broadcast()
287  *
288  * Broadcast a condition variable
289  *
290  * This call unblocks all of the threads that are waiting on the
291  * condition variable referenced by cond. If there are no threads
292  * waiting, the function has no effect.
293  *
294  * Returns 0 if successful; otherwise it returns an error code:
295  *     EINVAL: the value of cond is invalid
296  **/
297 int fosa_cond_broadcast(fosa_cond_t *cond)
298 {
299         return pthread_cond_broadcast(cond);
300 }
301
302 /**
303  * fosa_cond_wait()
304  *
305  * Wait at a condition variable
306  *
307  * This call is used to block on the condition variable referenced by
308  * cond. It shall be called with the mutex referenced by mutex
309  * locked. The function releases the mutex and blocks the calling
310  * thread until the condition is signalled by some other thread and
311  * the calling thread is awakened. Then it locks the mutex and
312  * returns with the mutex locked by the calling thread.
313  *
314  * Returns 0 if successful; otherwise it returns an error code:
315  *    EINVAL: the value of cond or mutex is invalid, or different
316  *            mutexes were used for concurrent wait operations on cond, or
317  *            the mutex was not owned by the calling thread
318  **/
319 int fosa_cond_wait(fosa_cond_t *cond, fosa_mutex_t *mutex)
320 {
321         return pthread_cond_wait(cond, mutex);
322 }
323
324 /**
325  * fosa_cond_timedwait()
326  *
327  * Wait at a condition variable, with a timeout
328  *
329  * This function is equal to fosa_cond_wait(), except that the maximum
330  * wait time is limited to the absolute time referenced by abstime, as
331  * measured by the FOSA_CLOCK_ABSOLUTE clock.
332  *
333  * Returns 0 if successful; otherwise it returns an error code:
334  *     EINVAL: the value of cond or mutex or abstime is invalid, or different
335  *             mutexes were used for concurrent wait operations on cond, or
336  *             the mutex was not owned by the calling thread
337  *     ETIMEDOUT: the timeout expired
338  **/
339 int fosa_cond_timedwait(fosa_cond_t *cond,
340         fosa_mutex_t *mutex,
341         const fosa_abs_time_t *abstime)
342 {
343         struct timespec abstime_tspec;
344
345         abstime_tspec = fosa_abs_time_to_timespec(*abstime);
346         return pthread_cond_timedwait(cond, mutex, &abstime_tspec);
347 }
348