Subversion Repositories shark

Rev

Rev 1676 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1676 tullio 1
%----------------------------------------------------------------------------
2
\chapter{The Scheduling Modules\label{CapSchedulingModules}}
3
%----------------------------------------------------------------------------
4
 
5
This chapter describes the interface of a generic Scheduling
6
Module, the semantic of the functions that compose the interface,
7
and a set of conventions used to write the Modules.
8
%
9
% Tool: such section does not exists.
10
%
11
% For more
12
% information on the Scheduling Module Architecture see Section
13
% \ref{ArchDetail_Scheduling_Modules}.
14
 
15
%----------------------------------------------------------------------------
16
\section{Task Lifecycle\label{SchedModules_Lifecycle}}
17
%----------------------------------------------------------------------------
18
 
19
To understand the interface of a Scheduling Module, we present a
20
simple view of the events that refer the life of a task, from its
21
creation to its end. The Module Interface reflects these events.
22
 
23
Figure \ref{SchedModules_Lifecycle_Base} illustrates a simple
24
case, in which a task is created, activated, and then preempted by
25
another task that dies after a while. The following events are
26
generated:
27
 
28
\begin{figure}
29
\begin{center}
30
\includegraphics[width=8cm]{images/schedmodules_lifecycle1.eps}
31
\end{center}
32
\label{SchedModules_Lifecycle_Base}
33
\caption{A simple scenario: tasks i and j are created and activated. Task i is
34
executed, and, after a while, it is preempted by task j. The numbers in
35
parenthesis denote the event sequence.}
36
\end{figure}
37
 
38
\begin{description}
39
\item [create]This event is generated at task creation. The
40
Scheduling Module initializes the data structures for the task
41
activation.
42
 
43
\item [activate]This event is generated when a task is
44
explicitly activated by a call to a user primitive. That event
45
authorizes the Scheduling Module to insert the task in the set of
46
the schedulable tasks.
47
 
48
\item [dispatch]This event is generated when a task, after it has been scheduled
49
\footnote{The scheduling event is not showed in the figure.}, is actually
50
executed. The Scheduling Module updates the data structures to register the
51
execution of the task.
52
 
53
\item [epilogue]This event is generated all the times a task is preempted by
54
another task \footnote{This event is also raised if the task finishes its time
55
capacity allocated on its server (for soft tasks).}. The Scheduling Module
56
usually reinserts the task in the set of the schedulable tasks.
57
 
58
\item [end]this event is generated when a
59
task ends its execution. The Scheduling Module is authorized to
60
free the task descriptor and any data allocated for the task.
61
\end{description}
62
 
63
Note that the POSIX standard does not differentiate between task
64
creation and task activation; in fact, the
65
\texttt{pthread\_create} primitive creates and activates directly
66
a task.
67
 
68
Figure \ref{SchedModules_Lifecycle_endcycle} shows a sample sequence of events
69
produced by a periodic task.
70
 
71
\begin{figure}
72
\begin{center}
73
\includegraphics[width=1.0\columnwidth]{images/schedmodules_lifecycle2.eps}
74
\end{center}
75
\label{SchedModules_Lifecycle_endcycle}
76
\caption{Activation handling: a periodic task is activated once, and it executes
77
for three activations .}
78
\end{figure}
79
 
80
A task is activated, it executes for three instances and then it
81
falls asleep waiting for another explicit activation. The new
82
events introduced in this scenario are:
83
 
84
\begin{description}
85
\item [endcycle]The endcycle event is the termination of the
86
current task instance. It is generated by a primitive inserted
87
into the task code. If the task is a periodic task, it will be
88
reactivated by the Scheduling Module at the beginning of the next
89
period. If the task is an aperiodic task, this event implies that
90
the task will wait for an explicit activation (through an activate
91
event).
92
 
93
\item [(reactivation)]This event is not created directly
94
by the user with a primitive, but it is handled internally by the
95
Scheduling Module that handles the task. This event reactivates
96
the task, and it is usually delivered at the end of a period.
97
\end{description}
98
 
99
Although the event \textit{endcycle} terminates an aperiodic or a
100
periodic job, and it can differ in the way they handle pending
101
activations. A \emph{pending activation} is an \emph{activate}
102
event which is delivered when the task has not ended the previous
103
instance. The handling of pending activations is left to the
104
Scheduling Modules.
105
 
106
Figure \ref{SchedModules_Lifecycle_extract} shows the
107
\textit{block} ed \textit{unblock} events. These events are
108
generated to handle the behavior of a synchronization primitives,
109
which generally blocks a task (\emph{block} event) and then
110
activate again the task after a while (\emph{unblock} event). The
111
events behave as
112
follows:
113
 
