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