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 //==============================================
48 // ******** ****** ******** **********
49 // **///// /** ** **////// /** /**
50 // ** /** ** /** /** /**
51 // ******* /** ** /********* /**********
52 // **//// /** ** ////////** /**//////**
53 // ** /** ** /** /** /**
54 // ** /** ** ******** /** /**
55 // // /******/ //////// // //
57 // FOSA(Frescor Operating System Adaptation layer)
58 //================================================
60 #include <linux/unistd.h>
64 /*************************
65 * Thread identification
66 *************************/
68 bool fosa_thread_equal(fosa_thread_id_t t1, fosa_thread_id_t t2)
70 if ( pthread_equal(t1.pthread_id, t2.pthread_id &&
71 t1.linux_pid == t2.linux_pid &&
72 t1.linux_tid == t2.linux_tid) )
78 fosa_thread_id_t fosa_thread_self()
80 fosa_thread_id_t thread_self;
82 * Fill the user pointer with appropriate data for the calling thread
84 * fosa_thread_id_t => struct {
85 * pthread_t pthread_id;
90 thread_self.pthread_id = pthread_self(); /* only valid for threads! */
91 thread_self.linux_pid = getpid();
92 thread_self.linux_tid = syscall(__NR_gettid); /* equal to gettid() */
97 /*************************
98 * Thread creation and termination
99 *************************/
101 int fosa_thread_create(fosa_thread_id_t *tid,
102 const fosa_thread_attr_t *attr,
103 fosa_thread_code_t code,
108 /* 'tid' can't be used, act other ways
109 * to get the thread id of the new thread */
110 return pthread_create(&tmp_tid,attr,code, arg);
113 /**************************************************
114 * Thread-specific data
115 * (extended with access from a different thread)
117 * Several data items (pointers) may be associated with each thread
118 * Each item is identified through a key, an integer value between 0
119 * and FOSA_MAX_KEYS-1. The caller is responsible of allocating and
120 * deallocating the memory area pointed to by the pointer
121 **************************************************/
123 int fosa_thread_set_specific_data(int key,
124 fosa_thread_id_t tid,
127 //if ((key > 0) && (key < (FOSA_MAX_KEYS-1))) {
128 // tid.pthread_id->tsd[key] = (void *) value;
137 int fosa_thread_get_specific_data(int key,
138 fosa_thread_id_t tid,
141 //if ((key > 0) && (key < (FOSA_MAX_KEYS-1))) {
142 // *value=pthread_remote_getspecific(key,tid);
143 // *value=tid.pthread_id->tsd[key];
153 /******************************************************************
156 * This implementation of FRSH assumes an underlying fixed priority
157 * scheduler with priorities in a range, with a minimum and a
158 * maximumm, a number of priority levels with at least 31
159 * priorities. A larger number implies a larger priority. In systems
160 * in which the underlying scheduler uses the opposite convention, a
161 * mapping is automatically provided by the OS adaptation layer.
162 *******************************************************************/
164 int fosa_get_priority_max() {
165 return sched_get_priority_max(0);
168 int fosa_get_priority_min() {
169 return sched_get_priority_min(0);
172 int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
174 //if ((sched_get_priority_min(0)<=prio) || (prio<=sched_get_priority_min(0))) {
175 // attr->sched_param.sched_priority = prio;
184 int fosa_thread_attr_get_prio (const fosa_thread_attr_t *attr, int *prio)
186 //*prio = attr->sched_param.sched_priority;
193 int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
195 //if ((sched_get_priority_min(0)<=prio) || (prio<=sched_get_priority_min(0))) {
196 // pthread_setschedprio(tid.pthread_id,prio);
204 int fosa_thread_get_prio (fosa_thread_id_t tid, int *prio)
206 //*prio = tid.pthread_id->sched_param.sched_priority;
213 /*******************************************************************
216 * Signals represent events that may be notified by the system, or
217 * sent explicitly by the application, and for which a thread may
218 * synchronously wait. Signals carry an associated piece of
219 * information (an integer or a pointer) and are queued until they are
220 * accepted. Signals are identified by an integer signal number (of
221 * the type fosa_signal_t) in the range FOSA_SIGNAL_MIN,
222 * FOSA_SIGNAL_MAX. This range is required to have at least <tbd>
224 *******************************************************************/
226 /* it's an hack and it does not work!
227 * We need to change the API if we want such a feature!!*/
228 sigset_t original_mask;
230 int fosa_set_accepted_signals(fosa_signal_t set[], int size)
235 /* all signal blocked by default */
236 sigfillset(&new_mask);
237 for (x = 0; x < size; x++)
238 /* unblock only the signals in 'set' */
239 sigdelset(&new_mask, set[x]);
241 /* NB. save the original mask in the
242 * default variable... Orrible hack!! :-( */
243 return pthread_sigmask(SIG_SETMASK, &new_mask, &original_mask);
246 int fosa_signal_queue(fosa_signal_t signal,
247 fosa_signal_info_t info,
248 fosa_thread_id_t receiver)
250 union sigval siginfo;
252 siginfo.sival_int = info.sival_int;
253 return sigqueue(receiver.linux_pid, signal, siginfo);
256 int fosa_signal_wait (fosa_signal_t set[],
258 fosa_signal_t *signal_received,
259 fosa_signal_info_t *info)
263 siginfo_t recv_signal_info;
265 /* only wait for the signals in 'set' */
266 sigemptyset(&wait_mask);
267 for (x = 0; x < size; x++)
268 sigaddset(&wait_mask, set[x]);
269 /* go to sleep and let's hope someone wake up us !! */
270 if (sigwaitinfo(&wait_mask, &recv_signal_info) < 0)
272 /* return back informations for the caller */
273 *signal_received = recv_signal_info.si_signo;
274 info->sival_int = recv_signal_info.si_value.sival_int;
275 /* reset the signal mask to original one (orrible hack!!) */
276 pthread_sigmask(SIG_SETMASK, &original_mask, NULL);
281 int fosa_signal_timedwait(fosa_signal_t set[],
283 fosa_signal_t *signal_received,
284 fosa_signal_info_t *info,
285 const struct timespec *timeout)
289 siginfo_t recv_signal_info;
291 /* only wait for the signals in 'set' */
292 sigemptyset(&wait_mask);
293 for (x = 0; x < size; x++)
294 sigaddset(&wait_mask, set[x]);
295 /* go to sleep and let's hope someone wake up us !! */
296 if (sigtimedwait(&wait_mask, &recv_signal_info, timeout) < 0)
298 /* return back informations for the caller */
299 if (signal_received != NULL)
300 *signal_received = recv_signal_info.si_signo;
302 info->sival_int = recv_signal_info.si_value.sival_int;
303 /* reset the signal mask to original one (orrible hack!!) */
304 pthread_sigmask(SIG_SETMASK, &original_mask, NULL);