114
\begin{figure}
115
\begin{center}
116
\includegraphics[width=8cm]{images/schedmodules_lifecycle3.eps}
117
\end{center}
118
\label{SchedModules_Lifecycle_extract}
119
\caption{Task synchronization. A task calls a synchronization primitive, which
120
blocks the task using an extract event. When the task will be able to continue,
121
an insert event will be called.}
122
\end{figure}
123
 
124
 
125
\begin{description}
126
\item [block]It disables the task scheduling because the task is
127
arrived at a synchronization point.
128
 
129
\item [unblock]This event is
130
used to notify to the task that the synchronization is occurred,
131
so the task scheduling must be enabled.
132
\end{description}
133
 
134
The Generic Kernel guarantees that an \textit{unblock} event will
135
never be called before a corresponding \textit{block} event. That
136
is, these two events are coupled.
137
 
138
 
139
%----------------------------------------------------------------------------
140
\section{Assumptions on Task Queues}
141
%----------------------------------------------------------------------------
142
 
143
The modules distributed with the Kernel use the following
144
assumptions when managing task queues:
145
 
146
\begin{itemize}
147
\item The variables of type \texttt{IQUEUE} are allocated into the extensions of
148
the level descriptor and \emph{not} outside;
149
 
150
\item The running task is extracted
151
from the ready queue (if there is one in the Module) at dispatch time
152
\footnote{A policy that leaves the running task at the head of the ready queue
153
is also suitable.};
154
 
155
\item A Module can handle queue and other data structures
156
than those provided by the Generic Kernel. In this case all the data structures
157
shall be inserted in the level descriptor extension and the functions that use
158
them shall be visible only in that Module (for example look at the file
159
\texttt{kernel/modules/srp.c}).
160
\end{itemize}
161
 
162
%----------------------------------------------------------------------------
163
\section{Scheduling Module Interface\label{SchedModules_Interface}}
164
%----------------------------------------------------------------------------
165
 
166
This section describes the interface of the functions that have to be
167
implemented to develop a Scheduling Module. The functions described in this
168
Section are those represented by the dashed rectangles named \emph{Public
169
Functions and Private Functions} introduced early in this chapter. They are
170
\emph{not} user primitives, but they are called to implement the scheduling
171
behavior of a primitive. The function names reported in this section are the
172
name of the function pointers contained into the \texttt{level\_des} structure
173
(defined into \texttt{include/kernel/descr.h}). When a designer implements a new
174
Scheduling Module, he writes the correspondent functions and then he sets the
175
correct values into the correct \texttt{level\_des} structure (as an example, a
176
template application is provided on the website). The user primitives are
177
listed into the S.Ha.R.K. User Manual (it can be found, together with the
178
template application, on the proper section of S.Ha.R.K. website).
179
%
180
% Tool: such section does not exists.
181
%
182
% For more information see also at Sections \ref{ArchDetail_Module_Interface} and
183
% \ref{KernSupport_Level_Descriptor}.
184
 
185
All the interface functions have as first parameter a variable of
186
\texttt{LEVEL} type, used to obtain a pointer to the level
187
descriptor of the current Scheduling Module; some functions may
188
also have additional parameters.
189
 
190
We recommend that the functions listed in Table
191
\ref{SchedModules_Tab_schedule_time} should use the global
192
variable \texttt{schedule\_time} to get the system time, and
193
should not use the \texttt{kern\_gettime} function provided with
194
the OS
195
Lib.
196
\begin{table}
197
\begin{center}\begin{tabular}{|c|c|}
198
\hline Type& Function\\ \hline \hline Public
199
Functions& \texttt{public\_scheduler}\\ &
200
\texttt{public\_dispatch}\\ &
201
\texttt{public\_epilogue}\\ &
202
\texttt{public\_message}\\ &
203
\texttt{public\_block}\\ \hline Private Functions&
204
\texttt{private\_dispatch}\\ &
205
\texttt{private\_epilogue}\\ \hline
206
\end{tabular}\end{center}
207
 
208
\caption{\label{SchedModules_Tab_schedule_time}These functions
209
should use the variable \texttt{schedule\_time} to read the
210
current time.}
211
\end{table}
212
 
213
\textbf{WARNING}: All the Scheduling Modules functions are called
214
with \emph{interrupts disabled}. They should never consume more
215
than a few microseconds!!!
216
 
217
%----------------------------------------------------------------------------
218
\subsection{Public Functions\label{SchedModules_PublicFunctions}}
219
%----------------------------------------------------------------------------
220
 
221
These functions are directly called by the Generic Kernel to
222
implement the behavior of a scheduling algorithm.
223
 
