]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_partikle/fosa_threads_and_signals.c
FOSA-PaRTiKle: some clean up
[frescor/fosa.git] / src_partikle / fosa_threads_and_signals.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 //==============================================
48 //  ********  ******    ********  **********
49 //  **///// /**    **  **//////  /**     /**
50 //  **      /**    ** /**        /**     /**
51 //  ******* /**    ** /********* /**********
52 //  **////  /**    ** ////////** /**//////**
53 //  **      /**    **        /** /**     /**
54 //  **      /**    **  ********  /**     /**
55 //  //       /******/  ////////   //      // 
56 //
57 // FOSA(Frescor Operating System Adaptation layer)
58 //================================================
59
60 #include <fosa_configuration_parameters.h>
61 #include <fosa_threads_and_signals.h>
62 #include <unistd.h>
63 #include <signal.h>
64
65 /*************************
66  * Thread identification
67  *************************/ 
68 bool fosa_thread_equal(fosa_thread_id_t t1, fosa_thread_id_t t2)
69 {
70         return pthread_equal (t1, t2);
71 }
72
73 fosa_thread_id_t fosa_thread_self()
74 {
75         return pthread_self();
76 }
77
78 /*************************
79  * Thread attributes
80  *************************/ 
81
82 int fosa_thread_attr_init(fosa_thread_attr_t *attr)
83 {
84   return pthread_attr_init (attr);
85 }
86
87 int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
88 {
89   return pthread_attr_destroy (attr);
90 }
91
92 int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
93                                    size_t stacksize)
94 {
95   return pthread_attr_setstacksize (attr, stacksize);
96 }
97
98
99 int fosa_thread_attr_get_stacksize(const fosa_thread_attr_t *attr, 
100                                    size_t *stacksize)
101 {
102   return pthread_attr_getstacksize (attr, stacksize);
103 }
104
105
106 /*************************
107  * Thread creation and termination
108  *************************/ 
109  int fosa_thread_create
110      (fosa_thread_id_t *tid, 
111       const fosa_thread_attr_t *attr, 
112       fosa_thread_code_t code, 
113       void * arg)
114 {
115   return pthread_create (tid, attr, code, arg);
116 }
117
118
119 /**************************************************
120  * Thread-specific data
121  *  (extended with access from a different thread)
122  **************************************************/ 
123 int fosa_key_create(int *key)
124 {
125         switch (pthread_key_create (key, NULL)) {
126                 case 0:
127                         break;
128                 case ENOMEM:
129                         return ENOMEM;
130                         break;
131                 case EAGAIN:
132                 default:
133                         return FOSA_EINVAL;
134         }
135
136         if (*key >= FOSA_MAX_KEYS + 1) {
137                 pthread_key_delete (*key);
138                 return FOSA_EINVAL;
139         }
140         
141         return 0;
142 }
143
144 int fosa_key_destroy(int key)
145 {
146         if (key < 0 || key >= FOSA_MAX_KEYS + 1)
147                 return FOSA_EINVAL;
148         
149         return pthread_key_delete (key);
150 }
151
152  int fosa_thread_set_specific_data
153      (int key, fosa_thread_id_t tid, const void * value)
154 {
155         if (key < 0 || key >= FOSA_MAX_KEYS + 1)
156                 return FOSA_EINVAL;
157         
158         return pthread_setspecific_for (key, tid, value);
159 }
160
161 int fosa_thread_get_specific_data(int key, fosa_thread_id_t tid, 
162                                   void ** value)
163 {
164         if (key < 0 || key >= FOSA_MAX_KEYS + 1)
165                 return FOSA_EINVAL;
166
167         return pthread_getspecific_from (key, tid, value);
168 }
169
170 /**********************
171  * Thread scheduling
172  **********************/
173 // PaRTiKle uses decreasing values for increasing priority (0 -> maxprio)
174
175 inline int fosa2prtk (int prio, int urg)
176 {
177   return ((prio & 0x3f) << 4) + (urg & 0xf);
178 }
179
180 static inline int prtk2fprio (int prio)
181 {
182   return (prio >> 4) & 0x3f;
183 }
184
185 static inline int prtk2furg (int prio)
186 {
187   return prio & 0xf;
188 }
189
190
191 int fosa_get_priority_max()
192 {
193         return prtk2fprio (sched_get_priority_min (SCHED_FIFO));
194 }
195
196 int fosa_get_priority_min()
197 {
198         return prtk2fprio (sched_get_priority_max (SCHED_FIFO));
199 }
200
201 int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
202 {
203         struct sched_param sp;
204         
205         if (prio > fosa_get_priority_max () || prio < fosa_get_priority_min ())
206                 return EINVAL;
207         
208         sp.sched_priority = sched_get_priority_min (SCHED_FIFO) - fosa2prtk (prio, 0);
209         
210         return pthread_attr_setschedparam (attr, &sp);
211 }
212
213  int fosa_thread_attr_get_prio
214      (const fosa_thread_attr_t *attr, int *prio)
215 {
216         struct sched_param sp;
217         
218         pthread_attr_getschedparam (attr, &sp);
219         
220         *prio = prtk2fprio (sched_get_priority_min (SCHED_FIFO) - sp.sched_priority);
221         
222         return 0;
223 }
224
225 int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
226 {
227         struct sched_param sp;
228         int policy;
229
230         if (prio > fosa_get_priority_max () || prio < fosa_get_priority_min ())
231                 return EINVAL;
232         
233         pthread_getschedparam (tid, &policy, &sp);
234         sp.sched_priority = sched_get_priority_min (SCHED_FIFO) - fosa2prtk (prio, 0);
235         
236         return pthread_setschedparam (tid, policy, &sp);
237 }
238         
239 int fosa_thread_get_prio (fosa_thread_id_t tid, int *prio)
240 {
241         struct sched_param sp;
242         int policy;
243         
244         pthread_getschedparam (tid, &policy, &sp);
245         *prio = sched_get_priority_min (SCHED_FIFO) - sp.sched_priority;
246         
247         return 0;
248 }
249
250
251 /*************
252  * Signals
253  *************/
254 int fosa_set_accepted_signals(fosa_signal_t set[], int size)
255 {
256         int i;
257         sigset_t accept_set;
258         struct sigaction act;
259         
260         if (size < 0) 
261                 return EINVAL;
262         
263         sigemptyset (&accept_set);
264         act.sa_mask = accept_set;
265         act.sa_flags = SA_SIGINFO;
266         act.sa_handler = SIG_DFL;
267         
268         for (i = 0; i < size; i ++) {
269                 if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
270                         return EINVAL;
271         
272                 sigaction (set [i], &act, NULL);
273                 sigaddset (&accept_set, set [i]);
274         }
275         
276         return pthread_sigmask (SIG_BLOCK, &accept_set, NULL);
277 }
278
279
280 int fosa_signal_queue
281     (fosa_signal_t signal, fosa_signal_info_t info,
282      fosa_thread_id_t receiver)
283 {
284         union sigval nfo = (union sigval) info.sival_ptr;
285         
286         if (sigqueue (1, signal, nfo))
287                 return errno;
288         else
289                 return 0;
290 }
291
292
293  int fosa_signal_wait
294      (fosa_signal_t set[], int size, fosa_signal_t *signal_received, 
295       fosa_signal_info_t *info)
296 {
297         return fosa_signal_timedwait (set, size, signal_received, info, NULL);
298 }
299
300  int fosa_signal_timedwait
301      (fosa_signal_t set[], int size, fosa_signal_t *signal_received, 
302       fosa_signal_info_t *info, const struct timespec *timeout)
303 {
304         int i, sig;
305         sigset_t wset;
306         siginfo_t nfo;
307         
308         if (size < 0) 
309                 return EINVAL;
310
311         sigemptyset (&wset);
312         for (i = 0; i < size; i ++) {
313                 if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
314                         return EINVAL;
315                 sigaddset (&wset, set [i]);
316         }
317         
318         sig = sigtimedwait (&wset, &nfo, timeout);
319         if (sig == -1)
320                 return errno;
321         
322         if (info)
323                 *info = (fosa_signal_info_t) nfo.si_value.sival_ptr;
324         
325         if (signal_received)
326                 *signal_received = sig;
327         
328         return 0;
329 }