]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_rtlinux/fosa_threads_and_signals.h
76a940276d7eb0b585667d7189b157e42a763f2d
[frescor/fosa.git] / src_rtlinux / fosa_threads_and_signals.h
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 //fosa_thread_and_signals.h
48 //==============================================
49 //  ********  ******    ********  **********
50 //  **///// /**    **  **//////  /**     /**
51 //  **      /**    ** /**        /**     /**
52 //  ******* /**    ** /********* /**********
53 //  **////  /**    ** ////////** /**//////**
54 //  **      /**    **        /** /**     /**
55 //  **      /**    **  ********  /**     /**
56 //  //       /******/  ////////   //      // 
57 //
58 // FOSA(Frescor Operating System Adaptation layer)
59 //================================================
60
61
62 #ifndef         FOSA_THREAD_AND_SIGNALS_H_
63 #define         FOSA_THREAD_AND_SIGNALS_H_
64
65 /**
66  * @defgroup threadandsignals Thread and Signals
67  * @ingroup fosa
68  *
69  * This module defines the functions that manipulate frsh_threads and
70  * frsh_signals inside FRSH implementation.
71  *
72  * Applications can refer to FRSH threads but they cannot create them
73  * directly, instead they must use frsh_thread_create*() which in turn
74  * use fosa_thread_create().
75  *
76  * For signals, we assume that the OS provides a direct mapping
77  * for frsh_signal_t and frsh_signal_info_t in the native interface.
78  *
79  * @{
80  **/
81
82
83
84 /*************************
85  * Thread identification
86  *************************/ 
87
88 /**
89  * fosa_thread_equal()
90  *
91  * Compare two thread identifiers to determine if they refer to the 
92  * same thread
93  **/
94 //bool fosa_thread_equal(frsh_thread_id_t t1, frsh_thread_id_t t2);
95
96 extern inline bool fosa_thread_equal(frsh_thread_id_t t1, frsh_thread_id_t t2){
97      return pthread_equal(t1,t2);
98 }
99
100
101 /**
102  * fosa_thread_self()
103  *
104  * Return the thread id of the calling thread
105  **/
106 //frsh_thread_id_t fosa_thread_self();
107
108 extern inline frsh_thread_id_t fosa_thread_self(){
109      retrun pthread_self();
110 }
111
112 /*************************
113  * Thread creation and termination
114  *************************/ 
115
116 /**
117  * fosa_thread_create()
118  *
119  * This function creates a new thread using the attributes specified
120  * in attr. If attr is NULL, default attributes are used. The new
121  * thread starts running immediately, executing the function specified
122  * by code, with an argument equal to arg. Upon successful return, the
123  * variable pointed to by tid will contain the identifier of the newly
124  * created thread. The set of signals that may be synchronously
125  * accepted is inherited from the parent thread.
126  *
127  * Returns 0 if successful; otherwise it returs a code error:
128  *
129  *     EAGAIN: the system lacks the necessary resources to create a
130  *             new thread or the maximum number of threads has been
131  *             reached
132  *
133  *     EINVAL: the value specified by attr is invalid (for instance,
134  *              it has not been correctly initialized)
135  *
136  *     EREJECT: the cretion of the thread was rejected by the frsh scheduler
137  *               possibly because of incorrect attributes, or because the 
138  *               requested minimum capacity cannot be guaranteed
139  *
140  **/
141 // int fosa_thread_create
142 //    (frsh_thread_id_t *tid, const frsh_thread_attr_t *attr, 
143 //     frsh_thread_code_t code, void * arg);
144
145 extern inline int fosa_thread_create (frsh_thread_id_t *tid, const frsh_thread_attr_t *attr, 
146                                frsh_thread_code_t code, void * arg){
147      return pthread_create(tid,attr,code, arg);
148 }
149
150
151 /**
152  * Note: no thread termination primitive is provided. The termination
153  * of a thread will be notifoed by the system to the FRSH scheduler
154  * through the scheduler API
155  **/
156
157
158 /**************************************************
159  * Thread-specific data
160  *  (extended with access from a different thread)
161  *
162  * Several data items (pointers) may be associated with each thread
163  * Each item is identified through a key, an integer value between 0
164  * and FOSA_MAX_KEYS-1. The caller is responsible of allocating and
165  * deallocating the memory area pointed to by the pointer
166  **************************************************/ 
167
168 /**
169  * fosa_thread_set_specific_data()
170  *
171  * Set thread-specific data
172  *
173  * For the thread identified by tid, the thread-specifid data field
174  * identified by key will be set to the value specified by value
175  *
176  * Returns 0 if successful; otherwise, an error code is returned
177  *     EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
178  *
179  * Alternatively, in case of error the implementation is allowed to
180  * notify it to the system console and then terminate the FRSH
181  * implementation and dependant applications
182  **/
183 // int fosa_thread_set_specific_data
184 //       (int key, frsh_thread_id_t tid, const void * value);
185
186 extern inline int fosa_thread_set_specific_data (int key, frsh_thread_id_t tid, 
187                                            const void * value){
188      if ((0<key) && (key<FOSA_MAX_KEYS-1)){
189           pthread_setspecific_for(key, tid, value);
190           return 0;
191      }
192      return EINVAL;
193 }
194
195 /**
196  * fosa_thread_get_specific_data()
197  *
198  * Get thread-specific data
199  *
200  * For the thread identified by tid, the thread-specifid data field
201  * identified by key will be copied to the variable pointed to by value
202  *
203  * Returns 0 if successful; otherwise, an error code is returned
204  *     EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
205  *
206  * Alternatively, in case of error the implementation is allowed to
207  * notify it to the system console and then terminate the FRSH
208  * implementation and dependant applications
209  **/
210 //int fosa_thread_get_specific_data(int key, frsh_thread_id_t tid, 
211 //                                  void ** value);
212
213
214 extern int fosa_thread_get_specific_data(int key, frsh_thread_id_t tid, 
215                                   void ** value){
216      if ((0<key) && (key<FOSA_MAX_KEYS-1)){
217           *value=pthread_remote_getspecific(key,tid);
218           return 0;
219      }
220      return EINVAL;
221
222 }
223
224
225 /******************************************************************
226  * Thread scheduling
227  * 
228  * This implementation of FRSH assumes an underlying fixed priority
229  * scheduler with priorities in a range, with a minimum and a
230  * maximumm, a number of priority levels with at least 31
231  * priorities. A larger number implies a larger priority. In systems
232  * in which the underlying scheduler uses the opposite convention, a
233  * mapping is automatically provided by the OS adaptation layer.
234  *******************************************************************/
235
236 /**
237  * fosa_get_priority_max()
238  *
239  * Return the maximum priority value used in this implementation
240  **/
241 //int fosa_get_priority_max();
242 extern inline int fosa_get_priority_max() {
243      return sched_get_priority_max(0);
244 }
245
246 /**
247  * fosa_get_priority_min()
248  *
249  * Return the minimum priority value used in this implementation
250  **/
251 //int fosa_get_priority_min();
252
253 extern inline int fosa_get_priority_min(){
254      return sched_get_priority_min(0);
255 }
256
257
258 /**
259  * fosa_thread_attr_set_prio()
260  *
261  * Change the priority of a thread attributes object
262  *
263  * The priority of the thread attriutes object specified by attr is
264  * set to the value specified by prio. This function has no runtime
265  * effect on the priority, except when the attributes object is used
266  * to create a thread, when it will be created with the specified
267  * priority
268  * 
269  * Returns 0 if successful, or the following error code:
270  *    EINVAL: the specified priority value is not between the 
271  *            minimum and the maximum priorities defined in this
272  *            FRSH implementation
273  * Alternatively, in case of error the implementation is allowed to
274  * notify it to the system console and then terminate the FRSH
275  * implementation and dependant applications
276  **/
277 // int fosa_thread_attr_set_prio(frsh_thread_attr_t *attr, int prio);
278
279 extern inline int fosa_thread_attr_set_prio(frsh_thread_attr_t *attr, int prio) {
280      if ((ched_get_priority_min(0)<=prio) || (prio<=sched_get_priority_min(0))){
281           attr->sched_param.sched_priority = prio;
282           return 0;
283      }
284      return EINVAL;
285 }
286
287
288
289 /**
290  * fosa_thread_attr_get_prio()
291  *
292  * Get the priority from a thread attributes object
293  *
294  * This function sets the variable pointed to by prio to the
295  * priority stored in the thread attributes object attr.
296  * 
297  * Returns 0
298  **/
299 // int fosa_thread_attr_get_prio
300 //          (const frsh_thread_attr_t *attr, size_t *prio);
301
302 extern inline  int fosa_thread_attr_get_prio (const frsh_thread_attr_t *attr, size_t *prio){
303      *prio = attr->sched_param.sched_priority;
304      return 0;
305 }
306
307 /**
308  * fosa_thread_set_prio()
309  *
310  * Dynamically change the priority of a thread
311  *
312  * The priority of the thread identified by tid is
313  * set to the value specified by prio. 
314  * 
315  * Returns 0 if successful, or the following error code:
316  *    EINVAL: the specified priority value is not between the 
317  *            minimum and the maximum priorities defined in this
318  *            FRSH implementation
319  * Alternatively, in case of error the implementation is allowed to
320  * notify it to the system console and then terminate the FRSH
321  * implementation and dependant applications
322  **/
323 int fosa_thread_set_prio(frsh_thread_id_t tid, int prio);
324 extern inline fosa_thread_set_prio(frsh_thread_id_t tid, int prio){
325      if ((ched_get_priority_min(0)<=prio) || (prio<=sched_get_priority_min(0))){
326            pthread_setschedprio(tid,prio);
327            return 0;
328      }
329      return EINVAL;
330 }
331
332
333
334 /**
335  * fosa_thread_get_prio()
336  *
337  * Dynamically get the priority of a thread
338  *
339  * This function sets the variable pointed to by prio to the
340  * priority of the thread identified by tid
341  * 
342  * Returns 0
343  **/
344 int fosa_thread_get_prio (frsh_thread_id_t tid, int *prio);
345
346 extern inline int fosa_thread_get_prio (frsh_thread_id_t tid, int *prio){
347      *prio = tid->sched_param.sched_priority;
348      return 0;
349 }
350
351
352
353 /*******************************************************************
354  * Signals
355  *
356  * Signals represent events that may be notified by the system, or
357  * sent explicitly by the application, and for which a thread may
358  * synchronously wait. Signals carry an associated piece of
359  * information (an integer or a pointer) and are queued until they are
360  * accepted.  Signals are identified by an integer signal number (of
361  * the type frsh_signal_t) in the range FOSA_SIGNAL_MIN,
362  * FOSA_SIGNAL_MAX.  This range is required to have at least <tbd>
363  * values.
364  *******************************************************************/
365
366 /**
367  * fosa_set_accepted_signals()
368  *
369  * Establish the set of signals that may be synchronously accepted 
370  * by the calling thread
371  *
372  * The function uses the array of signal numbers specified by set,
373  * which must be of size equal to size
374  *
375  * Returns 0 if successful; otherwise it returns an error code:
376  *     EINVAL: the array contains one or more values which are not
377  *             between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
378  *             is less than 0
379  *
380  * Alternatively, in case of error the implementation is allowed to
381  * notify it to the system console and then terminate the FRSH
382  * implementation and dependant applications
383  **/
384 //int fosa_set_accepted_signals(frsh_signal_t set[], int size);
385
386
387 extern inline int fosa_set_accepted_signals(frsh_signal_t set[], int size) {
388      int x;
389      rtl_sigset_t bitset;
390
391      rtl_sigfillset(bitset); // By default all signals will be blocked.
392      for (x=0; x<size; x++)
393           rtl_sigdelset(bitset, set[x]); // Unblock the "set" of signals.
394      
395      return pthread_sigmask(SIG_SETMASK, bitmask, NULL);
396 }
397
398
399
400 /**
401  * fosa_signal_queue()
402  *
403  * Queue a signal
404  *
405  * This function is used to explicitly send a signal with a specified
406  * value
407  * 
408  * The signal number specified by signal is sent together with the
409  * information specified by info, to the thread identified by
410  * receiver. In those implementations that do not support queueing a
411  * signal with information to a thread (such as POSIX), the signal may
412  * be sent to any thread that is waiting for this signal via
413  * fosa_signal_wait(). Portability can be ensured by having the receiver
414  * thread be the one who is waiting for the signal. 
415  *
416  * Returns 0 if successful; otherwise it returns an error code:
417  *     EINVAL: the signal specified by signal is not
418  *              between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
419  *
420  *     EAGAIN: no resources are available to queue the signal; the
421  *             maximum number of queued signals has been reached, or a
422  *             systemwide resource limit has been exceeded
423  *
424  * Alternatively, in case of error the implementation is allowed to
425  * notify it to the system console and then terminate the FRSH
426  * implementation and dependant applications
427  **/
428 // int fosa_signal_queue
429 //       (frsh_signal_t signal, frsh_signal_info_t info,
430 //        frsh_thread_id_t receiver);
431
432  extern inline int fosa_signal_queue (frsh_signal_t signal, frsh_signal_info_t info,
433                                       frsh_thread_id_t receiver){
434       union sigval value;
435
436       value.sival_ptr=info;
437       return sigqueue(0, signal, value);
438  }
439
440
441 /**
442  * fosa_signal_wait()
443  *
444  * Wait for a signal
445  * 
446  * The function waits for the arrival of one of the signals in the
447  * array of signal numbers specified by set, which must be of size
448  * equal to size. If there is a signal already queued, the function
449  * returns immediately. If there is no signal of the specified set
450  * queued, the calling thread is suspended until a signal from that
451  * set arrives. Upon return, if signal_received is not NULL the number
452  * of the signal received is stored in the variable pointed to by
453  * signal_received; and if info is not NULL the associated information
454  * is stored in the variable pointed to by info.
455  *
456  * Returns 0 if successful; otherwise it returns an error code:
457  *     EINVAL: the array contains one or more values which are not
458  *             between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
459  *             is less than 0
460  *
461  * Alternatively, in case of error the implementation is allowed to
462  * notify it to the system console and then terminate the FRSH
463  * implementation and dependant applications
464  **/
465 // int fosa_signal_wait
466 //      (frsh_signal_t set[], int size, frsh_signal_t *signal_received, 
467 //       frsh_signal_info_t *info);
468
469 extern inline int fosa_signal_wait (frsh_signal_t set[], int size, frsh_signal_t *signal_received, 
470                                     frsh_signal_info_t *info){
471      int x;
472      rtl_sigset_t bitset;
473      siginfo_t __info;
474      
475      rtl_sigemptyset(bitset); // No signals to wait for;
476      for (x=0; x<size; x++)
477           rtl_sigaddset(bitset, set[x]); // Add to the set of signals to be waited for.
478      sigwaitinfo(&bitset, &__info);
479      *signal_received=__info.si_signo;
480      *info = __info.si_value.sival_ptr;
481
482 }
483
484 /**
485  * fosa_signal_timedwait()
486  *
487  * Timed wait for a signal
488  * 
489  * This function behaves the same as fosa_signal_wait(), except that
490  * the suspension time is limited to the time interval specified in
491  * the timespec structure referenced by timeout.
492  * 
493  * Returns 0 if successful; otherwise it returns an error code:
494  *     EINVAL: the array contains one or more values which are not
495  *             between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
496  *             is less than 0, or timeout is invalid
497  *     EAGAIN: The timeout expired
498  *
499  * Alternatively, in case of the EINVAL error the implementation is
500  * allowed to notify it to the system console and then terminate the
501  * FRSH implementation and dependant applications
502  **/
503 // int fosa_signal_timedwait
504 //      (frsh_signal_t set[], int size, frsh_signal_t *signal_received, 
505 //       frsh_signal_info_t *info, const struct timespec *timeout);
506
507 extern inline int fosa_signal_timedwait (frsh_signal_t set[], int size, frsh_signal_t *signal_received, 
508                                          frsh_signal_info_t *info, const struct timespec *timeout){
509      
510      
511      int x;
512      rtl_sigset_t bitset;
513      siginfo_t __info;
514      
515      rtl_sigemptyset(bitset); // No signals to wait for;
516      for (x=0; x<size; x++)
517           rtl_sigaddset(bitset, set[x]); // Add to the set of signals to be waited for.
518      
519      sigwaitinfo(&bitset, &__info);
520      *signal_received=__info.si_signo;
521      *info = __info.si_value.sival_ptr;
522 }
523
524 /*}*/
525
526
527 #endif      /* !FOSA_THREAD_AND_SIGNALS_H_ */