224
%----------------------------------------------------------------------------
225
\subsubsection{\texttt{PID (*public\_scheduler)(LEVEL l);}}
226
%----------------------------------------------------------------------------
227
 
228
This function is the scheduler of the current Scheduling Module.
229
 
230
It must return the scheduled task among those handled by the
231
Module \footnote{That is, the tasks owned by the Module plus the tasks
232
that other Modules inserted in it using the private
233
functions.}.
234
 
235
The scheduled task must be selected only using the private data structures of
236
the Module, \emph{prescinding from the other Modules registered in the system}.
237
The fact that a task is returned by this function to be scheduled does not imply
238
that that task will be executed (dispatched) immediately
239
%
240
% Tool: such section does not exists.
241
%
242
% \footnote{Look at section \ref{ArchDetail_Shadows}}
243
.
244
 
245
So, the level scheduler shall not:
246
 
247
\begin{itemize}
248
\item Modify the pointer to the running task (in other words, the
249
variables \texttt{exec} and \texttt{exec\_shadow});
250
 
251
\item Handle
252
timers for deadline, capacity exhaustion, and things like that;
253
 
254
\item Set the data structures preparing the execution of the task (for example,
255
if the Module uses a ready queue, the task must not be extracted from the queue
256
\footnote{This will be done at dispatch time!}).
257
\end{itemize}
258
 
259
If the level does not implement a scheduler (because, for example, it is an
260
Aperiodic server that inserts all its tasks in another Module \footnote{look at
261
\texttt{kernel/modules/cbs.c}}), or if the Module currently does not have any
262
ready task, the returned value must be \texttt{NIL}.
263
 
264
%----------------------------------------------------------------------------
265
\subsubsection{\texttt{int (*public\_guarantee)(LEVEL l, bandwidth\_t *freebandwidth);}}
266
%----------------------------------------------------------------------------
267
 
268
This function implements the on-line acceptance test. This
269
function should only consider the tasks directly inserted in the
270
module, and it does not consider the tasks inserted in the module
271
through private functions (their guarantee is made by the Module
272
that owns them).
273
 
274
The function is called with an additional parameter that is the
275
free bandwidth left by the Modules with level number less than
276
\texttt{l}. The acceptance tests that can be implemented are those
277
based on the Utilization Factor.
278
 
279
The function returns 1 if the current task set can be guaranteed
280
using the free bandwidth available, 0 otherwise. The
281
\texttt{freebandwidth} parameter must be decreased by the function
282
by the amount of bandwidth used by the task being guaranteed.
283
 
284
If the pointer to this function is registered in the
285
\texttt{level\_des} descriptor of the Module with a NULL value,
286
the acceptance test procedure will stop and the whole task set is
287
considered guaranteed (see Section \ref{Kernel_Garanzia}).
288
 
289
This function is called by the Generic Kernel each time a task is
290
created in the system. The call is issued after the task is
291
created using the task call \texttt{public\_create} and after the
292
Resource Models of the new task have been registered. The
293
public\_guarantee functions are called starting from level 0 until
294
a NULL pointer is reached or the task set cannot be guaranteed.
295
 
296
%----------------------------------------------------------------------------
297
\subsubsection{\texttt{int (*public\_create)(LEVEL l, PID p, TASK\_MODEL *m);}}
298
%----------------------------------------------------------------------------
299
 
300
This function is called by the Generic Kernel into the
301
\texttt{task\_create} primitive to create a task into a Module.
302
The function has two additional parameters: the first is the task
303
descriptor allocated by the Generic Kernel for the new Task, and
304
the second is the Task Model passed at creation time.
305
 
306
The function returns 0 if the Module can handle the TASK\_MODEL
307
passed as parameter (that is, if the Module can handle the pclass
308
of the TASK\_MODEL, and if the level field is 0 or l), -1
309
otherwise.
310
 
311
The functions must set the Module internal data structures with
312
the QoS parameters passed with the Task Model. The function does
313
not enable the task to be scheduled in the system (i.e., if a
314
ready queue is implemented, the new task should not be inserted in
315
it).
316
 
317
The \texttt{task\_create} primitive sets the task state to the
318
default \texttt{SLEEP} value, and sets the flags of the
319
\texttt{control} field of the task descriptor to the values given
320
into the \texttt{control} field of the \texttt{TASK\_MODEL}
321
structure. These settings can be modified by the public\_create
322
function.
323
 
324
The acceptance test on a new task is called after this function.
325
 
326
%----------------------------------------------------------------------------
327
\subsubsection{\texttt{void (*public\_detach)(LEVEL l, PID p);}}
328
%----------------------------------------------------------------------------
329
 
