1 #include "fosa_app_def_sched.h"
2 #include "fosa_threads_and_signals.h"
3 #include "fosa_mutexes_and_condvars.h"
4 #include "fosa_clocks_and_timers.h"
5 #include <stdio.h> // for printf
6 #include <string.h> // for strlen, strncpy
7 #include <unistd.h> // for sleep
8 #include <time.h> // for nanosleep
9 #include <misc/assert.h> // for assert
10 #include <misc/load.h> // for adjust, eat
12 // linux_lib doesn't have panic
13 // ----------------------------
14 // #include <stdlib.h>
15 // void panic(const char *fmt, ...)
17 // printf("%s \n", fmt);
21 ///////////////////////////////////////////////////////
22 // 0) Function prototypes
23 ///////////////////////////////////////////////////////
25 static void *thread_code(void *arg);
27 static void frsh_callback_init
28 (void *sched_data, void *arg);
30 static void frsh_callback_new_thread
32 frsh_thread_id_t thread,
33 fosa_ads_actions_t *actions,
34 struct timespec *current_time);
36 static void frsh_callback_thread_terminate
38 frsh_thread_id_t thread,
39 fosa_ads_actions_t *actions,
40 struct timespec *current_time);
42 static void frsh_callback_thread_ready
44 frsh_thread_id_t thread,
45 fosa_ads_actions_t *actions,
46 struct timespec *current_time);
48 static void frsh_callback_thread_block
50 frsh_thread_id_t thread,
51 fosa_ads_actions_t *actions,
52 struct timespec *current_time);
54 static void frsh_callback_change_sched_param_thread
56 frsh_thread_id_t thread,
57 fosa_ads_actions_t *actions,
58 struct timespec *current_time);
60 static void frsh_callback_explicit_call_with_data
62 frsh_thread_id_t thread,
67 fosa_ads_actions_t *actions,
68 struct timespec *current_time);
70 static void frsh_callback_notification_for_thread
72 frsh_thread_id_t thread,
73 fosa_clock_id_t clock,
74 fosa_ads_actions_t *actions,
75 struct timespec *current_time);
77 static void frsh_callback_timeout
79 fosa_ads_actions_t *actions,
80 struct timespec *current_time);
82 static void frsh_callback_signal
85 frsh_signal_info_t siginfo,
86 fosa_ads_actions_t *actions,
87 struct timespec *current_time);
89 static void frsh_callback_appsched_error
91 frsh_thread_id_t thread,
92 fosa_ads_error_cause_t cause,
93 fosa_ads_actions_t *actions);
95 ///////////////////////////////////////////////////////
96 // 1) Types, Module variables and Constants
97 ///////////////////////////////////////////////////////
99 static fosa_ads_scheduler_ops_t scheduler_ops = {
100 .init = frsh_callback_init,
101 .new_thread = frsh_callback_new_thread,
102 .thread_terminate = frsh_callback_thread_terminate,
103 .thread_ready = frsh_callback_thread_ready,
104 .thread_block = frsh_callback_thread_block,
105 .change_sched_param_thread = frsh_callback_change_sched_param_thread,
106 .explicit_call_with_data = frsh_callback_explicit_call_with_data,
107 .notification_for_thread = frsh_callback_notification_for_thread,
108 .timeout = frsh_callback_timeout,
109 .signal = frsh_callback_signal,
110 .appsched_error = frsh_callback_appsched_error,
113 static frsh_mutex_t lock;
115 const unsigned int MX_INIT_ARGS_STRING = 30;
116 const unsigned int MX_PRIO = 20;
119 // general control structure for the scheduler
121 fosa_ads_urgency_t array_prio[MX_THREADS];
122 int array_status[MX_THREADS];
126 fosa_ads_urgency_t prio;
135 frsh_thread_id_t thread_id;
139 ///////////////////////////////////////////////////////
141 ///////////////////////////////////////////////////////
146 char init_args_string[MX_INIT_ARGS_STRING + 1];
147 frsh_thread_id_t tid1, tid2, tid3;
148 frsh_thread_attr_t th_attr;
150 appsched_params_t params;
151 frsh_signal_info_t timer_info;
152 fosa_timer_id_t timerid;
153 struct timespec timerval;
154 signal_action_t signal_action;
156 adjust(); // for function eat
158 err = fosa_mutex_init(&lock, MX_PRIO);
159 printf("mutex initialized with ceiling %d. err=%d\n", MX_PRIO, err);
162 //////////////////////////////////
163 // 2a) Create the scheduler
164 //////////////////////////////////
166 printf("--------------------------------------------------\n");
167 printf("2a) Create the scheduler\n");
169 strncpy(init_args_string, "Hello Scheduler!!", MX_INIT_ARGS_STRING);
170 init_args_string[MX_INIT_ARGS_STRING] = '\0';
172 err = fosa_ads_scheduler_create
174 sizeof(frsh_sched_data_t),
175 init_args_string, // INIT IS CALLED INMEDIATELY??!!!
176 strlen(init_args_string) + 1);
177 printf("scheduler created, err=%d\n", err);
180 //////////////////////////////////////////////////////////////
181 // 2b) Create two application scheduled threads
182 //////////////////////////////////////////////////////////////
184 printf("--------------------------------------------------\n");
185 printf("2b) Create two application scheduled threads\n");
187 err = frsh_thread_attr_init(&th_attr);
188 printf("thread attributes object initialized, err=%d\n", err);
191 err = frsh_thread_attr_set_stacksize(&th_attr,40000);
192 printf("thread attr set stack size to 40000, err=%d\n", err);
195 err = fosa_thread_attr_set_prio(&th_attr, MX_PRIO - 1);
196 printf("thread attr set prio to 10, err=%d\n",err);
199 err = fosa_thread_attr_set_appscheduled(&th_attr, true);
200 printf("thread attr set appscheduled, err=%d\n", err);
203 err = fosa_thread_attr_get_appscheduled(&th_attr, &is_appsched);
204 printf("thread attr get appscheduled=%d, err=%d\n",is_appsched, err);
208 err = fosa_thread_attr_set_appsched_params
209 (&th_attr, (void *)¶ms, sizeof(params));
210 printf("thread attr set params prio=%d, err=%d\n", params.prio, err);
214 err = fosa_thread_create (&tid1, &th_attr, thread_code, (void *)1);
215 printf("creating thread 1 with prio=%d, err=%d\n", params.prio, err);
219 err = fosa_thread_attr_set_appsched_params
220 (&th_attr, (void *)¶ms, sizeof(params));
221 printf("thread attr set params prio=%d, err=%d\n", params.prio, err);
225 err = fosa_thread_create (&tid2, &th_attr, thread_code, (void *)2);
226 printf("creating thread 2 with prio=%d, err=%d\n",params.prio, err);
229 err = frsh_thread_attr_destroy(&th_attr);
230 printf("thread attributes object destroyed, err=%d\n",err);
233 // create thread 3 - should be rejected
234 err = fosa_thread_create (&tid3, &th_attr, thread_code, (void *)3);
235 printf("creating thread 3 (rejected=%d), err=%d\n",
238 err = frsh_thread_attr_destroy(&th_attr);
239 printf("thread attributes object destroyed, err=%d\n",err);
244 //////////////////////////////////////////////////////////////
245 // 2c) Change appsched params
246 //////////////////////////////////////////////////////////////
247 printf("--------------------------------------------------\n");
248 printf("2c) Change appsched params\n");
250 err = fosa_thread_set_prio(tid1,14);
251 printf("priority of thread 1 set to 14, err=%d\n", err);
256 params.prio = MX_PRIO - 5;
257 err = fosa_ads_set_appsched_params(tid2, (void *)¶ms, sizeof(params));
258 printf("urgency of thread 2 set to %d, err=%d\n", params.prio, err);
263 //////////////////////////////////////////////////////////////
264 // 2d) Dettach from application scheduler
265 //////////////////////////////////////////////////////////////
266 printf("--------------------------------------------------\n");
267 printf("2d) Dettach from application scheduler\n");
269 err = fosa_ads_set_appscheduled (tid1, false);
270 printf("dettach thread 1, err=%d\n", err);
273 err = fosa_ads_set_appscheduled (tid2, false);
274 printf("dettach thread 2, err=%d\n", err);
277 err = fosa_ads_get_appscheduled (tid1, &is_appsched);
278 printf("thread 1 is dettached? %d, err=%d\n", is_appsched, err);
281 err = fosa_ads_get_appscheduled (tid2, &is_appsched);
282 printf("thread 2 is dettached? %d, err=%d\n", is_appsched, err);
285 signal_action.command = SUSPEND;
286 signal_action.thread_id = tid1;
287 timer_info.sival_ptr = (void *)&signal_action;
289 err = fosa_timer_create
290 (FOSA_CLOCK_REALTIME, FOSA_SIGNAL_MAX, timer_info, &timerid);
291 printf("timer created, err=%d\n", err);
295 timerval.tv_nsec = 500000000;
297 err=fosa_timer_arm(timerid, false, &timerval);
298 printf("suspend thread 1 in 0.5 secs, err=%d\n", err);
303 signal_action.command = ACTIVATE;
304 err=fosa_timer_arm(timerid, false, &timerval);
305 printf("activate thread 1 in 0.5 secs, err=%d\n", err);
308 fosa_timer_delete(timerid);
314 ///////////////////////////////////////////////////////
316 ///////////////////////////////////////////////////////
318 static void *thread_code (void * arg)
320 struct timespec ts = {5, 0};
322 char whoami[] = "who am i?";
325 printf("Thread %d starts\n", (int)arg);
327 nanosleep (&ts, NULL);
331 err=fosa_mutex_lock(&lock);
332 printf("mutex locked by %d. err=%d\n", (int)arg, err);
337 err=fosa_mutex_unlock(&lock);
338 printf("mutex unlocked %d. err=%d\n", (int)arg, err);
341 err = fosa_ads_invoke_withdata
342 (whoami, sizeof(whoami), (void *)&reply, NULL);
343 printf("who am I, correct?: %d, err=%d\n", reply == (int)arg, err);
351 ///////////////////////////////////////////////////////
352 // 4) Implementation of Application Defined Callbacks
353 ///////////////////////////////////////////////////////
354 static void frsh_callback_init
355 (void *sched_data, void *arg)
357 frsh_sched_data_t *frsh = (frsh_sched_data_t *)sched_data;
359 frsh_signal_t sched_signal = FOSA_SIGNAL_MAX; // HOW TO PUT SIGNALS IF IS OPAQUE??
361 printf ("CALLBACK: %s \n", __func__);
362 printf ("Init args string received: %s \n", (char *)arg);
364 err = fosa_ads_set_handled_signal_set(&sched_signal, 1);
365 printf("set signal set, err=%d\n", err);
368 for (i=0; i<MX_THREADS; i++) {
369 frsh->array_prio[i] = 0;
370 frsh->array_status[i] = 0;
374 static void frsh_callback_new_thread
376 frsh_thread_id_t thread,
377 fosa_ads_actions_t *actions,
378 struct timespec *current_time)
381 unsigned int i, index;
382 frsh_sched_data_t *frsh = (frsh_sched_data_t *)sched_data;
383 appsched_params_t params;
385 printf ("CALLBACK: %s \n", __func__);
388 for (i=0; i<MX_THREADS; i++) {
389 if (frsh->array_status[i] == 0) {
395 if (index == MX_THREADS) {
396 err = fosa_adsactions_add_reject(actions, thread);
399 // Get the priority for the new thread (NULL is possible?)
400 err = fosa_ads_get_appsched_params(thread, (void *)¶ms, NULL);
403 frsh->array_prio[index] = params.prio;
404 frsh->array_status[index] = 1;
406 err = fosa_adsactions_add_activate(actions, thread, params.prio);
411 static void frsh_callback_thread_terminate
413 frsh_thread_id_t thread,
414 fosa_ads_actions_t *actions,
415 struct timespec *current_time)
417 struct timespec at_time;
420 printf ("CALLBACK: %s \n", __func__);
422 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &at_time);
423 printf("current time sec=%d nsec=%d\n", at_time.tv_sec, at_time.tv_nsec);
424 at_time.tv_sec = at_time.tv_sec + 1;
426 err = fosa_adsactions_add_timeout(actions, FOSA_CLOCK_REALTIME, &at_time);
427 printf("put a timeout of one second, err=%d\n", err);
431 static void frsh_callback_thread_ready
433 frsh_thread_id_t thread,
434 fosa_ads_actions_t *actions,
435 struct timespec *current_time)
437 printf ("CALLBACK: %s \n", __func__);
440 static void frsh_callback_thread_block
442 frsh_thread_id_t thread,
443 fosa_ads_actions_t *actions,
444 struct timespec *current_time)
447 struct timespec at_time;
449 printf ("CALLBACK: %s \n", __func__);
451 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &at_time);
452 printf("current time sec=%d nsec=%d\n", at_time.tv_sec, at_time.tv_nsec);
453 at_time.tv_sec = at_time.tv_sec + 1;
455 err = fosa_adsactions_add_timeout(actions, FOSA_CLOCK_REALTIME, &at_time);
456 printf("put a timeout of one second, err=%d\n", err);
460 static void frsh_callback_change_sched_param_thread
462 frsh_thread_id_t thread,
463 fosa_ads_actions_t *actions,
464 struct timespec *current_time)
466 printf ("CALLBACK: %s \n", __func__);
467 // HOW DO I KNOW THE REASON IS SETPRIO OR SETSCHEDPARAMS????
470 static void frsh_callback_explicit_call_with_data
472 frsh_thread_id_t thread,
477 fosa_ads_actions_t *actions,
478 struct timespec *current_time)
480 printf ("CALLBACK: %s \n", __func__);
481 printf ("received command: %s \n", (char *)msg);
482 *((int *)reply) = (int)thread;
485 static void frsh_callback_notification_for_thread
487 frsh_thread_id_t thread,
488 fosa_clock_id_t clock,
489 fosa_ads_actions_t *actions,
490 struct timespec *current_time)
492 printf ("CALLBACK: %s \n", __func__);
495 static void frsh_callback_timeout // WHY NOT WATCHDOG????
497 fosa_ads_actions_t *actions,
498 struct timespec *current_time) // WHY IS IN OUT and not IN???
500 printf ("CALLBACK: %s \n", __func__);
501 printf("current time sec=%d nsec=%d\n",
502 current_time->tv_sec, current_time->tv_nsec);
505 static void frsh_callback_signal
507 frsh_signal_t signal,
508 frsh_signal_info_t siginfo, // HOW DO I KNOW THE ORIGIN (see signal_info type)
509 fosa_ads_actions_t *actions,
510 struct timespec *current_time)
513 signal_action_t *signal_action = (signal_action_t *)siginfo.sival_ptr;
514 frsh_sched_data_t *frsh = (frsh_sched_data_t *)sched_data;
516 printf ("CALLBACK: %s \n", __func__);
518 if (signal_action->command == SUSPEND) {
519 err = fosa_adsactions_add_suspend(actions, signal_action->thread_id);
520 printf("suspending thread 1 , err=%d\n", err);
523 err = fosa_adsactions_add_activate
524 (actions, signal_action->thread_id, frsh->array_prio[0]);
525 printf("activating thread 1, err=%d\n", err);
530 static void frsh_callback_appsched_error
532 frsh_thread_id_t thread,
533 fosa_ads_error_cause_t cause,
534 fosa_ads_actions_t *actions)
536 printf ("CALLBACK: %s \n", __func__);