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