330
This function is called into the Generic Kernel
331
\texttt{task\_create} primitive when an error is occurred during
332
the creation of a new task.
333
 
334
The function receives as an additional parameter the task
335
identifier passed to the \texttt{public\_create} function. This
336
function is called only after public\_create, and it must reset
337
the data structures allocated internally by the current Module
338
during public\_create.
339
 
340
%----------------------------------------------------------------------------
341
\subsubsection{\texttt{void (*public\_end)(LEVEL l, PID p);}}
342
%----------------------------------------------------------------------------
343
 
344
This function implements task termination. When this function is
345
called the task has been killed by someone (e.g., task\_kill() or
346
pthread\_cancel()), or it is ended. All the references to task p
347
have to be removed from the internal data structures of the
348
Module.
349
 
350
The \texttt{public\_end} function is called after the POSIX's
351
cleanup functions, after the POSIX's thread-specific data
352
destructors, and before the destructors of the Resource Modules.
353
 
354
When the function is called the task is in the EXE state. The
355
typical actions done by this function are the following:
356
 
357
\begin{itemize}
358
\item The task is extracted from some internal queue. \item All
359
the pending events for the task (e.g., deadline and capacity
360
timers) are removed. \item The task is inserted into the
361
\texttt{freedesc} queue. When the task is inserted in this queue
362
the task descriptor of the task may be reused by the Generic
363
Kernel.
364
 
365
 
366
If the Module implements some form of guarantee on the task set,
367
the insertion of the descriptor p into the \texttt{freedesc} queue
368
may be postponed until the bandwidth used by the task will be
369
totally released. This may occur after task's termination (for
370
example, in the EDF Module a guarantee is implemented, and the
371
bandwidth is decreased at the end of the current period. Hence,
372
the task descriptor will be inserted into the \texttt{freedesc}
373
queue at the end of the period.
374
 
375
\end{itemize}
376
 
377
%----------------------------------------------------------------------------
378
\subsubsection{\texttt{int (*public\_eligible)(LEVEL l, PID p);}}
379
%----------------------------------------------------------------------------
380
 
381
This function is called by the Generic Kernel into the global
382
scheduling function (see Section \ref{Kernel_Scheduler}) and is
383
used to ensure the Kernel of the correctness of the value returned
384
by the public\_scheduler.
385
 
386
The function receives as an additional parameter that is the task
387
returned by the \texttt{public\_scheduler} call. It must return 0
388
if the task can be scheduled, -1 otherwise. If a -1 is returned,
389
the system will call the level scheduler function again to choose
390
another (may be the same) task.
391
 
392
This function is used when implementing aperiodic servers and the
393
Module needs to know when its tasks will be scheduled by a
394
level\_scheduler of the Master Module, to update some old out-of
395
date parameters.
396
 
397
This function is useful in pathological or unplanned situations.
398
For example (see Figure \ref{SchedModules_Fig_eligible}), we have
399
implemented a CBS module in a way that it uses another Scheduling
400
Module. The CBS Module inserts its tasks in that module using the
401
guest calls; after that, it waits for its tasks to be scheduled.
402
In general, it may happen that, because of some overload
403
condition, the CBS task will be scheduled after its deadline.
404
Through the \texttt{public\_eligible} function the CBS Module can
405
postpone the task deadline, so causing the scheduler to be called
406
again to manage the new situation.
407
 
408
\begin{figure}
409
\begin{center}
410
\includegraphics[width=7cm]{images/schedmodules_eligible.eps}
411
\end{center}
412
\label{SchedModules_Fig_eligible}
413
\caption{Use of the \texttt{public\_eligible} function. Consider a CBS Module
414
that inserts its task j into an EDF-NP (EDF non-preemptive) Module. EDF-NP will
415
schedule task i first. When task i ends, task j (CBS) is scheduled. However,
416
this task has an obsolete deadline. The \texttt{public\_eligible} function
417
called on the CBS Module when the EDF-NP Module tries to schedule task j allows
418
the CBS Module to postpone the deadline.}
419
\end{figure}
420
 
421
%----------------------------------------------------------------------------
422
\subsubsection{\texttt{void (*public\_dispatch)(LEVEL l, PID p, int nostop);}}
423
%----------------------------------------------------------------------------
424
 
425
This function is called by the Generic Kernel to notify a Module
426
(registered at level l) that his task p is going to be the running
427
task.
428
 
429
When this function is called it is not possible to change the task
430
selected for execution. It is not possible to avoid the execution
431
of a task that is on the tail of a shadow chain
432
%
433
% Tool: such section does not exists.
434
%
435
% (see Section\ref{ArchDetail_Shadows})
436
. The \texttt{public\_eligible}
437
function should be used instead whenever a task cannot be
438
scheduled but it is chosen by a level scheduler.
439
 
