1 // -----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2007 FRESCOR consortium partners:
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
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org for a link to partners' websites
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
23 // This file is part of the FRSH implementation
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)
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.
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
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
46 // -----------------------------------------------------------------------
47 //fosa_thread_and_signals.h
48 //==============================================
49 // ******** ****** ******** **********
50 // **///// /** ** **////// /** /**
51 // ** /** ** /** /** /**
52 // ******* /** ** /********* /**********
53 // **//// /** ** ////////** /**//////**
54 // ** /** ** /** /** /**
55 // ** /** ** ******** /** /**
56 // // /******/ //////// // //
58 // FOSA(Frescor Operating System Adaptation layer)
59 //================================================
62 #ifndef FOSA_THREAD_AND_SIGNALS_H_
63 #define FOSA_THREAD_AND_SIGNALS_H_
66 * @defgroup threadandsignals Thread and Signals
69 * This module defines the functions that manipulate frsh_threads and
70 * frsh_signals inside FRSH implementation.
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().
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.
84 /*************************
85 * Thread identification
86 *************************/
91 * Compare two thread identifiers to determine if they refer to the
94 //bool fosa_thread_equal(frsh_thread_id_t t1, frsh_thread_id_t t2);
96 extern inline bool fosa_thread_equal(frsh_thread_id_t t1, frsh_thread_id_t t2){
97 return pthread_equal(t1,t2);
104 * Return the thread id of the calling thread
106 //frsh_thread_id_t fosa_thread_self();
108 extern inline frsh_thread_id_t fosa_thread_self(){
109 retrun pthread_self();
112 /*************************
113 * Thread creation and termination
114 *************************/
117 * fosa_thread_create()
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.
127 * Returns 0 if successful; otherwise it returs a code error:
129 * EAGAIN: the system lacks the necessary resources to create a
130 * new thread or the maximum number of threads has been
133 * EINVAL: the value specified by attr is invalid (for instance,
134 * it has not been correctly initialized)
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
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);
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);
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
158 /**************************************************
159 * Thread-specific data
160 * (extended with access from a different thread)
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 **************************************************/
169 * fosa_thread_set_specific_data()
171 * Set thread-specific data
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
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
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
183 // int fosa_thread_set_specific_data
184 // (int key, frsh_thread_id_t tid, const void * value);
186 extern inline int fosa_thread_set_specific_data (int key, frsh_thread_id_t tid,
188 if ((0<key) && (key<FOSA_MAX_KEYS-1)){
189 pthread_setspecific_for(key, tid, value);
196 * fosa_thread_get_specific_data()
198 * Get thread-specific data
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
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
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
210 //int fosa_thread_get_specific_data(int key, frsh_thread_id_t tid,
214 extern int fosa_thread_get_specific_data(int key, frsh_thread_id_t tid,
216 if ((0<key) && (key<FOSA_MAX_KEYS-1)){
217 *value=pthread_remote_getspecific(key,tid);
225 /******************************************************************
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 *******************************************************************/
237 * fosa_get_priority_max()
239 * Return the maximum priority value used in this implementation
241 //int fosa_get_priority_max();
242 extern inline int fosa_get_priority_max() {
243 return sched_get_priority_max(0);
247 * fosa_get_priority_min()
249 * Return the minimum priority value used in this implementation
251 //int fosa_get_priority_min();
253 extern inline int fosa_get_priority_min(){
254 return sched_get_priority_min(0);
259 * fosa_thread_attr_set_prio()
261 * Change the priority of a thread attributes object
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
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
277 // int fosa_thread_attr_set_prio(frsh_thread_attr_t *attr, int prio);
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;
290 * fosa_thread_attr_get_prio()
292 * Get the priority from a thread attributes object
294 * This function sets the variable pointed to by prio to the
295 * priority stored in the thread attributes object attr.
299 // int fosa_thread_attr_get_prio
300 // (const frsh_thread_attr_t *attr, size_t *prio);
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;
308 * fosa_thread_set_prio()
310 * Dynamically change the priority of a thread
312 * The priority of the thread identified by tid is
313 * set to the value specified by prio.
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
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);
335 * fosa_thread_get_prio()
337 * Dynamically get the priority of a thread
339 * This function sets the variable pointed to by prio to the
340 * priority of the thread identified by tid
344 int fosa_thread_get_prio (frsh_thread_id_t tid, int *prio);
346 extern inline int fosa_thread_get_prio (frsh_thread_id_t tid, int *prio){
347 *prio = tid->sched_param.sched_priority;
353 /*******************************************************************
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>
364 *******************************************************************/
367 * fosa_set_accepted_signals()
369 * Establish the set of signals that may be synchronously accepted
370 * by the calling thread
372 * The function uses the array of signal numbers specified by set,
373 * which must be of size equal to size
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
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
384 //int fosa_set_accepted_signals(frsh_signal_t set[], int size);
387 extern inline int fosa_set_accepted_signals(frsh_signal_t set[], int size) {
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.
395 return pthread_sigmask(SIG_SETMASK, bitmask, NULL);
401 * fosa_signal_queue()
405 * This function is used to explicitly send a signal with a specified
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.
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
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
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
428 // int fosa_signal_queue
429 // (frsh_signal_t signal, frsh_signal_info_t info,
430 // frsh_thread_id_t receiver);
432 extern inline int fosa_signal_queue (frsh_signal_t signal, frsh_signal_info_t info,
433 frsh_thread_id_t receiver){
436 value.sival_ptr=info;
437 return sigqueue(0, signal, value);
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.
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
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
465 // int fosa_signal_wait
466 // (frsh_signal_t set[], int size, frsh_signal_t *signal_received,
467 // frsh_signal_info_t *info);
469 extern inline int fosa_signal_wait (frsh_signal_t set[], int size, frsh_signal_t *signal_received,
470 frsh_signal_info_t *info){
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;
485 * fosa_signal_timedwait()
487 * Timed wait for a signal
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.
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
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
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);
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){
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.
519 sigwaitinfo(&bitset, &__info);
520 *signal_received=__info.si_signo;
521 *info = __info.si_value.sival_ptr;
527 #endif /* !FOSA_THREAD_AND_SIGNALS_H_ */