]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_aquosa/fosa_mutexes_and_condvars.c
move all the time related issues to FOSA absolute and relative data types.
[frescor/fosa.git] / src_aquosa / fosa_mutexes_and_condvars.c
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2007 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. Politecnica  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 //  This file is part of the FRSH implementation
24 //
25 //  FRSH is free software; you can  redistribute it and/or  modify
26 //  it under the terms of  the GNU General Public License as published by
27 //  the Free Software Foundation;  either  version 2, or (at  your option)
28 //  any later version.
29 //
30 //  FRSH  is distributed  in  the hope  that  it  will  be useful,  but
31 //  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
32 //  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
33 //  General Public License for more details.
34 //
35 //  You should have  received a  copy of  the  GNU  General Public License
36 //  distributed  with  FRSH;  see file COPYING.   If not,  write to the
37 //  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
38 //  02111-1307, USA.
39 //
40 //  As a special exception, if you include this header file into source
41 //  files to be compiled, this header file does not by itself cause
42 //  the resulting executable to be covered by the GNU General Public
43 //  License.  This exception does not however invalidate any other
44 //  reasons why the executable file might be covered by the GNU General
45 //  Public License.
46 // -----------------------------------------------------------------------
47 //fosa_mutexes_and_condvars.h
48 //==============================================
49 //  ********  ******    ********  **********
50 //  **///// /**    **  **//////  /**     /**
51 //  **      /**    ** /**        /**     /**
52 //  ******* /**    ** /********* /**********
53 //  **////  /**    ** ////////** /**//////**
54 //  **      /**    **        /** /**     /**
55 //  **      /**    **  ********  /**     /**
56 //  //       /******/  ////////   //      // 
57 //
58 // FOSA(Frescor Operating System Adaptation layer)
59 //================================================
60
61 #include "fosa_time.h"
62 #include "fosa_mutexes_and_condvars.h"
63
64 /*******************************************************
65  * Mutexes with priority/bandwidth inheritance
66  ******************************************************/
67
68 /**
69  * fosa_mutex_init()
70  *
71  * Initialize a frsh mutex
72  *
73  * The mutex pointed to by mutex is initialized as a mutex using
74  * the priority ceiling protocol. A priority ceiling of prioceiling
75  * is assigned to this mutex.
76  *
77  * Returns 0 if successful; otherwise it returns an error code:
78  *    EINVAL: the value of prioceiling is invalid
79  *    EAGAIN: the system lacked the necessary resources to create the mutex
80  *    ENOMEM: Insufficient memory exists to initialize the mutex
81  *    EBUSY:  The system has detected an attempt to reinitialize the mutex
82  **/
83 int fosa_mutex_init(fosa_mutex_t *mutex, int prioceiling)
84 {
85         int error;
86         pthread_mutexattr_t attr;
87
88         if ((error = pthread_mutexattr_init(&attr)) != 0)
89                 return error;
90
91         if ((error = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) != 0)
92                 return error;
93
94         return pthread_mutex_init(mutex, &attr);
95 }
96
97 /**
98  * fosa_mutex_destroy()
99  *
100  * Destroy a frsh mutex
101  *
102  * The mutex pointed to by mutex is destroyed
103  *
104  * Returns 0 if successful; otherwise it returns an error code:
105  *    EINVAL: the value of mutex is invalid
106  *    EBUSY:  The mutex is in use (is locked)
107  **/
108 int fosa_mutex_destroy(fosa_mutex_t *mutex)
109 {
110         return pthread_mutex_destroy(mutex);
111 }
112
113 /**
114  * fosa_mutex_set_prioceiling()
115  *
116  * Dynamically set the priority ceiling of a mutex
117  *
118  * Since in this implementation we use BandWidth Inheritance defining the
119  * ceiling of a mutex is meaningless, and so the function always returns
120  * EINVAL
121  **/
122 int fosa_mutex_set_prioceiling(fosa_mutex_t *mutex,
123                                int new_ceiling,
124                                int *old_ceiling)
125 {
126         return -EINVAL;
127 }
128
129 /**
130  * fosa_mutex_get_prioceiling()
131  *
132  * Dynamically get the priority ceiling of a mutex
133  *
134  * Since in this implementation we use BandWidth Inheritance defining the
135  * ceiling of a mutex is meaningless, and so the function always returns
136  * EINVAL
137  **/
138 int fosa_mutex_get_prioceiling(const fosa_mutex_t *mutex, int *ceiling)
139 {
140         return -EINVAL;
141 }
142
143 /**
144  * fosa_mutex_lock()
145  *
146  * Lock a mutex
147  *
148  * This function locks the mutex specified by mutex. If it is already
149  * locked, the calling thread blocks until the mutex becomes
150  * available. The operation returns with the mutex in the locked
151  * state, with the calling thread as its owner.
152  *
153  * Returns 0 if successful; otherwise it returns an error code:
154  *    EINVAL: the value of mutex is invalid, or the priority of the
155  *            calling thread is higher than the priority ceiling of the mutex
156  *    EDEADLK: the current thread already owns this mutex
157  **/
158 int fosa_mutex_lock(fosa_mutex_t *mutex)
159 {
160         return pthread_mutex_lock(mutex);
161 }
162
163 /**
164  * fosa_mutex_trylock()
165  *
166  * Try locking a mutex
167  *
168  * This function is identical to fosa_mutex_lock() except that if the
169  * mutex is already locked the call returns immediately with an error
170  * indication.
171  *
172  * Returns 0 if successful; otherwise it returns an error code:
173  *    EINVAL: the value of mutex is invalid, or the priority of the
174  *            calling thread is higher than the priority ceiling of the mutex
175  *    EBUSY: the mutex was already locked
176  **/
177 int fosa_mutex_trylock(fosa_mutex_t *mutex)
178 {
179         return pthread_mutex_trylock(mutex);
180 }
181
182 /**
183  * fosa_mutex_unlock()
184  *
185  * Unlock a mutex
186  *
187  * This function must be called by the owner of the mutex referenced
188  * by mutex, to unlock it. If there are threads blocked on the mutex
189  * the mutex becomes available and the highest priority thread is
190  * awakened to acquire the mutex.
191  *
192  * Returns 0 if successful; otherwise it returns an error code:
193  *     EINVAL: the value of mutex is invalid
194  *     EPERM: the calling thread is not the owner of the mutex
195  **/
196 int fosa_mutex_unlock(fosa_mutex_t *mutex)
197 {
198         return pthread_mutex_unlock(mutex);
199 }
200
201 /**********************
202  * Condition variables
203  *********************/
204
205 /**
206  * fosa_cond_init()
207  *
208  * Initiatize a condition variable
209  *
210  * The condition variable referenced by cond is initialized with
211  * the attributes required by the FOSA implementation.
212  *
213  *  Returns 0 if successful; otherwise it returns an error code:
214  *     EAGAIN: the system lacked the necessary resources to create the
215  *             condition variable
216  *     ENOMEM: Insufficient memory exists to initialize the condition variable
217  *     EBUSY:  The system has detected an attempt to reinitialize the
218  *             condition variable
219  **/
220 int fosa_cond_init(fosa_cond_t *cond)
221 {
222         return pthread_cond_init(cond, NULL);
223 }
224
225 /**
226  * fosa_cond_destroy()
227  *
228  * Destroy a condition variable
229  *
230  * The condition variable pointed to by cond is destroyed
231  *
232  * Returns 0 if successful; otherwise it returns an error code:
233  *     EINVAL: the value of cond is invalid
234  *     EBUSY:  The condition variable is in use (a thread is waiting on it)
235  **/
236 int fosa_cond_destroy(fosa_cond_t *cond)
237 {
238         return pthread_cond_destroy(cond);
239 }
240
241 /**
242  * fosa_cond_signal()
243  *
244  * Signal a condition variable
245  *
246  * This call unblocks at least one of the threads that are waiting on
247  * the condition variable referenced by cond. If there are no threads
248  * waiting, the function has no effect
249  *
250  * Returns 0 if successful; otherwise it returns an error code:
251  *     EINVAL: the value of cond is invalid
252  **/
253 int fosa_cond_signal(fosa_cond_t *cond)
254 {
255         return pthread_cond_signal(cond);
256 }
257
258 /**
259  * fosa_cond_broadcast()
260  *
261  * Broadcast a condition variable
262  *
263  * This call unblocks all of the threads that are waiting on the
264  * condition variable referenced by cond. If there are no threads
265  * waiting, the function has no effect.
266  *
267  * Returns 0 if successful; otherwise it returns an error code:
268  *     EINVAL: the value of cond is invalid
269  **/
270 int fosa_cond_broadcast(fosa_cond_t *cond)
271 {
272         return pthread_cond_broadcast(cond);
273 }
274
275 /**
276  * fosa_cond_wait()
277  *
278  * Wait at a condition variable
279  *
280  * This call is used to block on the condition variable referenced by
281  * cond. It shall be called with the mutex referenced by mutex
282  * locked. The function releases the mutex and blocks the calling
283  * thread until the condition is signalled by some other thread and
284  * the calling thread is awakened. Then it locks the mutex and
285  * returns with the mutex locked by the calling thread.
286  *
287  * Returns 0 if successful; otherwise it returns an error code:
288  *    EINVAL: the value of cond or mutex is invalid, or different
289  *            mutexes were used for concurrent wait operations on cond, or
290  *            the mutex was not owned by the calling thread
291  **/
292 int fosa_cond_wait(fosa_cond_t *cond, fosa_mutex_t *mutex)
293 {
294         return pthread_cond_wait(cond, mutex);
295 }
296
297 /**
298  * fosa_cond_timedwait()
299  *
300  * Wait at a condition variable, with a timeout
301  *
302  * This function is equal to fosa_cond_wait(), except that the maximum
303  * wait time is limited to the absolute time referenced by abstime, as
304  * measured by the FOSA_CLOCK_ABSOLUTE clock.
305  *
306  * Returns 0 if successful; otherwise it returns an error code:
307  *     EINVAL: the value of cond or mutex or abstime is invalid, or different
308  *             mutexes were used for concurrent wait operations on cond, or
309  *             the mutex was not owned by the calling thread
310  *     ETIMEDOUT: the timeout expired
311  **/
312 int fosa_cond_timedwait(fosa_cond_t *cond,
313         fosa_mutex_t *mutex,
314         const fosa_abs_time_t *abstime)
315 {
316         struct timespec abstime_tspec;
317
318         abstime_tspec = fosa_abs_time_to_timespec(*abstime);
319
320         return pthread_cond_timedwait(cond, mutex, &abstime_tspec);
321 }