440
The function receives two additional parameters: the task
441
\texttt{l} that will be executed and a \texttt{nostop} parameter.
442
The value of the latter parameter is the result of the logic
443
expression \texttt{exec == exec\_shadow}, where the value of
444
\texttt{exec\_shadow} is computed by the \texttt{scheduler()}
445
function (see Section \ref{Kernel_Scheduler}) after following the
446
shadow chain. If the value nostop is 0, no capacity event should
447
be generated by the Module.
448
 
449
In practice, the \texttt{public\_dispatch} can be thought as a
450
prologue in which the Scheduling Modules set the internal data
451
structures to allow a task to be executed. The state of the task
452
is set to EXE before the function call. The function shall not
453
modify the task state, as well as the \texttt{exec} and
454
\texttt{exec\_shadow} variables.
455
 
456
A few typical actions for this function are described below:
457
 
458
\begin{itemize}
459
\item the task is removed from the ready queue, if there is one;
460
 
461
\item if the Module does not use the \texttt{CONTROL\_CAP} flag (see
462
\ref{KernSupport_Capacita}, and kernel/modules/ps.c) but it needs capacity
463
control it is necessary to create a capacity event with the
464
\texttt{kern\_event\_post} function. Remember that a capacity event should not
465
be created if the \texttt{nostop} is not equal \texttt{0} \footnote{In this case
466
the task is going to be the running task because it locks a resource needed by a
467
high priority task, so usually the task must execute until the release of the
468
blocking resource.};
469
 
470
\item If the Scheduling Module is {}``coupled'' with a Resource
471
Handling Module, this function must update the ceiling (for
472
example as done with the SRP protocol).
473
\end{itemize}
474
 
475
%----------------------------------------------------------------------------
476
\subsubsection{\texttt{void (*public\_epilogue)(LEVEL l, PID p);}}
477
%----------------------------------------------------------------------------
478
 
479
This function is called by the Generic Kernel when:
480
 
481
\begin{itemize}
482
\item the running task p is preempted by another task in the
483
system;
484
 
485
\item a function that may generate a preemption is called
486
(these functions usually call the generic scheduler that, as a
487
first operation, simply call this function);
488
 
489
\item the capacity of
490
the running task p is exhausted (the capacity exhaustion is
491
handled as a preemption request!).
492
\end{itemize}
493
 
494
In general, this function receives as an additional parameter the
495
running task index. The effect of the call may also disable the
496
schedulability of the task. When this function is called the task
497
p has a state equal to EXE.
498
 
499
The typical actions done by this function are:
500
 
501
\begin{itemize}
502
\item if the schedulability of the task is still active, the task
503
is reinserted into the ready queue, if there exists one into the
504
Module; \item the state of the task is modified and it is set to
505
an internal Module state (for example, a READY state); \item the
506
capacity of the task is checked: if it is exhausted some
507
operations will be done, for example an exception is raised, a
508
deadline is postponed, and so on; \item If the Module created a
509
capacity event without using the \texttt{CONTROL\_CAP} field and
510
without using the \texttt{cap\_timer} variable, that capacity
511
event must be removed.
512
\end{itemize}
513
 
514
%----------------------------------------------------------------------------
515
\subsubsection{\texttt{void (*public\_activate)(LEVEL l, PID p, struct timespec *t);}}
516
%----------------------------------------------------------------------------
517
 
518
This function is called by the Generic Kernel when an explicit
519
activation for the task is called using the
520
\texttt{task\_activate} primitive or the \texttt{group\_activate}
521
primitive.
522
 
523
The PID parameter is the task that has to be activated. Also, the
524
activation time is given as an parameter (this will be the
525
time-base of the task). The effect of the function is to activate
526
the schedulability of the task.
527
 
528
The typical actions done by this function are listed below:
529
 
530
\begin{itemize}
531
\item First, a check is done to verify if the task is in a state
532
compatible with the activation (for example, a sporadic task
533
cannot be activated too frequently);
534
 
535
\item The state of the task,
536
usually equal to SLEEP, is modified (for example it becomes
537
READY);
538
 
539
\item If the Module has a ready queue, the task is
540
inserted in it;
541
 
542
\item If the Module counts the task's pending
543
activations, and the task does not have finished his current
544
activation yet, the activation should be saved for the task;
545
 
546
\item
547
If the Module handles periodic tasks or tasks with temporal
548
deadlines, some events should be created to check these
549
conditions.
550
\end{itemize}
551
 
