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