1 // -----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2009 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. Politécnica 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
24 // based on previous work (FSF) done in the FIRST project
26 // Copyright (C) 2005 Mälardalen University, SWEDEN
27 // Scuola Superiore S.Anna, ITALY
28 // Universidad de Cantabria, SPAIN
29 // University of York, UK
31 // FSF API web pages: http://marte.unican.es/fsf/docs
32 // http://shark.sssup.it/contrib/first/docs/
34 // This file is part of FOSA (Frsh Operating System Adaption)
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.
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 // -----------------------------------------------------------------------
57 * Vicent Brocal <vibrotor@ai2.upv.es>:
58 * Minor modifications to adapt the code to test the implementation of
59 * group clocks for PaRTiKle.
66 #include <stdlib.h> // for exit in assert
67 #include <string.h> // for memset
72 /*****************************/
73 /* D E F I N I T I O N S */
74 /*****************************/
75 #define RT_ERROR_SIGWAIT -2
76 #define RT_ERROR_TIMER -3
78 #define SIGNAL_TIMER (FOSA_SIGNAL_MAX - 1)
80 #define SIGNAL_A (FOSA_SIGNAL_MAX - 2)
81 #define SIGNAL_KILL_A (FOSA_SIGNAL_MAX - 3)
83 #define SIGNAL_B (FOSA_SIGNAL_MAX - 4)
84 #define SIGNAL_KILL_B (FOSA_SIGNAL_MAX - 5)
85 #define SIGNAL_C (FOSA_SIGNAL_MAX - 6)
86 #define SIGNAL_KILL_C (FOSA_SIGNAL_MAX - 7)
93 #define PRIO_CATCHER 8
96 typedef struct _my_signal_info_t
98 fosa_rel_time_t eat_time;
101 typedef struct _my_thread_arg_t
103 char identifier[100];
104 fosa_signal_t signum;
105 fosa_signal_t sigkill;
111 /***************************/
112 /* P R O T O T Y P E S */
113 /***************************/
114 static void *controlled_thread(void *thread_arg);
115 static void *catcher_thread(void *arg);
117 static void create_thread(fosa_thread_code_t thread_code,
120 fosa_thread_id_t *tid);
122 static void time_printf(const char *format, ...);
125 /***************************/
126 /* S T A T I C D A T A */
127 /***************************/
128 static fosa_abs_time_t start_time;
129 static bool timer_expired;
131 fosa_clock_id_t group_clock_id;
137 fosa_thread_id_t tid_A, tid_B, tid_C, tid_catcher;
138 my_thread_arg_t thread_arg_A, thread_arg_B, thread_arg_C;
139 fosa_rel_time_t eat_time_A, eat_time_B, eat_time_C, group_time;
140 fosa_signal_info_t siginfo_A, siginfo_B, siginfo_C, siginfo_timer;
142 fosa_thread_set_id_t thread_set_id;
143 fosa_timer_id_t group_timer;
145 /* Initialize base time and thread arguments */
146 /*********************************************/
147 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &start_time);
149 strcpy(thread_arg_A.identifier, "THREAD A");
150 thread_arg_A.signum = SIGNAL_A;
151 thread_arg_A.sigkill = SIGNAL_KILL_A;
152 siginfo_A.sival_ptr = &eat_time_A;
154 strcpy(thread_arg_B.identifier, "THREAD B");
155 thread_arg_B.signum = SIGNAL_B;
156 thread_arg_B.sigkill = SIGNAL_KILL_B;
157 siginfo_B.sival_ptr = &eat_time_B;
159 strcpy(thread_arg_C.identifier, "THREAD C");
160 thread_arg_C.signum = SIGNAL_C;
161 thread_arg_C.sigkill = SIGNAL_KILL_C;
162 siginfo_C.sival_ptr = &eat_time_C;
165 /* We set our priority and create the threads. The threads */
166 /* will be blocked waiting for the signal. */
167 /************************************************************/
168 err = fosa_thread_set_prio(fosa_thread_self(), fosa_get_priority_min() + PRIO_MAIN);
171 printf("MAIN: Error %d with setting main priority\n", err);
175 create_thread(controlled_thread, &thread_arg_A, PRIO_A, &tid_A);
176 create_thread(controlled_thread, &thread_arg_B, PRIO_B, &tid_B);
177 create_thread(controlled_thread, &thread_arg_C, PRIO_C, &tid_C);
179 create_thread(catcher_thread, NULL, PRIO_CATCHER, &tid_catcher);
182 /* We create the thread set, get its clock and create a timer */
183 /****************************************************************/
184 err = fosa_thread_set_create(&thread_set_id);
187 printf("MAIN: Error %d creating thread_set\n", err);
191 err = fosa_get_groupcpu_clock(thread_set_id, &group_clock_id);
194 printf("MAIN: Error %d obtaining group clock\n", err);
198 err = fosa_timer_create(group_clock_id, SIGNAL_TIMER, siginfo_timer, &group_timer);
201 printf("MAIN: Error %d obtaining group CPU timer\n", err);
205 /* We add the 3 threads to the set */
206 /*************************************/
207 err = fosa_thread_set_add(thread_set_id, tid_A);
210 printf("MAIN: Error %d adding thread to thread set\n", err);
214 err = fosa_thread_set_add(thread_set_id, tid_B);
217 printf("MAIN: Error %d adding thread to thread set\n", err);
221 err = fosa_thread_set_add(thread_set_id, tid_C);
224 printf("MAIN: Error %d adding thread to thread set\n", err);
229 /* First experiment: We arm the group CPU timer with 5 sec and */
230 /* make each thread execute two seconds each. */
231 /****************************************************************/
232 eat_time_A = fosa_msec_to_rel_time(2000);
233 eat_time_B = fosa_msec_to_rel_time(2000);
234 eat_time_C = fosa_msec_to_rel_time(2000);
236 group_time = fosa_msec_to_rel_time(5000);
238 timer_expired = false;
239 time_printf("MAIN: Arming group timer for 5 seconds\n");
240 err = fosa_rel_timer_arm(group_timer, &group_time);
243 printf("MAIN: Error %d queueing signal\n", err);
247 err = fosa_signal_queue(SIGNAL_A, siginfo_A, (fosa_thread_id_t) 0);
250 printf("MAIN: Error %d queueing signal\n", err);
254 err = fosa_signal_queue(SIGNAL_B, siginfo_B, (fosa_thread_id_t) 0);
257 printf("MAIN: Error %d queueing signal\n", err);
261 err = fosa_signal_queue(SIGNAL_C, siginfo_C, (fosa_thread_id_t) 0);
264 printf("MAIN: Error %d queueing signal\n", err);
268 struct timespec t = {2,0};
269 nanosleep (&t, NULL);
270 time_printf("MAIN: Back after all threads\n");
272 assert(timer_expired);
282 // ----------------------------------------------------------------
285 * This is a controlled thread. It stays waiting for a signal and
286 * then eats the requested time sent in the signal info.
288 static void *controlled_thread(void *arg)
291 fosa_signal_t signal_set[2];
294 my_thread_arg_t *thread_arg = (my_thread_arg_t *) arg;
296 time_printf("%s: Initializing\n", thread_arg->identifier);
298 signal_set[0] = thread_arg->signum;
299 signal_set[1] = thread_arg->sigkill;
300 err = fosa_set_accepted_signals(signal_set, 2);
303 printf ("%s: Error %d while setting the signal mask\n", thread_arg->identifier, err);
309 fosa_signal_t signal_received;
310 fosa_signal_info_t info_received;
311 my_signal_info_t *signal_info;
313 err = fosa_signal_wait(signal_set, 2, &signal_received, &info_received);
316 printf("%s: Error %d while waiting for signal\n", thread_arg->identifier, err);
320 if (signal_received == thread_arg->sigkill)
322 time_printf("%s: Terminating\n", thread_arg->identifier);
326 signal_info = (my_signal_info_t *) info_received.sival_ptr;
328 time_printf("%s: about to eat %ld msec\n", thread_arg->identifier, fosa_rel_time_to_msec(signal_info->eat_time) );
330 fosa_eat(&signal_info->eat_time);
336 // ------------------------------------------------------------------
338 static void *catcher_thread(void *arg)
341 fosa_signal_t signal_set[1];
343 time_printf("CATCHER: Initializing\n");
345 signal_set[0] = SIGNAL_TIMER;
346 err = fosa_set_accepted_signals(signal_set, 1);
349 printf ("CATCHER: Error %d while setting the signal mask\n", err);
355 fosa_signal_t signal_received;
356 fosa_signal_info_t info_received;
358 err = fosa_signal_wait(signal_set, 1, &signal_received, &info_received);
361 printf("CATCHER: Error %d while waiting for signal\n", err);
365 time_printf("CATCHER: Group timer expired!!!\n");
366 timer_expired = true;
373 // ------------------------------------------------------------------------
375 static void create_thread(fosa_thread_code_t thread_code,
378 fosa_thread_id_t *tid)
380 fosa_thread_attr_t attr;
383 err = fosa_thread_attr_init(&attr);
385 printf("Error %d while initializing the attr\n", err);
389 err = fosa_thread_attr_set_prio(&attr, fosa_get_priority_min() + priority);
391 printf("Error %d while setting priority\n", err);
395 err = fosa_thread_create(tid, &attr, thread_code, arg);
397 printf("Error %d in fosa_thread_create\n", err);
404 // ------------------------------------------------------------------------
407 static void time_printf(const char *format, ...)
411 fosa_abs_time_t current_time;
412 fosa_rel_time_t interval;
414 fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
415 interval = fosa_abs_time_extract_interval(start_time, current_time);
417 printf("%ld:", fosa_rel_time_to_msec(interval));
419 va_start(args, format);
420 vprintf(format, args);