552
%----------------------------------------------------------------------------
553
\subsubsection{\texttt{void (*public\_block)(LEVEL l, PID p);}}
554
%----------------------------------------------------------------------------
555
 
556
The function implements the blocking of the task p (p is the
557
running task) in a generic synchronization primitive that does not
558
use the shadow mechanism.
559
 
560
The function must disable the schedulability for the task until it
561
is ``freed'' by a call to the \texttt{public\_unblock} function.
562
 
563
The typical actions done by this function are:
564
 
565
\begin{itemize}
566
\item The task should be extracted from the ready queue if the
567
\texttt{task\_dispatch} didn't do this;
568
 
569
\item The events posted
570
with the dispatch should be removed (for example, the capacity
571
events should be removed, but not the deadline ones);
572
 
573
\item The
574
function shall not modify the state of the task; the state of the
575
task is modified by the primitive that calls the function;
576
\end{itemize}
577
 
578
%----------------------------------------------------------------------------
579
\subsubsection{\texttt{void (*public\_unblock)(LEVEL l, PID p);}}
580
%----------------------------------------------------------------------------
581
 
582
The function accepts a parameter p that is the task that has
583
terminated the synchronization started with a call to the
584
\texttt{public\_block} function. After this call, the awaken task
585
can be scheduled in the system.
586
 
587
Usually the function inserts the task into some internal queues,
588
and the state of the task is modified (for example it is set to
589
READY). Usually the function does not post any event.
590
 
591
The function is called into the code of the Generic Kernel
592
primitives that implement synchronization without using the shadow
593
mechanism. The Generic Kernel guarantees that this function is not
594
called before the corresponding call to \texttt{public\_block}.
595
 
596
%----------------------------------------------------------------------------
597
\subsubsection{\texttt{int (*public\_message)(LEVEL l, PID p, void *m);}}
598
%----------------------------------------------------------------------------
599
 
600
This function is called when the task\_message() primitive is
601
called by a task to send a message to the scheduler. Typical
602
messages are, for example, the end of an instance, or some kind of
603
signaling the task must do to a scheduling module, like a
604
checkpint mechanism.
605
 
606
The parameter p is the running task (that is, exec\_shadow). A
607
parameter m is passed, and it can be used to pass arbitrary
608
parameters to the scheduler. The value NULL is typically used by
609
the Kernel to signal the task\_endcycle primitive. An integer is
610
also returned to return a kind of status value to the calling
611
task.
612
 
613
%----------------------------------------------------------------------------
614
\subsubsection{The task\_endcycle primitive}
615
%----------------------------------------------------------------------------
616
 
617
A typical message that a task sends to a scheduling module is the
618
end of an instance, signaled using a task\_endcycle() primitive.
619
The implementation of that primitive is simply a
620
``task\_message(NULL,1)''. The task\_message should implement a
621
behavior similar to the one descried in the following paragraphs.
622
 
623
If the task does not have pending activations (or if the Module does not manage
624
them) the effect of the function is to disable the schedulability of the task
625
until an explicit activation is done by the user \footnote{using a
626
\texttt{task\_activate} call.} or an automatic reactivation done by the Module
627
(if the task is periodic).
628
 
629
If the task has some pending activations the function will
630
reactivate the task in a way similar to \texttt{public\_epilogue}.
631
 
632
The typical actions done by this function are listed below:
633
 
634
\begin{itemize}
635
\item If the task must be suspended, the task state is modified to
636
a ``parking'' state (\texttt{IDLE} or \texttt{SLEEP});
637
 
638
\item The
639
task may be removed from the ready queue (if it was not removed by
640
the \texttt{public\_dispatch});
641
 
642
\item Some resource reclaiming
643
algorithm may be implemented, because a task instance is finished;
644
 
645
\item Timer events related to the budget exhaustion and deadlines
646
are handled (for example events can be deleted, or postponed).
647
\end{itemize}
648
 
649
%----------------------------------------------------------------------------
650
\subsection{Private Functions}
651
%----------------------------------------------------------------------------
652
 
653
This section describes the private functions provided by a
654
scheduling module. Private functions are called only by other
655
scheduling modules, and never by the generic kernel, and they
656
represent the interface extorted by a scheduling module towards
657
other modules. Typical example of use of the private functions
658
are:
659
 
660
\begin{itemize}
661
 
662
\item an EDF module have to implement task activation and
663
unblocking simply inserting a task into the ready queue. For that
664
purpose, the functions public\_activate and public\_unblock
665
internally calls the private function private\_insert. Moreover,
666
the two functions can have some peculiarities. For example, the
667
implementer would like that public\_activate adds a deadline check
668
posting an OSLib event at the deadline time, whereas this is not
669
the case of public\_unblock, because the deadline used before have
670
to be used again. Deadline posting can be done into
671
public\_activate. private\_insert will simply insert the task into
672
its \char`\"{}private\char`\"{} queue.
673
 
