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 // -----------------------------------------------------------------------
41 //fosa_app_def_sched.h
42 //==============================================
43 // ******** ****** ******** **********
44 // **///// /** ** **////// /** /**
45 // ** /** ** /** /** /**
46 // ******* /** ** /********* /**********
47 // **//// /** ** ////////** /**//////**
48 // ** /** ** /** /** /**
49 // ** /** ** ******** /** /**
50 // // /******/ //////// // //
52 // FOSA(Frescor Operating System Adaptation layer)
53 //================================================
55 #include "fosa_app_def_sched.h"
56 #include "fosa_configuration_parameters.h"
64 #include <misc/error_checks.h>
66 /********************************
67 * Application-defined scheduling
68 ********************************/
71 * We make the following ASSUMPTIONS:
73 * - The ADS always executes in the user memory space, so we don't
74 * need to manage the memory space translation.
76 * - Only one application scheduler exists, so we don't need an
82 * Data structures for the scheduler thread
85 struct scheduler_thread_data {
86 fosa_ads_scheduler_ops_t scheduler_ops;
88 size_t scheduler_data_size;
89 void * scheduler_data;
91 size_t init_args_size;
94 static struct scheduler_thread_data schedthreaddata;
95 static pthread_t scheduler_thread_id;
98 * Code of application-defined thread. The current version of MaRTE OS
99 * requires a thread to perform the scheduler actions.
100 * In the future it is expected that this thread will not be necessary.
102 void * scheduler_thread_code(void *arg) {
103 posix_appsched_actions_t sched_actions;
104 struct scheduler_thread_data *schedthreaddata=
105 (struct scheduler_thread_data *) arg;
107 //schedthreaddata->scheduler_ops(
112 * fosa_ads_scheduler_create()
114 * Create the application defined scheduler
116 * The application defined scheduler is created with the primitive
117 * operations specified in the object pointed to by scheduler_ops.
119 * The clock used to read the time immediately before the invocation
120 * of each primitive operation, to be reported to the scheduler via
121 * the current_time parameter of each primitive operation is the
122 * FOSA_CLOCK_REALTIME clock.
124 * The scheduler_data_size parameter is used to request that a memory
125 * area of this size must be created and reserved for the scheduler to
126 * store its state. A pointer to this area is passed to the scheduler
127 * operations in the sched_data parameter.
129 * Parameter init_arg points to an area that contains configuration
130 * information for the scheduler. The function creates a memory area
131 * of init_arg_size bytes and copies into it the area pointed by
132 * arg. A pointer to this new created area will be passed to the
133 * primitive operation init() in its arg parameter.
135 * Returns 0 if successful; otherwise it returns an error code:
136 * EINVAL: The value of scheduler_ops was invalid
137 * EAGAIN: The system lacks enough resources to create the scheduler
139 * Alternatively, in case of error the implementation is allowed to
140 * notify it to the system console and then terminate the FRSH
141 * implementation and dependant applications
143 int fosa_ads_scheduler_create
144 (const fosa_ads_scheduler_ops_t * scheduler_ops,
145 size_t scheduler_data_size,
147 size_t init_args_size)
151 struct sched_param param;
153 // check for NULL scheduler operations
154 if (scheduler_ops==NULL) {
158 // copy arguments in scheduler data
159 schedthreaddata.scheduler_ops=*scheduler_ops;
160 schedthreaddata.scheduler_data_size=scheduler_data_size;
161 schedthreaddata.init_args=init_args;
162 schedthreaddata.init_args_size=init_args_size;
164 // create scheduler memory area
165 schedthreaddata.scheduler_data=malloc(scheduler_data_size);
166 // check malloc return ...
169 // set the attributes for the scheduler thread
170 err=pthread_attr_init(&attr);
174 CHK(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED));
175 CHK(pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED));
176 CHK(pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED));
177 CHK(pthread_attr_setschedpolicy(&attr,SCHED_FIFO));
178 param.sched_priority=sched_get_priority_max(SCHED_FIFO)-
179 FOSA_ADS_SCHEDULER_PRIO_DIFF;
180 CHK(pthread_attr_setschedparam(&attr,¶m));
181 CHK(pthread_attr_setappschedulerstate(&attr,PTHREAD_APPSCHEDULER));
182 CHK(pthread_attr_setpreemptionlevel(&attr,FOSA_ADS_SCHEDULER_LEVEL));
184 // create the scheduler thread
185 return pthread_create(&scheduler_thread_id,&attr,
186 scheduler_thread_code, &schedthreaddata);
190 * fosa_thread_attr_set_appscheduled()
192 * Set the appscheduled attribute of a thread attributes object
194 * This function is used to set the appscheduled attribute in the
195 * object pointed to by attr. This attribute controls the kind of
196 * scheduling used for threads created with it. If true, the thread is
197 * scheduled by the application scheduler. If not, it is scheduled by
198 * the system under a fixed priority scheduler
200 * Returns 0 if successful; otherwise it returns an error code:
201 * EINVAL: The value of attr is invalid
203 * Alternatively, in case of error the implementation is allowed to
204 * notify it to the system console and then terminate the FRSH
205 * implementation and dependant applications
207 int fosa_thread_attr_set_appscheduled
208 (frsh_thread_attr_t *attr,
211 return pthread_attr_setschedpolicy(attr,SCHED_APP);
215 * fosa_thread_attr_get_appscheduled()
217 * Get the appscheduled attribute of a thread attributes object
219 * This function is used to get the appscheduled attribute in the
220 * object pointed to by attr. This attribute controls the kind of
221 * scheduling used for threads created with it. If true, the thread is
222 * scheduled by the application scheduler. If not, it is scheduled by
223 * the system under a fixed priority scheduler.
225 * Returns 0 if successful; otherwise it returns an error code:
226 * EINVAL: The value of attr is invalid
228 * Alternatively, in case of error the implementation is allowed to
229 * notify it to the system console and then terminate the FRSH
230 * implementation and dependant applications
232 int fosa_thread_attr_get_appscheduled
233 (const frsh_thread_attr_t *attr,
236 int policy, ret_value;
238 ret_value=pthread_attr_getschedpolicy(attr,&policy);
240 if (policy==SCHED_APP) {
250 * fosa_thread_attr_set_appsched_params()
252 * Set the appsched_param attribute of a thread attributes object
254 * This function is used to set the appsched_param attribute in the
255 * object pointed to by attr. For those threads with appscheduled set
256 * to true, this attribute represents the application-specific
257 * scheduling parameters. If successful, the function shall set the
258 * size of the appsched_param attribute to the value specified by
259 * paramsize, and shall copy the scheduling parameters occupying
260 * paramsize bytes and pointed to by param into that attribute
262 * Returns 0 if successful; otherwise it returns an error code:
263 * EINVAL: The value of attr is invalid, or paramsize is less than
264 * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
266 * Alternatively, in case of error the implementation is allowed to
267 * notify it to the system console and then terminate the FRSH
268 * implementation and dependant applications
270 int fosa_thread_attr_set_appsched_params
271 (frsh_thread_attr_t *attr,
279 * fosa_thread_attr_get_appsched_params()
281 * Get the appsched_param attribute of a thread attributes object
283 * This function is used to get the appsched_param attribute from the
284 * object pointed to by attr. For those threads with appscheduled set
285 * to true, this attribute represents the application-specific
286 * scheduling parameters. If successful, the function shall set the
287 * value pointed to by paramsize to the size of the appsched_param
288 * attribute, and shall copy the scheduling parameters occupying
289 * paramsize bytes into the variable pointed to by param. This
290 * variable should be capable of storing a number of bytes equal to
293 * Returns 0 if successful; otherwise it returns an error code:
294 * EINVAL: The value of attr is invalid
296 * Alternatively, in case of error the implementation is allowed to
297 * notify it to the system console and then terminate the FRSH
298 * implementation and dependant applications
300 int fosa_thread_attr_get_appsched_params
301 (const frsh_thread_attr_t *attr,
309 * fosa_ads_set_appscheduled()
311 * Dynamically set the appscheduled attribute of a thread
313 * This function is used to dynamically set the appscheduled attribute
314 * of the thread identified by thread. This attribute controls the
315 * kind of scheduling used for threads created with it. If true, the
316 * thread is scheduled by the application scheduler. If not, it is
317 * scheduled by the system under a fixed priority scheduler.
319 * Returns 0 if successful; otherwise it returns an error code:
320 * EINVAL: The value of thread is invalid
322 * EREJECT: the attachment of the thread to the frsh schehduler
323 * was rejected by the frsh scheduler possibly because of
324 * incorrect attributes, or because the requested minimum
325 * capacity cannot be guaranteed
327 * Alternatively, in case of error the implementation is allowed to
328 * notify it to the system console and then terminate the FRSH
329 * implementation and dependant applications
331 int fosa_ads_set_appscheduled
332 (frsh_thread_id_t thread,
339 * fosa_ads_getappscheduled()
341 * Dynamically get the appscheduled attribute of a thread
343 * This function is used to dynamically get the appscheduled attribute
344 * of the thread identified by thread. This attribute controls the
345 * kind of scheduling used for threads created with it. If true, the
346 * thread is scheduled by the application scheduler. If not, it is
347 * scheduled by the system under a fixed priority scheduler
349 * Returns 0 if successful; otherwise it returns an error code:
350 * EINVAL: The value of thread is invalid
352 * Alternatively, in case of error the implementation is allowed to
353 * notify it to the system console and then terminate the FRSH
354 * implementation and dependant applications
356 int fosa_ads_get_appscheduled
357 (frsh_thread_id_t thread,
365 * fosa_ads_setappschedparam()
367 * Dynamically set the appsched_param attribute of a thread
369 * This function is used to dynamically set the appsched_param
370 * attribute of the thread identified by thread. For those threads
371 * with appscheduled set to true, this attribute represents the
372 * application-specific scheduling parameters. If successful, the
373 * function shall set the size of the appsched_param attribute to the
374 * value specified by paramsize, and shall copy the scheduling
375 * parameters occupying paramsize bytes and pointed to by param into
378 * Returns 0 if successful; otherwise it returns an error code:
379 * EINVAL: The value of thread is invalid, or paramsize is less than
380 * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
382 * Alternatively, in case of error the implementation is allowed to
383 * notify it to the system console and then terminate the FRSH
384 * implementation and dependant applications
386 int fosa_ads_set_appsched_params
387 (frsh_thread_id_t thread,
395 * fosa_ads_get_appsched_params()
397 * Dynamically get the appsched_param attribute of a thread
399 * This function is used to dynamically get the appsched_param
400 * attribute of the thread identified by thread. For those threads
401 * with appscheduled set to true, this attribute represents the
402 * application-specific scheduling parameters. If successful, the
403 * function shall set the variable pointed to by paramsize to the size
404 * of the appsched_param attribute, and shall copy the scheduling
405 * parameters occupying paramsize bytes into the variable pointed to
406 * by param. This variable should be capable of storing a number of
407 * bytes equal to paramsize.
409 * Returns 0 if successful; otherwise it returns an error code:
410 * EINVAL: The value of thread is invalid, or paramsize is less than
411 * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
413 * Alternatively, in case of error the implementation is allowed to
414 * notify it to the system console and then terminate the FRSH
415 * implementation and dependant applications.
417 int fosa_ads_get_appsched_params
418 (frsh_thread_id_t thread,
426 /*********************************
429 * A scheduling actions object is used to specify a series of actions
430 * to be performed by the system at the end of a scheduler primitive
431 * operation. The order of the actions added to the object shall be
434 *********************************/
437 * fosa_adsactions_add_reject()
439 * Add a reject-thread action
441 * This function adds a thread-reject action to the object referenced
442 * by sched_actions, that will serve to notify that the thread
443 * identified by thread has not been accepted by the scheduler to be
444 * scheduled by it, possibly because the thread contained invalid
445 * application scheduling attributes, or because there are not enough
446 * resources for the new thread. At the end of the new_thread()
447 * scheduler primitive operation, the parent of the rejected thread
448 * waiting on a fosa_thread_create() or the rejected thread itself
449 * waiting on a fosa_ads_set_appscheduled() function shall complete the
450 * function with an error code of EREJECT. If no reject-thread action
451 * is added during the new_thread() scheduler primitive operation, the
452 * thread is accepted to be scheduled by the scheduler and the
453 * associated fosa_thread_create() or the fosa_ads_set_appscheduled()
454 * function shall be completed without error. For the function to
455 * succeed, it has to be called from the new_thread() primitive
456 * operation and for the thread that is requesting attachment to the
459 * Returns 0 if successful; otherwise it returns an error code:
460 * ENOMEM: There is insufficient memory to add this action
461 * EPOLICY: The thread specified by thread is not the one requesting
462 * attachment to the scheduler, or the function is not being
463 * called from the new_thread primitive operation
464 * EINVAL: The value specified by sched_actions is invalid
466 * Alternatively, in case of error the implementation is allowed to
467 * notify it to the system console and then terminate the FRSH
468 * implementation and dependant applications
470 int fosa_adsactions_add_reject(
471 fosa_ads_actions_t *sched_actions,
472 frsh_thread_id_t thread)
478 * fosa_adsactions_add_activate()
480 * Add a thread-activate action
482 * This function adds a thread-activate action to the object
483 * referenced by sched_actions. In case the thread had been previously
484 * suspended via posix_appsched_actions_addsuspend(), it will be
485 * activated at the end of the primitive operation.
487 * In those implementations that do not support urgency scheduling,
488 * the urgencu value is ignored. These implementations cannot support
489 * the frsh hierarchical scheduling module.
491 * In those implementations supporting urgency-scheduling, the action
492 * will cause the change of the urgency of the thread to the value
493 * specified in the urgency argument. Besides, if the thread was
494 * already active at the time the thread-activate action is executed,
495 * the change or urgency will imply a reordering of the thread in its
496 * priority queue, so that for threads of the same priority, those
497 * with more urgency will be scheduled before those of less urgency.
499 * Returns 0 if successful; otherwise it returns an error code:
500 * ENOMEM: There is insufficient memory to add this action
501 * EPOLICY: The thread specified by thread has its appscheduled
502 * attribute set to false,
503 * EINVAL: The value specified by sched_actions is invalid
505 * Alternatively, in case of error the implementation is allowed to
506 * notify it to the system console and then terminate the FRSH
507 * implementation and dependant applications
509 int fosa_adsactions_add_activate(
510 fosa_ads_actions_t *sched_actions,
511 frsh_thread_id_t thread,
512 fosa_ads_urgency_t urgency)
518 * fosa_adsactions_add_suspend()
520 * Add a thread-suspend action
522 * This function adds a thread-suspend action to the object referenced
523 * by sched_actions, that will cause the thread identified by thread
524 * to be suspended waiting for a thread-activate action at the end of
525 * the scheduler operation. If the thread was already waiting for a
526 * thread-activate action the thread-suspend action has no effect. It
527 * is an error trying to suspend a thread that is blocked by the
530 * Returns 0 if successful; otherwise it returns an error code:
531 * ENOMEM: There is insufficient memory to add this action
532 * EPOLICY: The thread specified by thread has its appscheduled
533 * attribute set to false,
534 * EINVAL: The value specified by sched_actions is invalid
536 * Alternatively, in case of error the implementation is allowed to
537 * notify it to the system console and then terminate the FRSH
538 * implementation and dependant applications
540 int fosa_adsactions_add_suspend(
541 fosa_ads_actions_t *sched_actions,
542 frsh_thread_id_t thread)
548 * fosa_adsactions_add_timeout()
550 * Add a timeout action
552 * This function adds a timeout action to the object referenced by
553 * sched_actions, that will cause the timeout() scheduler operation to
554 * be invoked if no other scheduler operation is invoked before
555 * timeout expires. The timeout shall expire when the clock specified by
556 * clock_id reaches the absolute time specified by the at_time
559 * Returns 0 if successful; otherwise it returns an error code:
560 * ENOMEM: There is insufficient memory to add this action
561 * EPOLICY: The thread specified by thread has its appscheduled
562 * attribute set to false,
563 * EINVAL: The value specified by sched_actions is invalid
565 * Alternatively, in case of error the implementation is allowed to
566 * notify it to the system console and then terminate the FRSH
567 * implementation and dependant applications
569 int fosa_adsactions_add_timeout(
570 fosa_ads_actions_t *sched_actions,
571 fosa_clock_id_t clock_id,
572 const struct timespec *at_time)
578 * fosa_adsactions_add_thread_notification()
580 * Add a timed-thread-notification action
582 * This function adds a thread-notification action associated with the
583 * thread specified in the thread argument that will cause the
584 * notification_for_thread() scheduler operation to be invoked at the
585 * time specified by at_time. This operation shall be invoked when the
586 * clock specified by clock_id reaches the absolute time specified by
587 * the at_time argument. In particular, a cpu-time clock may be used
588 * for parameter clock_id.Only one thread-notification can be active
589 * for each thread and clock. Calling the function shall remove the
590 * former thread-notification, if any, that had been programmed for
591 * the same thread and clock. A value of NULL for parameter at_time is
592 * used to cancel a previous thread-notification, if any, for the
593 * thread specified by thread and the clock specified by clock_id.
595 * Returns 0 if successful; otherwise it returns an error code:
596 * ENOMEM: There is insufficient memory to add this action
597 * EPOLICY: The thread specified by thread has its appscheduled
598 * attribute set to false,
599 * EINVAL: The value specified by sched_actions is invalid
601 * Alternatively, in case of error the implementation is allowed to
602 * notify it to the system console and then terminate the FRSH
603 * implementation and dependant applications
605 int fosa_adsactions_add_thread_notification(
606 fosa_ads_actions_t *sched_actions,
607 frsh_thread_id_t thread,
608 fosa_clock_id_t clock_id,
609 const struct timespec *at_time)
616 * fosa_ads_set_handled_signal_set()
618 * Specifiy the set of signals that will be handled by the application
621 * This function is used to dynamically set the set of signals that
622 * are handled by the application scheduler. When a signal included
623 * in this set is generated, the signal() primitive operation of the
624 * application scheduler shall be executed. When a signal in tis set
625 * is generated, it shall always imply the execution of the signal()
626 * primitive operation, regardless of whether that signal could be
627 * accepted by some other thread. Once the signal() primitive
628 * operation is executed the signal is consumed, so no signal handlers
629 * shall be executed and no threads using a sigwait operation shall
630 * return for that particular signal instance. For this function to
631 * succeed, it has to be called from a primitive operation of a
634 * Returns 0 if successful; otherwise it returns an error code:
635 * EPOLICY: The function has not been called from a scheduler
636 * primitive operation
637 * EINVAL: The value specified by set is invalid
639 * Alternatively, in case of error the implementation is allowed to
640 * notify it to the system console and then terminate the FRSH
641 * implementation and dependant applications
643 int fosa_ads_set_handled_signal_set(frsh_signal_t set[])
650 * fosa_ads_invoke_withdata()
652 * Explicitly invoke the scheduler, with data
654 * This function can be used by any thread in the process to invoke
655 * the ads scheduler or to share data with it.
657 * If successful, the function shall cause the execution of the
658 * primitive operation explicit_call_with_data() of the ads scheduler
659 * with its thread parameter equal to the thread ID of the calling
660 * thread, and its msg_size parameter equal to msg_size. In addition,
661 * if msg_size is larger than zero, the function shall make available
662 * to the scheduler a memory area whose contents are identical to the
663 * memory area pointed to by msg in the msg parameter of the
664 * explicit_call_with_data() primitive operation (note that copying
665 * the information is not needed).
667 * The function shall not return until the system has finished
668 * execution of the explicit_call_with_data() primitive operation. If
669 * the reply argument is non NULL, the memory area pointed to by the
670 * reply parameter of explicit_call_with_data() primitive operation is
671 * copied into the memory area pointed to by reply, and its size is
672 * copied into the variable pointed to by reply_size. The size of the
673 * reply information is limited to the value FOSA_ADS_SCHEDINFO_MAX.
675 * The function shall fail if the size specified by msg_size is larger
676 * than FOSA_ADS_SCHEDINFO_MAX. The function shall fail if primitive
677 * operation explicit_call_with_data() is set to NULL for the ads
680 * Returns 0 if successful; otherwise it returns an error code:
681 * EPOLICY: The function been called from inside a scheduler
682 * primitive operation
683 * EINVAL: The value of msg_size is less than zero or larger than
684 * FOSA_ADS_SCHEDINFO_MAX
685 * EMASKED: The operation cannot be executed because the primitive
686 * operation explicit_call_with_data() is set to NULL
688 * Alternatively, in case of error the implementation is allowed to
689 * notify it to the system console and then terminate the FRSH
690 * implementation and dependant applications
692 int fosa_ads_invoke_withdata
693 (const void *msg, size_t msg_size, void *reply, size_t *reply_size)