]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_ose/fosa_app_def_sched.c
Finishing renaming thread_group to thread_set. Integrating Michal's AQuoSA
[frescor/fosa.git] / src_ose / fosa_app_def_sched.c
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2007 by the FRESCOR consortium:
3 //
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
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org
17 //
18 //        The 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
21 //        made of this code.
22 //
23 //  All rights reserved.
24 //
25 //  Redistribution and use in source and binary forms, with or 
26 //  without modification, are permitted provided that the 
27 //  following conditions are met:
28 //
29 //    * Redistributions of source code must retain the above 
30 //      copyright notice, this list of conditions and the 
31 //      following disclaimer.
32 //    * Redistributions in binary form must reproduce the above 
33 //      copyright notice, this list of conditions and the 
34 //      following disclaimer in the documentation and/or other 
35 //      materials provided with the distribution.
36 //    * Neither the name of FRESCOR nor the names of its 
37 //      contributors may be used to endorse or promote products 
38 //      derived from this software without specific prior 
39 //      written permission.
40 //
41 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
42 //  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
43 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
44 //  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
45 //  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
46 //  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
47 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
48 //  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
49 //  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
50 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
51 //  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
52 //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
53 //  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
54 //  POSSIBILITY OF SUCH DAMAGE.
55 // -----------------------------------------------------------------------
56 //fosa_app_def_sched.c
57 //==============================================
58 //  ********  ******    ********  **********
59 //  **///// /**    **  **//////  /**     /**
60 //  **      /**    ** /**        /**     /**
61 //  ******* /**    ** /********* /**********
62 //  **////  /**    ** ////////** /**//////**
63 //  **      /**    **        /** /**     /**
64 //  **      /**    **  ********  /**     /**
65 //  //       /******/  ////////   //      // 
66 //
67 // FOSA(Frescor Operating System Adaptation layer)
68 //================================================
69
70 #include "string.h"
71 #include "malloc.h"
72 #include "heapapi.h"
73 #include "ose.h"
74
75 #include "fosa.h"
76 #include "fosa_app_def_sched.h"
77 #include "fosa_ose_implementation_specific.h"
78
79 #include "frsh_internal.h"
80
81 //Debug purpose only.................
82 #include "stdio.h"
83
84 /**
85  * @defgroup appdefsched Application Defined Scheduling
86  * @ingroup fosa
87  *
88  * This module defines the function and types for an abstraction of
89  * the Application Defined Scheduling.
90  *
91  * @{
92  **/
93
94
95
96 /********************************
97  * Application-defined scheduling
98  ********************************/
99
100 /**
101  * We make the following ASSUMPTIONS:
102  *
103  * - The ADS always executes in the user memory space, so we don't
104  *   need to manage the memory space translation. 
105  *
106  * - Only one application scheduler exists, so we don't need an
107  *   scheduler_id.
108  **/
109
110 /*
111  * author erth
112  *
113  * Creation of the ads scheduler that takes the events from OSE calls the
114  * right scheduler callback that returns a list of actions that is 
115  * executed in the right order by this function.
116  *
117  * author erth swedish:
118  *
119  * Denna funktion skall kunna ta emot event (att process nu blivit 
120  * blockad, terminerad, signallerad eller ready) från "OSE" eller annan 
121  * del av FOSA. Därefter skall rätt funktion i structen med 
122  * funktionspekare anropas. Vilket ÄR FRSH schemaläggaren. Sedan fyller 
123  * FRSH schemaläggaren på med action noder i action listan. När anropet 
124  * till "rätt funktion" returnerar så skall den nu inte längre tomma 
125  * listan med actions utföras. Efter detta loopas det tillbaka till att 
126  * vänta på en ny action, alternativt ta emot nästa meddelande i action 
127  * kön (OSE:s signal kö till denna process).
128  */
129 OS_PROCESS(fosa_scheduler_process)
130 {
131     struct timespec current_time;
132     fosa_ose_scheduler_startup_t *sig;
133     fosa_ads_scheduler_ops_t scheduler_ops;
134     frsh_sched_data_t* frsh_sched_data;
135     
136     SIGSELECT sel_any[]       = { 0 };
137     SIGSELECT sel_start_sig[] = {1, FOSA_OSE_STARTUP_SIGNAL};
138     SIGSELECT event     = 0;
139     PROCESS asking_pid  = 0;
140     PROCESS event_pid   = 0;
141     
142     
143     // Receive the scheduler startup signal
144     sig = (fosa_ose_scheduler_startup_t *) receive(sel_start_sig);
145  
146     scheduler_ops = sig->scheduler_ops;
147     frsh_sched_data = (frsh_sched_data_t *) 
148                                          malloc(sig->scheduler_data_size);
149     
150     // Initialize the scheduler            
151     //scheduler_ops.frsh_callback_init(frsh_sched_data, sig->init_args);
152     free_buf((union SIGNAL**)&sig);
153     
154     // Initialize the queue of actions
155     fosa_ose_action_t* tmp_action;
156     fosa_ads_actions_t actions;
157     fosa_ose_ads_actions_init(&actions);
158         
159     fosa_ose_event_signal_t *event_sig;
160     while(1) {
161         //Recieve the event
162         event_sig = (fosa_ose_event_signal_t *) receive(sel_any);
163         event = event_sig->sig_no;
164         
165         fosa_clock_get_time(FOSA_CLOCK_REALTIME, &current_time);
166                 
167         //Call the right scheduler callback function.
168         switch (event) {
169
170             case FOSA_OSE_BLOCK_SIGNAL:
171                 event_pid = event_sig->pid;
172                 printf("FOSA SCHEDULER: Process %x blocked.\n",
173                         event_pid); //Debug purpose only...................
174                 //scheduler_ops.frsh_callback_thread_block(
175                 //                          frsh_sched_data, 
176                 //                          frsh_thread_id_t thread,
177                 //                          &actions, 
178                 //                          &current_time)
179                 break;
180                 
181             case FOSA_OSE_READY_SIGNAL:
182                 event_pid = event_sig->pid;
183                 printf("FOSA SCHEDULER: Process %x ready.\n",
184                         event_pid); //Debug purpose only...................
185                 //scheduler_ops.frsh_callback_thread_ready(
186                 //                          frsh_sched_data, 
187                 //                          frsh_thread_id_t thread,
188                 //                          &actions, 
189                 //                          &current_time)
190                 break;
191
192             case FOSA_OSE_SIGNAL_SCHED_SIGNAL:
193                 //scheduler_ops.frsh_callback_signal(
194                 //                          frsh_sched_data, 
195                 //                          frsh_signal_t signal, 
196                 //                          frsh_signal_info_t signal_info,
197                 //                          &actions, 
198                 //                          &current_time)
199                 break;
200                 
201             case FOSA_OSE_TERMINATE_SIGNAL:
202                 event_pid = event_sig->pid;
203                 printf("FOSA SCHEDULER: Process %x terminated.\n",
204                         event_pid); //Debug purpose only...................
205                 //scheduler_ops.frsh_callback_thread_terminate(
206                 //                          frsh_sched_data, 
207                 //                          event_sig->tid,
208                 //                          &actions, 
209                 //                          &current_time)
210                 break;
211
212             case FOSA_OSE_NEW_THREAD_SIGNAL:
213                 event_pid  = event_sig->pid;
214                 asking_pid = sender((union SIGNAL**)&event_sig);
215                 printf("FOSA SCHEDULER: Process %x new.\n", event_pid); //Debug purpose only...................
216                 //scheduler_ops.frsh_callback_new_thread(
217                 //                          frsh_sched_data, 
218                 //                          event_sig->tid, 
219                 //                          &actions, 
220                 //                          &current_time);
221                 /*
222                  * author erth
223                  *
224                  * We also need to save the process that the question was
225                  * sent from. To be able to reply with a reject or activate
226                  * in the action below. Since the action type can't save
227                  * it, it's stored in the variable asking_pid.
228                  * 
229                  * If the thread is rejected a REJECT action is added to
230                  * the actions list. But if accepted, no REJECT action is
231                  * added. Instead of adding a ACCEPT action if there were
232                  * one. Now you need to search through the list
233                  * of actions to see if there is any reject action. If
234                  * none, it is accepted. Bad design of FOSA API.
235                  */
236                 tmp_action = actions.FirstAction;
237                 while (tmp_action != NULL) 
238                 {
239                     if (tmp_action->action == REJECT)
240                         break;
241                     tmp_action = tmp_action->NextAction;
242                 }
243                 if (tmp_action == NULL)
244                     fosa_ose_execute_action_accept(asking_pid);
245                 break;
246
247             /*case FOSA_OSE_EMPTY:
248                 //scheduler_ops.frsh_callback_explicit_call_with_data((void *) frsh_sched_data,
249                 //                          frsh_thread_id_t thread_id,
250                 //                          const void * msg, 
251                 //                          size_t msg_size,
252                 //                          void **reply, 
253                 //                          size_t *reply_size,
254                 //                          fosa_ads_actions_t * actions,
255                 //                          &current_time)
256                 break;
257
258             case FOSA_OSE_EMPTY:
259                 //scheduler_ops.frsh_callback_change_sched_param_thread(
260                 //                          frsh_sched_data, 
261                 //                          frsh_thread_id_t thread,
262                 //                          &actions, 
263                 //                          &current_time)
264                 break;
265             
266             case FOSA_OSE_EMPTY:
267                 //scheduler_ops.frsh_callback_appsched_error(
268                 //                          frsh_sched_data, 
269                 //                          frsh_thread_id_t thread,
270                 //                          fosa_ads_error_cause_t cause, 
271                 //                          &actions)
272                 break;
273             
274             case FOSA_OSE_SHUTDOWN_FRSH:
275                 //Shutdown the possible parts of frsh and fosa and return
276                 //all allocated memory. Restart FRSH again?
277                 free(frsh_sched_data);
278                 kill_proc(current_process()); 
279                 break;
280             */    
281             case FOSA_OSE_TEST_EVENT_SIGNAL:
282                 ramlog_printf("FOSA: Sucess by: receive an event in the \
283                 scheduler.\n"); 
284                 fosa_ose_adsactions_add_test(&actions, (action_t)SUSPEND);            
285                 break;
286                 
287             default:
288                 ramlog_printf("FOSA: Unknown event (sig_no: %d) given to \
289                 scheduler. The scheduler process shutdown.\n", event);
290                 kill_proc(current_process()); 
291                 break;
292         }
293         free_buf((union SIGNAL **)&event_sig);
294         
295         //Execute the received actions in the action list, returned from 
296         //the callback scheduler functions above.
297         while(actions.LastAction != NULL){
298             switch (actions.FirstAction->action) {
299                 case ACTIVATE:
300                     //fosa_ose_execute_action_activate(
301                     //            actions.FirstAction->thread);
302                     break;
303                     
304                 case REJECT:
305                     //fosa_ose_execute_action_reject(
306                     //            asking_pid, actions.FirstAction->thread);
307                     break;
308                     
309                 case SUSPEND:
310                     printf("Sucess by: Action %d executed.\n",
311                             actions.FirstAction->action); //Debug purpose only...................
312                     //fosa_ose_execute_action_suspend(
313                     //            actions.FirstAction->thread);
314                     break;
315                     
316                 case THREAD_NOTIFICATION:
317                     //fosa_ose_execute_action_thread_notification(
318                     //            actions.FirstAction);
319                     break;
320                     
321                 case TIMEOUT:
322                     //fosa_ose_execute_action_timeout(
323                     //            actions.FirstAction);
324                     break;
325                     
326                 default:
327                     ramlog_printf("FOSA SCHEDULER: Unknown action (no: %d\
328                     ) given to scheduler. The scheduler process shutdown.\
329                     \n", actions.FirstAction->action);
330                     kill_proc(current_process()); 
331                     break;
332             }
333             fosa_ose_adsactions_remove_first(&actions);
334         }
335     } 
336     kill_proc(current_process());
337 }
338
339 /**
340  * fosa_ads_scheduler_create()
341  *
342  * Create the application defined scheduler
343  *
344  * The application defined scheduler is created with the primitive
345  * operations specified in the object pointed to by scheduler_ops.
346  * 
347  * The clock used to read the time immediately before the invocation
348  * of each primitive operation, to be reported to the scheduler via
349  * the current_time parameter of each primitive operation is the
350  * FOSA_CLOCK_REALTIME clock.
351  *
352  * The scheduler_data_size parameter is used to request that a memory
353  * area of this size must be created and reserved for the scheduler to
354  * store its state. A pointer to this area is passed to the scheduler
355  * operations in the sched_data parameter. 
356  *
357  * Parameter init_arg points to an area that contains configuration
358  * information for the scheduler. The function creates a memory area
359  * of init_arg_size bytes and copies into it the area pointed by
360  * arg. A pointer to this new created area will be passed to the
361  * primitive operation init() in its arg parameter.
362  *
363  * Returns 0 if successful; otherwise it returns an error code:
364  *     EINVAL: The value of scheduler_ops was invalid
365  *     EAGAIN: The system lacks enough resources to create the scheduler
366  *
367  * Alternatively, in case of error the implementation is allowed to
368  * notify it to the system console and then terminate the FRSH
369  * implementation and dependant applications
370  **/
371 int fosa_ads_scheduler_create
372      (const fosa_ads_scheduler_ops_t * scheduler_ops, 
373       size_t scheduler_data_size,
374       void * init_args, 
375       size_t init_args_size)
376 {
377     /*
378      * author erth
379      *
380      * There are no way to kill this process and to turn off the fosa 
381      * implementation. That would be nice to have, actually almost need to
382      * have! Other wise ther will be many schedulers if this function are
383      * called several times. Michael Gonzales sais that there are no 
384      * reason to turn of the scheduler... I think there should be a way to
385      * turn off as many tings as possible anyway.
386      */
387     
388     // Error check.
389     if (scheduler_ops == NULL) return FOSA_EINVAL;
390     //Can better check be performed?
391
392     // Create scheduler startup signal
393     fosa_ose_scheduler_startup_t *sig;
394     sig = (fosa_ose_scheduler_startup_t *)alloc(
395             sizeof(fosa_ose_scheduler_startup_t) + init_args_size + 
396             scheduler_data_size,
397             FOSA_OSE_STARTUP_SIGNAL);
398     
399     //Stupid to make copy here????........................................
400     sig->scheduler_ops        = *scheduler_ops;
401     sig->scheduler_data_size  = scheduler_data_size;
402     sig->init_args            = init_args;
403     sig->init_args_size       = init_args_size;
404     
405     //Make ose priority from fosa priority, and set attr.
406     OSPRIORITY prio = (OSPRIORITY) fosa_get_priority_max() 
407                           + fosa_get_priority_min() - FRSH_SCHEDULER_PRIORITY;
408     
409     
410     // Create the scheduler
411     char name[] = "fosa_scheduler_process";
412     PROCESS pid = create_process(
413                    OS_PRI_PROC,             // Process type.                
414                    name,                    // Name. 
415                    fosa_scheduler_process,  // Entrypoint. 
416                    1000,                    // Stacksize.           
417                    prio,                    // Priority. 28+3-29=2 To low?                    
418                    0,                       // Timeslice.                   
419                    0,                       // 0 = Part of callers block.......??   
420                    NULL,                    // No signal redirection.       
421                    0,                       // OSvector.                    
422                    0);                      // OSuser.   
423
424     send((union SIGNAL **)&sig, pid); 
425     start(pid);
426     
427     // EAGAIN error check taken care of by OSE.
428     return 0;
429 }
430
431
432 /**
433  * fosa_thread_attr_set_appscheduled()
434  *
435  * Set the appscheduled attribute of a thread attributes object
436  *
437  * This function is used to set the appscheduled attribute in the
438  * object pointed to by attr. This attribute controls the kind of
439  * scheduling used for threads created with it. If true, the thread is
440  * scheduled by the application scheduler. If not, it is scheduled by
441  * the system under a fixed priority scheduler
442  *
443  * Returns 0 if successful; otherwise it returns an error code:
444  *     EINVAL: The value of attr is invalid
445  *
446  * Alternatively, in case of error the implementation is allowed to
447  * notify it to the system console and then terminate the FRSH
448  * implementation and dependant applications
449  **/
450 int fosa_thread_attr_set_appscheduled
451         (frsh_thread_attr_t *attr, 
452          bool appscheduled)
453 {
454     if (attr == NULL) return FOSA_EINVAL;
455     
456     attr->app_scheduled = appscheduled;
457         
458     return 0;
459 }
460
461 /**
462  * fosa_thread_attr_get_appscheduled()
463  *
464  * Get the appscheduled attribute of a thread attributes object
465  *
466  * This function is used to get the appscheduled attribute in the
467  * object pointed to by attr. This attribute controls the kind of
468  * scheduling used for threads created with it. If true, the thread is
469  * scheduled by the application scheduler. If not, it is scheduled by
470  * the system under a fixed priority scheduler.
471  * 
472  * Returns 0 if successful; otherwise it returns an error code:
473  *    EINVAL: The value of attr is invalid
474  *
475  * Alternatively, in case of error the implementation is allowed to
476  * notify it to the system console and then terminate the FRSH
477  * implementation and dependant applications
478  **/
479 int fosa_thread_attr_get_appscheduled
480         (const frsh_thread_attr_t *attr,
481          bool *appscheduled)
482 {
483     if (attr == NULL) return FOSA_EINVAL;
484        
485     *appscheduled = attr->app_scheduled; 
486     
487     return 0;
488 }
489
490 /**
491  * fosa_thread_attr_set_appsched_params()
492  *
493  * Set the appsched_param attribute of a thread attributes object
494  *
495  * This function is used to set the appsched_param attribute in the
496  * object pointed to by attr.  For those threads with appscheduled set
497  * to true, this attribute represents the application-specific
498  * scheduling parameters. If successful, the function shall set the
499  * size of the appsched_param attribute to the value specified by
500  * paramsize, and shall copy the scheduling parameters occupying
501  * paramsize bytes and pointed to by param into that attribute
502  *
503  * Returns 0 if successful; otherwise it returns an error code:
504  *    EINVAL: The value of attr is invalid, or paramsize is less than 
505  *            zero or larger than FOSA_ADS_SCHEDPARAM_MAX
506  *
507  * Alternatively, in case of error the implementation is allowed to
508  * notify it to the system console and then terminate the FRSH
509  * implementation and dependant applications
510  **/
511 int fosa_thread_attr_set_appsched_params
512         (frsh_thread_attr_t *attr,
513          const void *param,
514          size_t paramsize)
515 {
516     if (attr == NULL) return FOSA_EINVAL;
517     
518     attr->appsched_param = heap_realloc_shared(
519                     attr->appsched_param, paramsize, __FILE__, __LINE__);
520     if (attr->appsched_param == NULL) return ENOMEM;
521     
522     // Copy *param to above allocated memory
523     memcpy( attr->appsched_param, param, paramsize );  
524     attr->appsched_param_size = paramsize;    
525             
526     return 0;
527 }
528
529 /**
530  * fosa_thread_attr_get_appsched_params()
531  *
532  * Get the appsched_param attribute of a thread attributes object
533  *
534  * This function is used to get the appsched_param attribute from the
535  * object pointed to by attr.  For those threads with appscheduled set
536  * to true, this attribute represents the application-specific
537  * scheduling parameters. If successful, the function shall set the
538  * value pointed to by paramsize to the size of the appsched_param
539  * attribute, and shall copy the scheduling parameters occupying
540  * paramsize bytes into the variable pointed to by param. This
541  * variable should be capable of storing a number of bytes equal to
542  * paramsize.
543  *
544  * Returns 0 if successful; otherwise it returns an error code:
545  *     EINVAL: The value of attr is invalid
546  *
547  * Alternatively, in case of error the implementation is allowed to
548  * notify it to the system console and then terminate the FRSH
549  * implementation and dependant applications
550  **/
551 int fosa_thread_attr_get_appsched_params
552         (const frsh_thread_attr_t *attr,
553          void *param,
554          size_t *paramsize)
555 {
556     if (attr == NULL) 
557         return FOSA_EINVAL;
558     else if (attr->appsched_param == NULL)  
559         return FOSA_EINVAL; 
560     
561     if (attr->app_scheduled) {
562         /*
563          * author erth
564          *
565          * This is not logical. The size of the memory area
566          * should be returned, but memory of (at least) the same size need
567          * to be already reserved, by the one who calls this function.
568          * This means the caller need to already know the size of the 
569          * memory. Then why return the size? Or why not reserve the memory
570          * here? Reasoning in circles!!!...................................
571          */
572         
573         //param = (void *) malloc(attr->appsched_param_size); // Should not be done here!?!!
574         //in that case a (void **param) are needed, not a (void *param).
575         memcpy( param, attr->appsched_param, attr->appsched_param_size );
576         *paramsize = attr->appsched_param_size;
577     } else {
578         return FOSA_EINVAL; 
579     }
580     
581     /*
582      * author erth
583      *
584      * Since allocated memory at attr->appsched_param are not freed here 
585      * this is possibly a memoryleak, 
586      * where or when are this memory returned?...........................
587      */
588     
589     return 0;
590 }
591
592 /**
593  * fosa_ads_set_appscheduled()
594  *
595  * Dynamically set the appscheduled attribute of a thread
596  * 
597  * This function is used to dynamically set the appscheduled attribute
598  * of the thread identified by thread. This attribute controls the
599  * kind of scheduling used for threads created with it. If true, the
600  * thread is scheduled by the application scheduler. If not, it is
601  * scheduled by the system under a fixed priority scheduler.
602  *
603  * Returns 0 if successful; otherwise it returns an error code:
604  *     EINVAL: The value of thread is invalid
605  *
606  *     EREJECT: the attachment of the thread to the frsh schehduler
607  *     was rejected by the frsh scheduler possibly because of
608  *     incorrect attributes, or because the requested minimum
609  *     capacity cannot be guaranteed
610  *
611  * Alternatively, in case of error the implementation is allowed to
612  * notify it to the system console and then terminate the FRSH
613  * implementation and dependant applications
614  **/
615 int fosa_ads_set_appscheduled
616         (frsh_thread_id_t thread,
617          bool appscheduled)
618 {
619     fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
620     if (process == NULL) return FOSA_EINVAL;
621     
622     //Ask the scheduler if ok to add the thread?..........................
623     //Or possible to use the user area variable of the process?...........
624     
625     process->app_scheduled = appscheduled;
626     return 0;
627 }
628
629 /**
630  * fosa_ads_getappscheduled()
631  *
632  * Dynamically get the appscheduled attribute of a thread
633  * 
634  * This function is used to dynamically get the appscheduled attribute
635  * of the thread identified by thread. This attribute controls the
636  * kind of scheduling used for threads created with it. If true, the
637  * thread is scheduled by the application scheduler. If not, it is
638  * scheduled by the system under a fixed priority scheduler
639  *
640  * Returns 0 if successful; otherwise it returns an error code:
641  *     EINVAL: The value of thread is invalid
642  *
643  * Alternatively, in case of error the implementation is allowed to
644  * notify it to the system console and then terminate the FRSH
645  * implementation and dependant applications
646  **/
647 int fosa_ads_get_appscheduled
648         (frsh_thread_id_t thread,
649          bool *appscheduled)
650 {
651     fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
652     if (process == NULL) return FOSA_EINVAL;
653     
654     *appscheduled = process->app_scheduled;
655     return 0;
656 }
657
658
659 /**
660  * fosa_ads_setappschedparam()
661  *
662  * Dynamically set the appsched_param attribute of a thread
663  *
664  * This function is used to dynamically set the appsched_param
665  * attribute of the thread identified by thread.  For those threads
666  * with appscheduled set to true, this attribute represents the
667  * application-specific scheduling parameters. If successful, the
668  * function shall set the size of the appsched_param attribute to the
669  * value specified by paramsize, and shall copy the scheduling
670  * parameters occupying paramsize bytes and pointed to by param into
671  * that attribute
672  *
673  * Returns 0 if successful; otherwise it returns an error code:
674  *    EINVAL: The value of thread is invalid, or paramsize is less than 
675  *            zero or larger than FOSA_ADS_SCHEDPARAM_MAX
676  *
677  * Alternatively, in case of error the implementation is allowed to
678  * notify it to the system console and then terminate the FRSH
679  * implementation and dependant applications
680  **/
681 int fosa_ads_set_appsched_params
682         (frsh_thread_id_t thread,
683          const void *param,
684          size_t paramsize)
685 {
686     fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
687     if ((paramsize < 0) ||
688         (paramsize > FOSA_ADS_SCHEDPARAM_MAX) ||
689         (process == NULL)) { 
690         return FOSA_EINVAL;
691     }
692     
693     process->appsched_param = heap_realloc_shared(
694                 process->appsched_param, paramsize, __FILE__, __LINE__);
695     memcpy(process->appsched_param, param, paramsize);
696     process->appsched_param_size = paramsize;
697
698     return 0;    
699 }
700
701 /**
702  * fosa_ads_get_appsched_params()
703  *
704  * Dynamically get the appsched_param attribute of a thread
705  *
706  * This function is used to dynamically get the appsched_param
707  * attribute of the thread identified by thread.  For those threads
708  * with appscheduled set to true, this attribute represents the
709  * application-specific scheduling parameters. If successful, the
710  * function shall set the variable pointed to by paramsize to the size
711  * of the appsched_param attribute, and shall copy the scheduling
712  * parameters occupying paramsize bytes into the variable pointed to
713  * by param. This variable should be capable of storing a number of
714  * bytes equal to paramsize.
715  *
716  *  Returns 0 if successful; otherwise it returns an error code:
717  *     EINVAL: The value of thread is invalid, or paramsize is less than 
718  *             zero or larger than FOSA_ADS_SCHEDPARAM_MAX
719  *
720  * Alternatively, in case of error the implementation is allowed to
721  * notify it to the system console and then terminate the FRSH
722  * implementation and dependant applications.
723  **/
724 int fosa_ads_get_appsched_params
725         (frsh_thread_id_t thread,
726          void *param,
727          size_t *paramsize)
728 {
729     fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
730     if (process == NULL) return FOSA_EINVAL;
731     
732     *paramsize = process->appsched_param_size;
733     memcpy(param, process->appsched_param, process->appsched_param_size);
734     
735     return 0;
736 }
737
738
739 /*********************************
740  * ADS actions
741  *
742  * A scheduling actions object is used to specify a series of actions
743  * to be performed by the system at the end of a scheduler primitive
744  * operation. The order of the actions added to the object shall be
745  * preserved.
746  *
747  *********************************/
748
749 /*
750  * author erth
751  *
752  * This function are introcuded to avoid code multiplication in the
753  * fosa_adsactions_add_* functions and it should also only be called by 
754  * these functions. It returns 0 if successful, otherwise the errors given
755  * by its calling function. 
756  */
757 int fosa_ose_adsactions_add(fosa_ads_actions_t* sched_actions,
758                             action_t            action,
759                             frsh_thread_id_t    thread,
760                             fosa_ads_urgency_t  urgency,
761                             fosa_clock_id_t     clock_id,
762                             time_t              sec,
763                             long                nsec)
764 {
765     // How to initialize fosa_ads_actions_t? Set pointers to NULL............
766     bool sched_actions_first_element = false;
767     
768     // Chcek for errors.
769     if (sched_actions->LastAction == NULL) { 
770         sched_actions_first_element = true;    
771     } else if (sched_actions->LastAction->NextAction != NULL) 
772         return FOSA_EINVAL;    
773    
774     // Make new action node.
775     fosa_ose_action_t* NewAction = (fosa_ose_action_t*) 
776         heap_alloc_shared(sizeof(fosa_ose_action_t), __FILE__, __LINE__);
777     if (NewAction == NULL) return FOSA_ENOMEM;
778     
779     NewAction->action           = action;
780     NewAction->tid              = thread;
781     NewAction->urgency          = urgency;
782     NewAction->clock_id         = clock_id;
783     NewAction->at_time.tv_sec   = sec;
784     NewAction->at_time.tv_nsec  = nsec;
785     NewAction->NextAction       = NULL;
786     
787     // Add action node to list.
788     if (sched_actions_first_element) 
789         sched_actions->FirstAction = NewAction;        
790     else                          
791         (sched_actions->LastAction)->NextAction = NewAction;
792     
793     sched_actions->LastAction = NewAction;
794     
795     return 0;                         
796 }
797
798 /**
799  * fosa_adsactions_add_reject()
800  *
801  * Add a reject-thread action
802  *
803  * This function adds a thread-reject action to the object referenced
804  * by sched_actions, that will serve to notify that the thread
805  * identified by thread has not been accepted by the scheduler to be
806  * scheduled by it, possibly because the thread contained invalid
807  * application scheduling attributes, or because there are not enough
808  * resources for the new thread.  At the end of the new_thread()
809  * scheduler primitive operation, the parent of the rejected thread
810  * waiting on a fosa_thread_create() or the rejected thread itself
811  * waiting on a fosa_ads_set_appscheduled() function shall complete the
812  * function with an error code of EREJECT. If no reject-thread action
813  * is added during the new_thread() scheduler primitive operation, the
814  * thread is accepted to be scheduled by the scheduler and the
815  * associated fosa_thread_create() or the fosa_ads_set_appscheduled()
816  * function shall be completed without error. For the function to
817  * succeed, it has to be called from the new_thread() primitive
818  * operation and for the thread that is requesting attachment to the
819  * scheduler.
820  *
821  *  Returns 0 if successful; otherwise it returns an error code:
822  *     ENOMEM: There is insufficient memory to add this action
823  *     EPOLICY: The thread specified by thread is not the one requesting
824  *               attachment to the scheduler, or the function is not being
825  *               called from the new_thread primitive operation
826  *     EINVAL: The value specified by sched_actions is invalid
827  *
828  * Alternatively, in case of error the implementation is allowed to
829  * notify it to the system console and then terminate the FRSH
830  * implementation and dependant applications
831  **/
832
833  
834 int fosa_adsactions_add_reject(
835         fosa_ads_actions_t *sched_actions,
836         frsh_thread_id_t thread) 
837 {
838     if (thread != current_process()) return FOSA_EPOLICY;
839     
840     return fosa_ose_adsactions_add( sched_actions,  //sched_actions
841                                     REJECT,         //action
842                                     thread,         //thread
843                                     0,              //urgency
844                                     0,              //clock_id
845                                     0,              //sec
846                                     0);             //nsec
847 }
848
849 /**
850  * fosa_adsactions_add_activate()
851  *
852  * Add a thread-activate action 
853  *
854  * This function adds a thread-activate action to the object
855  * referenced by sched_actions. In case the thread had been previously
856  * suspended via posix_appsched_actions_addsuspend(), it will be
857  * activated at the end of the primitive operation.
858  *
859  * In those implementations that do not support urgency scheduling,
860  * the urgencu value is ignored. These implementations cannot support
861  * the frsh hierarchical scheduling module.
862  *
863  * In those implementations supporting urgency-scheduling, the action
864  * will cause the change of the urgency of the thread to the value
865  * specified in the urgency argument. Besides, if the thread was
866  * already active at the time the thread-activate action is executed,
867  * the change or urgency will imply a reordering of the thread in its
868  * priority queue, so that for threads of the same priority, those
869  * with more urgency will be scheduled before those of less urgency.
870  *
871  * Returns 0 if successful; otherwise it returns an error code:
872  *     ENOMEM: There is insufficient memory to add this action
873  *     EPOLICY: The thread specified by thread has its appscheduled
874  *              attribute set to false, 
875  *     EINVAL: The value specified by sched_actions is invalid
876  *
877  * Alternatively, in case of error the implementation is allowed to
878  * notify it to the system console and then terminate the FRSH
879  * implementation and dependant applications
880  **/
881 int fosa_adsactions_add_activate(
882         fosa_ads_actions_t *sched_actions,
883         frsh_thread_id_t thread,
884         fosa_ads_urgency_t urgency) 
885 {
886     return fosa_ose_adsactions_add( sched_actions,  //sched_actions
887                                     ACTIVATE,       //action
888                                     thread,         //thread
889                                     urgency,        //urgency
890                                     0,              //clock_id
891                                     0,              //sec
892                                     0);             //nsec
893 }
894
895 /**
896  * fosa_adsactions_add_suspend()
897  *
898  * Add a thread-suspend action
899  *
900  * This function adds a thread-suspend action to the object referenced
901  * by sched_actions, that will cause the thread identified by thread
902  * to be suspended waiting for a thread-activate action at the end of
903  * the scheduler operation. If the thread was already waiting for a
904  * thread-activate action the thread-suspend action has no effect. It
905  * is an error trying to suspend a thread that is blocked by the
906  * operating system.
907  * 
908  *  Returns 0 if successful; otherwise it returns an error code:
909  *     ENOMEM: There is insufficient memory to add this action
910  *     EPOLICY: The thread specified by thread has its appscheduled
911  *              attribute set to false, 
912  *     EINVAL: The value specified by sched_actions is invalid
913  *
914  *  Alternatively, in case of error the implementation is allowed to
915  *  notify it to the system console and then terminate the FRSH
916  *  implementation and dependant applications
917  **/
918 int fosa_adsactions_add_suspend(
919         fosa_ads_actions_t *sched_actions,
920         frsh_thread_id_t thread)
921 {
922     return fosa_ose_adsactions_add( sched_actions,  //sched_actions
923                                     SUSPEND,        //action
924                                     thread,         //thread
925                                     0,              //urgency
926                                     0,              //clock_id
927                                     0,              //sec
928                                     0);             //nsec
929 }
930
931 /**
932  * fosa_adsactions_add_timeout()
933  *
934  * Add a timeout action
935  *
936  * This function adds a timeout action to the object referenced by
937  * sched_actions, that will cause the timeout() scheduler operation to
938  * be invoked if no other scheduler operation is invoked before
939  * timeout expires. The timeout shall expire when the clock specified by
940  * clock_id reaches the absolute time specified by the at_time
941  * argument.
942  *
943  *  Returns 0 if successful; otherwise it returns an error code:
944  *     ENOMEM: There is insufficient memory to add this action
945  *     EPOLICY: The thread specified by thread has its appscheduled
946  *              attribute set to false, 
947  *     EINVAL: The value specified by sched_actions is invalid
948  *
949  * Alternatively, in case of error the implementation is allowed to
950  * notify it to the system console and then terminate the FRSH
951  * implementation and dependant applications
952  **/
953 int fosa_adsactions_add_timeout(
954         fosa_ads_actions_t *sched_actions,
955         fosa_clock_id_t clock_id,
956         const struct timespec *at_time)
957 {
958     return fosa_ose_adsactions_add( sched_actions,      //sched_actions
959                                     TIMEOUT,            //action
960                                     current_process(),  //thread
961                                     0,                  //urgency
962                                     clock_id,           //clock_id
963                                     at_time->tv_sec,    //sec
964                                     at_time->tv_nsec);  //nsec
965 }
966
967 /**
968  * fosa_adsactions_add_thread_notification()
969  *
970  * Add a timed-thread-notification action
971  *
972  * This function adds a thread-notification action associated with the
973  * thread specified in the thread argument that will cause the
974  * notification_for_thread() scheduler operation to be invoked at the
975  * time specified by at_time. This operation shall be invoked when the
976  * clock specified by clock_id reaches the absolute time specified by
977  * the at_time argument. In particular, a cpu-time clock may be used
978  * for parameter clock_id.Only one thread-notification can be active
979  * for each thread and clock. Calling the function shall remove the
980  * former thread-notification, if any, that had been programmed for
981  * the same thread and clock. A value of NULL for parameter at_time is
982  * used to cancel a previous thread-notification, if any, for the
983  * thread specified by thread and the clock specified by clock_id.
984  * 
985  *  Returns 0 if successful; otherwise it returns an error code:
986  *     ENOMEM: There is insufficient memory to add this action
987  *     EPOLICY: The thread specified by thread has its appscheduled
988  *              attribute set to false, 
989  *     EINVAL: The value specified by sched_actions is invalid
990  *
991  *  Alternatively, in case of error the implementation is allowed to
992  *  notify it to the system console and then terminate the FRSH
993  *  implementation and dependant applications
994  **/
995 int fosa_adsactions_add_thread_notification(
996         fosa_ads_actions_t *sched_actions,
997         frsh_thread_id_t thread,
998         fosa_clock_id_t clock_id,
999         const struct timespec *at_time)
1000 {
1001     return fosa_ose_adsactions_add( sched_actions,      //sched_actions
1002                                     THREAD_NOTIFICATION,//action
1003                                     thread,             //thread
1004                                     0,                  //urgency
1005                                     clock_id,           //clock_id
1006                                     at_time->tv_sec,    //sec
1007                                     at_time->tv_nsec);  //nsec
1008 }
1009
1010
1011 /**
1012  * fosa_ads_set_handled_signal_set()
1013  *
1014  * Specifiy the set of signals that will be handled by the application
1015  * scheduler
1016  *
1017  * This function is used to dynamically set the set of signals that
1018  * are handled by the application scheduler.  When a signal included
1019  * in this set is generated, the signal() primitive operation of the
1020  * application scheduler shall be executed. When a signal in tis set
1021  * is generated, it shall always imply the execution of the signal()
1022  * primitive operation, regardless of whether that signal could be
1023  * accepted by some other thread. Once the signal() primitive
1024  * operation is executed the signal is consumed, so no signal handlers
1025  * shall be executed and no threads using a sigwait operation shall
1026  * return for that particular signal instance.  For this function to
1027  * succeed, it has to be called from a primitive operation of a
1028  * scheduler.
1029  *
1030  * Returns 0 if successful; otherwise it returns an error code:
1031  *    EPOLICY: The function has not been called from a scheduler 
1032  *              primitive operation
1033  *    EINVAL: The value specified by set is invalid
1034  *
1035  * Alternatively, in case of error the implementation is allowed to
1036  * notify it to the system console and then terminate the FRSH
1037  * implementation and dependant applications
1038  **/
1039 int fosa_ads_set_handled_signal_set(frsh_signal_t set[])
1040 {
1041     /*
1042      * author erth
1043      *
1044      * This function is not neccisary in OSE since set[] is used as an 
1045      * argument in the calls to fosa_signal_wait() and 
1046      * fosa_signal_timedwait() functions. Also decided to be empty in 
1047      * Barcelona meeting 2007-01-31.
1048      */
1049     return 0;
1050 }
1051
1052 /**
1053  * fosa_ads_invoke_withdata()
1054  *
1055  * Explicitly invoke the scheduler, with data  
1056  *
1057  * This function can be used by any thread in the process to invoke
1058  * the ads scheduler or to share data with it.
1059  *
1060  * If successful, the function shall cause the execution of the
1061  * primitive operation explicit_call_with_data() of the ads scheduler
1062  * with its thread parameter equal to the thread ID of the calling
1063  * thread, and its msg_size parameter equal to msg_size. In addition,
1064  * if msg_size is larger than zero, the function shall make available
1065  * to the scheduler a memory area whose contents are identical to the
1066  * memory area pointed to by msg in the msg parameter of the
1067  * explicit_call_with_data() primitive operation (note that copying
1068  * the information is not needed). 
1069  *
1070  * The function shall not return until the system has finished
1071  * execution of the explicit_call_with_data() primitive operation. If
1072  * the reply argument is non NULL, the memory area pointed to by the
1073  * reply parameter of explicit_call_with_data() primitive operation is
1074  * copied into the memory area pointed to by reply, and its size is
1075  * copied into the variable pointed to by reply_size. The size of the
1076  * reply information is limited to the value FOSA_ADS_SCHEDINFO_MAX. 
1077  * 
1078  * The function shall fail if the size specified by msg_size is larger
1079  * than FOSA_ADS_SCHEDINFO_MAX.  The function shall fail if primitive
1080  * operation explicit_call_with_data() is set to NULL for the ads
1081  * scheduler.
1082  *
1083  *  Returns 0 if successful; otherwise it returns an error code:
1084  *     EPOLICY: The function been called from inside a scheduler 
1085  *              primitive operation
1086  *     EINVAL: The value of msg_size is less than zero or larger than 
1087  *             FOSA_ADS_SCHEDINFO_MAX
1088  *     EMASKED: The operation cannot be executed because the primitive
1089  *              operation explicit_call_with_data() is set to NULL
1090  *
1091  *  Alternatively, in case of error the implementation is allowed to
1092  *  notify it to the system console and then terminate the FRSH
1093  *  implementation and dependant applications
1094  **/
1095 int fosa_ads_invoke_withdata
1096    (const void *msg, size_t msg_size, void *reply, size_t *reply_size) 
1097 {
1098    //Not implemented yet!!...........................................
1099    
1100    /*
1101     * author erth
1102     *
1103     * This function should send a message to the fosa_scheduler_process,
1104     * that calls the frsh_callback_explicit_call_with_data(), 
1105     * that creates a reply message that are 
1106     * sent back to this process from fosa_scheduler_process, 
1107     * here we then set the reply message and
1108     * this function return
1109     * 
1110     * For example a call to frsh_contract_negotiate() results in a call
1111     * to this function. If the messages were not sent the execution of the
1112     * callback would be made of the calling processes. Which are not good. 
1113     */
1114     
1115    return 0;
1116    }
1117
1118 /*}*/
1119
1120