674
\item an aperiodic server
675
wants to insert a task into the EDF queue. Again, the
676
public\_activate and the public\_unblock of the aperiodic server
677
will call the private\_insert of the EDF queue, that will insert
678
the task into its queue.
679
\end{itemize}
680
 
681
%----------------------------------------------------------------------------
682
\subsubsection{\texttt{void (*private\_insert )(LEVEL l, PID p, TASK\_MODEL *m);}}
683
%----------------------------------------------------------------------------
684
 
685
This function is used to insert a task into the Module. The
686
inserted task must have been already created through a call to the
687
\texttt{task\_create} primitive. When inserted, the behavior of
688
the function is as the task has been activated into the module
689
(e.g., the task goes into the ready queue). All the useful
690
informations passed to the task Model must be registered
691
internally to the Module.
692
 
693
%----------------------------------------------------------------------------
694
\subsubsection{\texttt{void (*private\_extract )(LEVEL l, PID p);}}
695
%----------------------------------------------------------------------------
696
 
697
This function terminates a chunk of a task previously inserted in the Module
698
using private\_insert. The typical effect of this function is to extract the
699
task from the internal queues and to delete the events generated for the task
700
(deadline, capacity, and so on). The function shall not insert the task
701
descriptor in the \texttt{freedesc} queue \footnote{public\_end() is responsible
702
for that\ldots{} }.
703
 
704
%----------------------------------------------------------------------------
705
\subsubsection{\texttt{void (*private\_dispatch)(LEVEL l, PID p, int nostop);}}
706
%----------------------------------------------------------------------------
707
 
708
This function is usually called by \texttt{public\_dispatch} to
709
inform the Master Module that a task inserted in it as a guest is
710
being dispatched. The semantic of the function is similar to that
711
of \texttt{public\_dispatch}.
712
 
713
%----------------------------------------------------------------------------
714
\subsubsection{\texttt{void (*private\_epilogue)(LEVEL l, PID p);}}
715
%----------------------------------------------------------------------------
716
 
717
This function is called by a Module to inform the Master Module
718
that a task inserted in it using private\_insert() is being
719
preempted or its budget has been exhausted.
720
 
721
%----------------------------------------------------------------------------
722
\subsubsection{\texttt{int (*private\_eligible)(LEVEL l, PID p);}}
723
%----------------------------------------------------------------------------
724
 
725
This function is usually called by public\_eligible to inform the
726
Master Module that a task inserted in it as a guest has been
727
chosen for scheduling. The semantic of the function is similar to
728
that of \texttt{public\_eligible}.
729
 
730
%----------------------------------------------------------------------------
731
\section{Registration Function}
732
%----------------------------------------------------------------------------
733
 
734
The code contained in a Module is composed by the function calls
735
(Level, Task and Guest Calls), and by a Registration Function that
736
must be called when the system starts to properly initialize the
737
kernel data structures. This registration function can be thought
738
as a C++ constructor for the Module.
739
 
740
A Module initialization typically consists of four parts:
741
 
742
\begin{itemize}
743
\item The first part allocates a level descriptor that will be
744
used to initialize the Module; To alloc a level descriptor, the
745
functions
746
 
747
\texttt{LEVEL~level\_alloc\_descriptor(void)} and
748
 
749
\texttt{RLEVEL~resource\_alloc\_descriptor(void)}
750
 
751
must be used. These functions take no arguments and return a free
752
descriptor to be used; \item The second part initializes the
753
function pointer of the level descriptor of a scheduling module;
754
\item The third part initializes the private data structures of
755
the Module, and possibly posts a function that has to be called
756
just after the system has gone in multitasking mode; \item The
757
fourth part executes the function posted in the third part.
758
\end{itemize}
759
The first three parts are written in the Registration Function,
760
which is called by the \texttt{\_\_kernel\_init\_\_} function
761
before the Kernel goes in multitasking mode.
762
 
763
In the \texttt{\_\_kernel\_init\_\_} function no Generic Kernel
764
primitives can be called. If there is a need to do that, a
765
registered function has to be called instead. For example, the
766
dummy task is created by the Dummy Module
767
(\texttt{kernel/modules/dummy.c}) through a registration function.
768
The main task is created in the same way by the Round Robin Module
769
(\texttt{kernel/modules/rr.c}).
770
 
771
%----------------------------------------------------------------------------
772
\subsection{Default values}
773
%----------------------------------------------------------------------------
774
 
