]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_partikle/fosa_threads_and_signals.c
FOSA-PaRTiKle implementation
[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 // TODO: planificació jeràrquica
175
176 int fosa_get_priority_max()
177 {
178         return sched_get_priority_min (SCHED_FIFO);
179 }
180
181 int fosa_get_priority_min()
182 {
183         return sched_get_priority_max (SCHED_FIFO);
184 }
185
186 int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
187 {
188         struct sched_param sp;
189         
190         if (prio > fosa_get_priority_max () || prio < fosa_get_priority_min ())
191                 return EINVAL;
192         
193         sp.sched_priority = sched_get_priority_min (SCHED_FIFO) - prio;
194         
195         return pthread_attr_setschedparam (attr, &sp);
196 }
197
198  int fosa_thread_attr_get_prio
199      (const fosa_thread_attr_t *attr, int *prio)
200 {
201         struct sched_param sp;
202         
203         pthread_attr_getschedparam (attr, &sp);
204         
205         *prio = sched_get_priority_min (SCHED_FIFO) - sp.sched_priority;
206         
207         return 0;
208 }
209
210 int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
211 {
212         struct sched_param sp;
213         int policy;
214
215         if (prio > fosa_get_priority_max () || prio < fosa_get_priority_min ())
216                 return EINVAL;
217         
218         pthread_getschedparam (tid, &policy, &sp);
219         sp.sched_priority = sched_get_priority_min (SCHED_FIFO) - prio;
220         
221         return pthread_setschedparam (tid, policy, &sp);
222 }
223         
224 int fosa_thread_get_prio (fosa_thread_id_t tid, int *prio)
225 {
226         struct sched_param sp;
227         int policy;
228         
229         pthread_getschedparam (tid, &policy, &sp);
230         *prio = sched_get_priority_min (SCHED_FIFO) - sp.sched_priority;
231         
232         return 0;
233 }
234
235
236 /*************
237  * Signals
238  *************/
239 int fosa_set_accepted_signals(fosa_signal_t set[], int size)
240 {
241         int i;
242         sigset_t accept_set;
243         struct sigaction act;
244         
245         if (size < 0) 
246                 return EINVAL;
247         
248         sigemptyset (&accept_set);
249         act.sa_mask = accept_set;
250         act.sa_flags = SA_SIGINFO;
251         act.sa_handler = SIG_DFL;
252         
253 //      printf ("Handled\n");
254 //      printf ("Fosa signal range [%d,%d]\n", FOSA_SIGNAL_MIN, FOSA_SIGNAL_MAX);
255         for (i = 0; i < size; i ++) {
256 //              printf ("signal num=%d\n", set [i]);
257                 if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
258                         return EINVAL;
259         
260                 sigaction (set [i], &act, NULL);
261                 sigaddset (&accept_set, set [i]);
262         }
263         
264 //      printf ("Added to accept set\n");
265         return pthread_sigmask (SIG_BLOCK, &accept_set, NULL);
266 }
267
268
269 int fosa_signal_queue
270     (fosa_signal_t signal, fosa_signal_info_t info,
271      fosa_thread_id_t receiver)
272 {
273         union sigval *nfo = (union sigval *) &info;
274         
275         if (sigqueue (1, signal, *nfo))
276                 return errno;
277         else
278                 return 0;
279 }
280
281
282  int fosa_signal_wait
283      (fosa_signal_t set[], int size, fosa_signal_t *signal_received, 
284       fosa_signal_info_t *info)
285 {
286         return fosa_signal_timedwait (set, size, signal_received, info, NULL);
287 }
288
289  int fosa_signal_timedwait
290      (fosa_signal_t set[], int size, fosa_signal_t *signal_received, 
291       fosa_signal_info_t *info, const struct timespec *timeout)
292 {
293         int i, sig;
294         sigset_t wset;
295         siginfo_t nfo;
296         
297         if (size < 0) 
298                 return EINVAL;
299
300         sigemptyset (&wset);
301         for (i = 0; i < size; i ++) {
302                 if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
303                         return EINVAL;
304                 sigaddset (&wset, set [i]);
305         }
306         
307         sig = sigtimedwait (&wset, &nfo, timeout);
308         if (sig == -1)
309                 return errno;
310         
311         if (info)
312                 *info = *((fosa_signal_info_t*) (&nfo.si_value));
313         
314         if (signal_received)
315                 *signal_received = sig;
316         
317         return 0;
318 }