775
In general, the scheduling modules needs only to register the
776
functions they want to redefine. For that reason, the public and
777
private functions have a default value, set by
778
\texttt{level\_alloc\_descriptor()}. Here is a list of these
779
default values:
780
 
781
\begin{description}
782
\item [private\_insert]Kernel Exception.
783
 
784
\item
785
[private\_extract]Kernel Exception.
786
 
787
\item
788
[private\_eligible]Returns 0 (that is, the task can be accepted
789
for scheduling).
790
 
791
\item [private\_dispatch]Kernel Exception.
792
 
793
\item
794
[private\_epilogue]Kernel Exception.
795
 
796
\item
797
[public\_scheduler]Returns -1 (that is, no task are ready to be
798
scheduled).
799
 
800
\item [public\_guarantee]Returns 1 (that is, the
801
system can be scheduled).
802
 
803
\item [public\_create]Returns -1 (that
804
is, the model can not be handled by the module).
805
 
806
\item
807
[public\_detach]Does nothing.
808
 
809
\item [public\_end]Kernel Exception.
810
 
811
\item [public\_eligible]Returns 0 (that is, the task can be
812
accepted for scheduling).
813
 
814
\item [public\_dispatch]Kernel
815
Exception.
816
 
817
\item [public\_epilogue]Kernel Exception.
818
 
819
\item
820
[public\_activate]Kernel Exception.
821
 
822
\item [public\_unblock]Kernel
823
Exception.
824
 
825
\item [public\_block]Kernel Exception.
826
 
827
\item
828
[public\_message]Kernel Exception.
829
\end{description}
830
 
831
%----------------------------------------------------------------------------
832
\section{Writing Conventions\label{SchedModules_Convenzioni}}
833
%----------------------------------------------------------------------------
834
 
835
This Section explains some conventions followed in writing the
836
Modules. They are useful to understand how to write new Modules
837
using the same style adopted in the Modules distributed with the
838
Kernel. They can be summarized as follows.
839
 
840
\begin{itemize}
841
\item Each Module is composed of two files, one file \texttt{.h}
842
and one file \texttt{.c}. The \texttt{.h} files are stored in the
843
\texttt{include/modules} directory; the \texttt{.c} files are
844
stored in the \texttt{kernel/modules} directory. \item Each
845
Registration Function registers only ONE level descriptor. In this
846
way the level at which a Module is registered can be found
847
inspecting the initialization file. The level descriptor number is
848
usually returned by the register function. \item The Task Models
849
used by the Modules are listed in the
850
\texttt{include/kernel/model.h} file. \item The names of the
851
internal functions are defined as \texttt{static} and are in the
852
form \texttt{MODULENAME\_FUNCTIONNAME}, where \texttt{MODULENAME}
853
is the name of the \texttt{.c} file where the Module code is
854
written. \item A Module can export some functions to implement a
855
specific behavior; these functions have a first parameter of type
856
\texttt{LEVEL}, in order to retrieve the Module data structures.
857
An application that relies on a specific Module configuration can
858
use the functions under the assumption that the Application knows
859
the level at which the Module is registered. \item The prototypes
860
of the functions exported by a Module (registration function plus
861
other functions if present) have to be included in the \texttt{.h}
862
file. \item The Modules should not use global data, because
863
different instances of a Module can be registered at the same time
864
in the system.
865
\end{itemize}
866
In general writing a new Scheduling Module requires the creation
867
of new files. To simplify the distribution and the integration of
868
new modules in the Generic Kernel no modifications have to be made
869
to the standard distribution of the Kernel. Beside that, a few
870
rules of common sense have to be followed:
871
 
872
\begin{itemize}
873
\item A new Scheduling Module should consist of only one
874
\texttt{.h} file and only one \texttt{.c} file. Modules composed
875
of many files should contain an explanation in their
876
documentation. \item Together with the Scheduling Module a system
877
designer should provide:
878
 
879
\begin{itemize}
880
\item an initialization file (similar to those present in the
881
\texttt{kernel/init} directory) that shows how the new Module must
882
be initialized; \item at least one test program showing the
883
functionality of the Module;
884
\end{itemize}
885
\item New data definitions (for example new Task Models, new
886
\texttt{pclass}, version and exception values) used by the new
887
Modules should be inserted into the \texttt{.h} file of the
888
Module. New constants should be different from the others
889
contained into the default distribution.
890
\end{itemize}
891
A template example of a Scheduling Module can be found on the
892
S.Ha.R.K. web site. Examples of third-party scheduling modules can
893
be dound into the demos directory (e.g., demos/static,
894
demos/edfact, demos/cash).