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{Examples}
3
%----------------------------------------------------------------------------
4
 
5
The application of the proposed approach is presented in this
6
chapter, on three meaningful examples, by showing the code of the
7
scheduling and of the resource modules. The examples are really
8
implemented in the Kernel, so these remarks can also be used as
9
documentation.
10
 
11
%----------------------------------------------------------------------------
12
\section{SIMPLEEDF (Earliest Deadline First) Scheduling Module}
13
%----------------------------------------------------------------------------
14
 
15
This section describes an implementation of EDF with the following
16
characteristics:
17
 
18
\begin{itemize}
19
\item Support for periodic and sporadic tasks;
20
\item Support for release offsets and relative deadlines less than the period;
21
\item On-line guarantee using the utilization factor paradigm;
22
\item Temporal isolation implemented using the \texttt{CONTROL\_CAP} flag;
23
\item A number of different deadline/WCET/activation violation options.
24
\end{itemize}
25
 
26
Typically this module is registered at Level 0; in effect the
27
guarantee algorithm works only if the Module can use all the
28
bandwidth of the system. In order to schedule background periodic
29
tasks, a soft task model should be used with a Scheduling Module
30
like the CBS Scheduling Module. The Module described in this
31
section is contained in \texttt{modules/edf.c}.
32
 
33
%----------------------------------------------------------------------------
34
\subsection{State transition diagram}
35
%----------------------------------------------------------------------------
36
 
37
The state transition diagram for an EDF task is shown in Figure
38
\ref{Examples_EDF_Stati}.
39
 
40
\begin{figure}
41
\begin{center}
42
\includegraphics[width=1.0\columnwidth]{images/example_EDF_status.eps}
43
\end{center}
44
\label{Examples_EDF_Stati}
45
\caption{State transition diagram for an EDF task. (For simplicity, some
46
transitions have been excluded.)}
47
\end{figure}
48
 
49
The states whose name start with \texttt{EDF\_} are internal
50
Module statuses. The event names are reported near the arcs; in
51
particular the names of the timer events are written within
52
parentheses. The different states have the following meanings:
53
 
54
\begin{description}
55
\item [\texttt{FREE}]Before creation, and after destruction, the
56
task is in this state.
57
 
58
\item [\texttt{SLEEP}]The task waits in this state for an explicit activation.
59
 
60
\item [\texttt{EDF\_READY}]This is the classic ready state where the task has to
61
wait until it has the highest priority (i.e., the earliest deadline).
62
 
63
\item [\texttt{EXE}]This is the state when the task is executing.
64
 
65
\item [\texttt{EDF\_WAIT}]This is the state of a sporadic task after finishing
66
an instance, waiting for the endperiod event to arrive.
67
 
68
\item [\texttt{EDF\_IDLE}]This is the
69
state of a periodic task after finishing an instance, waiting for
70
the endperiod event to arrive. An activated task with a release
71
offset is also put in this state, waiting for the first period to
72
arrive.
73
 
74
\item [\texttt{EDF\_ZOMBIE}]This is the state where a task
75
is put when it terminates correctly. The allocated bandwidth is
76
freed when the endperiod event is fired.
77
\end{description}
78
 
79
%----------------------------------------------------------------------------
80
\subsection{Level
81
descriptor}
82
%----------------------------------------------------------------------------
83
 
84
The EDF Module extends the \texttt{level\_des} structure that
85
contains the interface exported by a generic Scheduling Module.
86
The extended data structure, \texttt{EDF\_level\_des,} contains
87
the following fields:
88
 
89
\begin{description}
90
\item [\texttt{flags}]This variable stores the flags passed to the
91
module at registration time. The following flags are defined:
92
 
93
\begin{description}
94
\item [\texttt{EDF\_ENABLE\_DL\_CHECK}]If set, the module will
95
keep track of task deadlines by internal deadline timers. The
96
behavior in case of a deadline overrun depends on the
97
\texttt{EDF\_ENABLE\_DL\_EXCEPTION} flag, see below.
98
 
99
\item
100
[\texttt{EDF\_ENABLE\_WCET\_CHECK}]If set, the module will keep
101
track of task execution times by enabling the CONTROL\_CAP flag
102
for the tasks in the generic kernel.
103
 
104
\item
105
[\texttt{EDF\_ENABLE\_DL\_EXCEPTION}]If set, the module will raise
106
an exception if a deadline overrun occurs. If not set, the
107
\texttt{dl\_miss} counter for the task is increased every time a
108
deadline overrun occurs.
109
 
110
\item
111
[\texttt{EDF\_ENABLE\_WCET\_EXCEPTION}]If set, the module will
112
raise an exception if an execution-time overrun occurs. If not
113
set, the \texttt{wcet\_miss} counter for the task is increased
114
every time an execution-time overrun occurs.
115
 
116
\item
117
[\texttt{EDF\_ENABLE\_ACT\_EXCEPTION}]If set, the module will
118
raise an exception if a task is activated more often than its
119
declared minimum interarrival time. If not set, the \texttt{nskip}
120
counter for the task is increased instead.
121
\end{description}
122
 
123
\item [\texttt{ready}]This is an \texttt{IQUEUE} variable used to
124
handle the ready queue. \item [\texttt{U}]This variable is used to
125
store the sum of the reserved bandwidth for the tasks owned by the
126
Module. \item [\texttt{tvec}]A vector of EDF task descriptors,
127
\texttt{EDF\_task\_des}, that defines a number of additional
128
variables for each task, see below.
129
\end{description}
130
 
131
%----------------------------------------------------------------------------
132
\subsection{Task
133
descriptor}
134
%----------------------------------------------------------------------------
135
 
136
The EDF module introduces a number of additional task variables.
137
They are collected in a \texttt{EDF\_task\_des} structure for each
138
task:
139
 
140
\begin{description}
141
\item [\texttt{flags}]Flags that store some additional type/status
142
information about the task. The following flags are defined:
143
 
144
\begin{description}
145
\item [\texttt{EDF\_FLAG\_SPORADIC}]The task is sporadic. This
146
influences some state transitions, see Figure
147
\ref{Examples_EDF_Stati}.
148
 
149
\item
150
[\texttt{EDF\_FLAG\_SPOR\_LATE}]The task is sporadic and has
151
experienced a period overrun. (This is only possible if the
152
EDF\_ENABLE\_DL\_EXCEPTION level flag is not set.) When finished,
153
the task should go directly to the SLEEP state.
154
\end{description}
155
 
156
\item [\texttt{period}]The period or minimum interarrival time of
157
the task.
158
 
159
\item [\texttt{rdeadline}]The relative deadline of the
160
task. Currently, only $D\leq T$ is allowed.
161
 
162
\item
163
[\texttt{offset}]The release offset, relative to the activation
164
time of the task. \item [\texttt{release}]This variable stores the
165
release time of the current instance.
166
 
167
\item
168
[\texttt{adeadline}]This variable stores the absolute deadline
169
associated with the most recent task activation.
170
 
171
\item
172
[\texttt{dltimer}]A handle to the task deadline timer.
173
 
174
\item
175
[\texttt{eop\_timer}]A handle to the task end-of-period timer.
176
 
177
\item [\texttt{dl\_miss}]Counter for the number of missed
178
deadlines.
179
 
180
\item [\texttt{wcet\_miss}]Counter for the number of
181
execution-time overruns.
182
 
183
\item [\texttt{act\_miss}]Counter for the
184
number of skipped activations.
185
 
186
\item [\texttt{nact}]The current
187
number of queued activations (periodic tasks only).
188
\end{description}
189
 
190
%----------------------------------------------------------------------------
191
\subsection{Module
192
internal event handlers}
193
%----------------------------------------------------------------------------
194
 
195
The module uses internal kernel events (one-shot timers) to handle
196
the release of tasks, deadline overruns, etc. When an event is
197
posted by the module, an event handler is specified, and the PID
198
of the relevant task is passed as parameter. For instance, the
199
\texttt{endperiod} event is handled by the following function:
200
 
201
%----------------------------------------------------------------------------
202
\subsubsection{\texttt{static
203
void EDF\_timer\_endperiod(void *par) }}
204
%----------------------------------------------------------------------------
205
 
206
The first thing to do when handling an event is to recover the
207
information about the Module that posted the event. This can be
208
done with the following statements:
209
 
210
\bigskip{}
211
\texttt{PID p = (PID) par;}
212
 
213
\texttt{EDF\_level\_des *lev =}
214
 
215
\begin{center}\texttt{(EDF\_level\_des
216
*)level\_table{[}proc\_table{[}p{]}.task\_level{]};}\end{center}
217
\bigskip{}
218
 
219
The generic kernel task fields can be referenced as
220
\texttt{proc\_table{[}p{]}.name}; the internal data of the Module
221
can be referenced as \texttt{lev-}\texttt{\emph{>}}\texttt{field}.
222
The EDF task descriptor can be referenced as
223
 
224
\bigskip{}
225
\texttt{EDF\_task\_des *td = \&lev->tvec{[}p{]}; }
226
\bigskip{}
227
 
228
and the EDF task fields can then be referenced as
229
\texttt{td-}\texttt{\emph{>}}\texttt{field}.
230
 
231
By studying the state transition diagram, we see that different
232
actions should be taken depending on the state of the task:
233
 
234
\begin{itemize}
235
\item If the task state is \texttt{EDF\_ZOMBIE,} the task is
236
inserted into the \texttt{freedesc} queue and the allocated
237
bandwidth is freed;
238
 
239
\item If the state is \texttt{EDF\_WAIT,} the
240
task state is set to \texttt{SLEEP}, so the sporadic task can be
241
reactivated;
242
 
243
\item If the state is \texttt{EDF\_IDLE} and the task
244
is periodic, it is reactivated by a call to the
245
\texttt{EDF\_intern\_release} function. This involves posting a
246
deadline event (if \texttt{EDF\_ENABLE\_DL\_CHECK} is set);
247
inserting the task in the ready queue; increasing the absolute
248
deadline; and telling the kernel that it may need to reschedule by
249
calling \texttt{event\_need\_reschedule.}
250
 
251
\item If the state is
252
\texttt{EDF\_IDLE} and the task is sporadic, it is marked as late.
253
\end{itemize}
254
The module also contains the following event handlers:
255
 
256
static void EDF\_timer\_deadline(void *par)
257
 
258
static void EDF\_timer\_offset(void *par)
259
 
260
static void EDF\_timer\_guest\_deadline(void *par)
261
 
262
%----------------------------------------------------------------------------
263
\subsection{Public Functions}
264
%----------------------------------------------------------------------------
265
 
266
The Module redefines the Level Calls interface. In the following
267
paragraphs the implementation of these functions is described.
268
 
269
All the functions of the interface receive a parameter of type
270
\texttt{LEVEL} that can be used in a way similar to the parameter
271
passed to the event functions to find all the data structures
272
needed.
273
 
274
%----------------------------------------------------------------------------
275
\subsubsection{\texttt{PID
276
EDF\_public\_scheduler(LEVEL l);}}
277
%----------------------------------------------------------------------------
278
 
279
This is the Module scheduler that, as all good schedulers, simply
280
returns the first task in the ready queue without extracting it.
281
 
282
%----------------------------------------------------------------------------
283
\subsubsection{\texttt{int
284
EDF\_public\_guarantee(LEVEL l, bandwidth\_t *freebandwidth);}}
285
%----------------------------------------------------------------------------
286
 
287
The on-line guarantee function simply verifies if there is enough
288
free bandwidth for scheduling its tasks. If so, the free bandwidth
289
is decremented by the amount used by the Module, and it returns
290
that the task set can be guaranteed.
291
 
292
If the guarantee is called after a task creation in the Module, it
293
can be the case that the new task, with all the other tasks
294
already guaranteed by the Module, uses a bandwidth greater than 1
295
(note that the U field can store only numbers in the
296
{[}0\ldots{}1{]} interval). In this case, in the function
297
\texttt{EDF\_public\_create} a flag is set forcing the guarantee
298
algorithm to fail.
299
 
300
%----------------------------------------------------------------------------
301
\subsubsection{\texttt{int EDF\_public\_create(LEVEL l, PID p, TASK\_MODEL *m);}}
302
%----------------------------------------------------------------------------
303
 
304
The function checks if the Model passed as second parameter can be
305
handled. In this case, the Module handles all the
306
HARD\_TASK\_MODELs that have a correct \texttt{pclass} value and a
307
wcet and a period != 0. This function sets the \texttt{period},
308
\texttt{flag}, and \texttt{wcet} internal fields of the newly
309
created task. The function sets also the \texttt{CONTROL\_CAP}
310
flag to inform the Generic Kernel that the execution time have to
311
be controlled. Finally, the function allocates the system
312
bandwidth in such a way that it can be checked by the guarantee
313
algorithm. If the bandwidth allocated for the already guaranteed
314
tasks plus the new one is greater than 1, a flag is set to signal
315
that the guarantee algorithm must fail.
316
 
317
%----------------------------------------------------------------------------
318
\subsubsection{\texttt{void EDF\_public\_detach(LEVEL l, PID p);}}
319
%----------------------------------------------------------------------------
320
 
321
This function simply reclaims the bandwidth used by the task
322
allocated by \texttt{EDF\_public\_create}, disabling the flag set
323
by \texttt{EDF\_public\_create} when the guarantee is impossible
324
(U>1).
325
 
326
%----------------------------------------------------------------------------
327
\subsubsection{\texttt{int EDF\_public\_eligible(LEVEL l, PID p);}}
328
%----------------------------------------------------------------------------
329
 
330
This function simply returns 0 because the EDF tasks are always
331
eligibles. In fact, the EDF Module does not use the guest
332
functions of another Module to handle its tasks.
333
 
334
%----------------------------------------------------------------------------
335
\subsubsection{\texttt{void EDF\_public\_dispatch(LEVEL l, PID p, int nostop);}}
336
%----------------------------------------------------------------------------
337
 
338
To dispatch an EDF task, the task itself must be removed from the
339
ready queue. The capacity handling (like the capacity event post)
340
is automatically done by the Generic Kernel.
341
 
342
%----------------------------------------------------------------------------
343
\subsubsection{\texttt{void EDF\_public\_epilogue(LEVEL l, PID p);}}
344
%----------------------------------------------------------------------------
345
 
346
The function must suspend the running task because it has been preempted or
347
because if has finished his capacity. Therefore, the first thing to be done is
348
the check of the available capacity. If it is exhausted an exception is raised
349
and the task is put into the \texttt{EDF\_WCET\_VIOLATED} \footnote{The task
350
shall not be extracted by any queue because the task was extracted by the
351
\texttt{EDF\_public\_dispatch} function.} state.
352
 
353
When the task has not consumed all of its capacity it is inserted
354
back into the ready queue.
355
 
356
%----------------------------------------------------------------------------
357
\subsubsection{\texttt{void EDF\_public\_activate(LEVEL l, PID p, struct timespec *t);}}
358
%----------------------------------------------------------------------------
359
 
360
This function simply activates the task, inserting it into the
361
ready queue. A task can be activated only if it is in the
362
\texttt{SLEEP} or in the \texttt{EDF\_WCET\_VIOLATED} state. If
363
the task is in the \texttt{EDF\_WAIT} state it means that the task
364
is a sporadic task activated too early, so an exception is raised.
365
 
366
The function executes the following steps:
367
 
368
\begin{itemize}
369
\item A suitable deadline is computed for the task;
370
 
371
\item The task
372
is inserted into the ready queue;
373
 
374
\item A deadline event is posted
375
for the task.
376
\end{itemize}
377
 
378
%----------------------------------------------------------------------------
379
\subsubsection{\texttt{void EDF\_public\_unblock(LEVEL l, PID p);}}
380
%----------------------------------------------------------------------------
381
 
382
The function simply inserts the task into into the ready queue.
383
The task was blocked on a synchronization by a call to the
384
function \texttt{EDF\_public\_block}.
385
 
386
%----------------------------------------------------------------------------
387
\subsubsection{\texttt{void EDF\_public\_block(LEVEL l, PID p);}}
388
%----------------------------------------------------------------------------
389
 
390
The function implements a synchronization block. The function
391
simply does nothing, because:
392
 
393
\begin{itemize}
394
\item The task was already extracted from the ready queue;
395
 
396
\item
397
The capacity event is handled by the Generic Kernel;
398
 
399
\item The
400
task state is set by the calling primitive;
401
 
402
\item The deadline
403
does not need modifications.
404
\end{itemize}
405
 
406
%----------------------------------------------------------------------------
407
\subsubsection{\texttt{int EDF\_public\_message(LEVEL l, PID p, void *m);}}
408
%----------------------------------------------------------------------------
409
 
410
This function implement only the task\_endcycle behavior, doing
411
two things:
412
 
413
\begin{itemize}
414
\item The \texttt{wcet} of the task is refilled, since the task
415
has finished its instance;
416
 
417
\item The task state is set to
418
\texttt{EDF\_IDLE} or \texttt{EDF\_WAIT}, waiting the deadline
419
arrival.
420
\end{itemize}
421
 
422
%----------------------------------------------------------------------------
423
\subsubsection{\texttt{void EDF\_public\_end(LEVEL l, PID p);}}
424
%----------------------------------------------------------------------------
425
 
426
The function should erase all the information about the task in
427
the data structure of the Module. It simply sets the task state to
428
\texttt{EDF\_ZOMBIE}. The deallocation of the bandwidth used by
429
the task and the freeing of the task descriptor is performed while
430
handling the deadline event.
431
 
432
%----------------------------------------------------------------------------
433
\subsection{Private Functions}
434
%----------------------------------------------------------------------------
435
 
436
The EDF Module can accept a JOB\_TASK\_MODEL as the Model for the
437
Guest Tasks. This Model does not provide information about the
438
time that the task will execute. This means that the EDF Module
439
does not check the execution time of the task. It must be checked
440
by the Module that inserts the tasks as guest tasks. In the
441
following paragraphs the guest calls are described.
442
 
443
%----------------------------------------------------------------------------
444
\subsubsection{\texttt{int EDF\_private\_insert(LEVEL l, PID p, TASK\_MODEL *m);}}
445
%----------------------------------------------------------------------------
446
 
447
This function is called by a generic Aperiodic Server Module to
448
insert a task into the EDF Module.
449
 
450
The function simply fills the private data structures of the EDF
451
Module with the task parameters passed through the Task Model. No
452
guarantee is done on the guest tasks (the guarantee of a guest
453
task is a responsibility of the Module that calls this function).
454
 
455
%----------------------------------------------------------------------------
456
\subsubsection{\texttt{void EDF\_private\_dispatch(LEVEL l, PID p, int nostop);}}
457
%----------------------------------------------------------------------------
458
 
459
This function is typically called by the \texttt{task\_dispatch}
460
Task Call of the Module that inserts the task as guest task. The
461
effect of the call is to extract a task from the ready queue, so
462
it is identical to the \texttt{task\_dispatch} Task Call.
463
 
464
%----------------------------------------------------------------------------
465
\subsubsection{\texttt{void EDF\_private\_epilogue(LEVEL l, PID p);}}
466
%----------------------------------------------------------------------------
467
 
468
This function is called when a task is preempted (no capacity are
469
handled by the Module). The function simply inserts the task into
470
the ready queue.
471
 
472
%----------------------------------------------------------------------------
473
\subsubsection{\texttt{void EDF\_guest\_activate(LEVEL l, PID p);}}
474
%----------------------------------------------------------------------------
475
 
476
This function is called when the Module that inserts the task in
477
the system through the EDF\_private\_insert wants to activate it.
478
The effect of this function is to insert the task into the ready
479
queue and to post a deadline event if the deadline miss should be
480
detected for the task (a flag that specifies if the Module should
481
generate a deadline is given in the JOB\_TASK\_MODEL.
482
 
483
%----------------------------------------------------------------------------
484
\subsubsection{\texttt{void EDF\_private\_extract(LEVEL l, PID p);}}
485
%----------------------------------------------------------------------------
486
 
487
This function is called by a Module when it wants to terminate a
488
task inserted as guest. This function is not called only at task
489
termination, but also when the Module has to change some
490
parameters for the task (for example, when a deadline should be
491
postponed).
492
 
493
The function has to erase all references to the task in the
494
private data structures of the EDF Module. Note that this function
495
can be called also when the task is not in the EXE state, so all
496
task states should be checked for a correct behavior.
497
 
498
%----------------------------------------------------------------------------
499
\subsection{Additional Functions exported by the Module}
500
%----------------------------------------------------------------------------
501
 
502
Finally, the EDF Module exports two functions that can be used by
503
the user.
504
 
505
The first function is the registration function, used to register
506
the Module into the system and to init the internal data
507
structures.
508
 
509
The second function, \texttt{EDF\_usedbandwidth}, can be used to
510
get the bandwidth actually used by the Module. That function needs
511
as a parameter the level at which an EDF Module is registered, so
512
all the private data structures can be read. Note that giving the
513
level of a Module in an application should not be considered a
514
violation of the independence of an Application to the Registered
515
Modules. If an application wants to know a specific data in a
516
Module, it has to know in what level the Module is Registered...
517
 
518
%----------------------------------------------------------------------------
519
\section{PS (Polling Server) Scheduling Module}
520
%----------------------------------------------------------------------------
521
 
522
In this Section will be described an implementation of a PS Module
523
that have the following characteristics:
524
 
525
\begin{itemize}
526
\item Soft Aperiodic Task support;
527
 
528
\item On-line guarantee using
529
the utilization factor paradigm;
530
 
531
\item Temporal isolation
532
implemented without the \texttt{CONTROL\_CAP} flag.
533
 
534
\item Feature
535
that allows to use the idle time left by the Modules registered at
536
lower level numbers;
537
 
538
\item Support for pending task activations;
539
 
540
\item Compatibility with static (RM) and dynamic (EDF) algorithms.
541
\end{itemize}
542
 
543
This Module implements an aperiodic server that inserts its tasks
544
into another Scheduling Module, without having any information on
545
how the Master Module is implemented. The module described in this
546
section is contained in \texttt{modules/ps}.
547
 
548
%----------------------------------------------------------------------------
549
\subsection{Transition state diagram}
550
%----------------------------------------------------------------------------
551
 
552
In Figure \ref{Examples_PS_Status} the state diagram of a task is
553
showed.
554
 
555
\begin{figure}
556
\begin{center}
557
\includegraphics[width=1.0\columnwidth]{images/example_PS_status.eps}
558
\end{center}
559
\label{Examples_PS_Status}
560
\caption{State Diagram of a Task scheduled with the PS Module.}
561
\end{figure}
562
 
563
 
564
The Module introduce only one state, \texttt{PS\_WAIT}. This is
565
the state in which a task waits to be inserted in the ``ready
566
queue''. The server queue is handled in a FIFO way. The other
567
states in which a Module will go are internal states of the Master
568
Module.
569
 
570
%----------------------------------------------------------------------------
571
\subsection{Private Data structures}
572
%----------------------------------------------------------------------------
573
 
574
The PS Module redefines the \texttt{level\_des} structures adding
575
some private data structures, listed below:
576
 
577
\begin{description}
578
\item [\texttt{nact}]This array is used to track the pending
579
activations of a task handled by the Module. Each task element has
580
a value of\texttt{-1} (if the task skips the pending activations)
581
or a value \texttt{>=0} (that is, the value of pending activations
582
for the task);
583
 
584
\item [\texttt{lastdline}]This field is used to
585
store the deadline used by the Polling Server;
586
 
587
\item
588
[\texttt{period}]This field stores the reactivation period of the
589
server;
590
 
591
\item [\texttt{Cs}]This field stores the Maximum capacity
592
of the server;
593
 
594
\item [\texttt{availCs}]This field stores the
595
computation time available for the server at a given time. The
596
capacity is updated when the task handled by the Module is
597
scheduled by the Master Module, or when a task handled by the
598
Module is dispatched following the shadow chain and the server is
599
not scheduling in background;
600
 
601
\item [\texttt{wait}]This field is
602
the wait queue, where the tasks wait their turn to be served by
603
the Polling Server;
604
 
605
item [\texttt{activated}]This field is the
606
PID of the task currently inserted into the Scheduling Module. The
607
server inserts in the Master Module maximum one Module at a time;
608
 
609
\item [\texttt{flags}]The flag field is used to store some
610
informations passed when the Module was registered, like for
611
example the implemented guarantee algorithm (RM or EDF). This
612
field is used also to know if the server is executing a task in
613
background;
614
 
615
\item [\texttt{U}]This field is used to store an
616
information of the used bandwidth by the task handled by the
617
Module.
618
 
619
\item [\texttt{scheduling\_level}]This field stores the
620
level of the Host Module.
621
\end{description}
622
 
623
%----------------------------------------------------------------------------
624
\subsection{Internal Module Functions}
625
%----------------------------------------------------------------------------
626
 
627
The PS Module needs to define some internal functions. These
628
functions are called to handle the internal events posted by the
629
Module. Many of these functions are declared \texttt{static}, so
630
they are not visible externally to the Module.
631
 
632
%----------------------------------------------------------------------------
633
\subsubsection{\texttt{void PS\_activation(PS\_level\_des *lev);}}
634
%----------------------------------------------------------------------------
635
 
636
This function is an inline function and it handles the activation
637
of a task into a Master Module. In particular:
638
 
639
\begin{itemize}
640
\item It inits a Job Task Model that will be passed to the Master
641
Module with the period and the deadline of the Polling Server;
642
 
643
\item It creates and activates through the guest calls the task
644
indexed by the private field \texttt{lev->activated}.
645
\end{itemize}
646
 
647
%----------------------------------------------------------------------------
648
\subsubsection{\texttt{void PS\_deadline\_timer(void *a);}}
649
%----------------------------------------------------------------------------
650
 
651
This function implements the periodic reactivation of the Polling
652
Server. In particular:
653
 
654
\begin{itemize}
655
\item a new deadline is computed and a new deadline event is
656
posted;
657
 
658
\item the Server capacity is reloaded to the maximum value
659
if the available capacity was positive, to a value less than the
660
maximum (a ``recharge'' (sum) is done) if negative;
661
 
662
\item If the
663
recharge turn the available capacity positive, a waiting task is
664
activated, or the capacity available is depleted.
665
\end{itemize}
666
 
667
%----------------------------------------------------------------------------
668
\subsection{Public Functions}
669
%----------------------------------------------------------------------------
670
 
671
All the functions of the interface receives a LEVEL parameter that
672
can be used in a way similar to the parameter passed to the event
673
functions to get all the private data of the Module.
674
 
675
%----------------------------------------------------------------------------
676
\subsubsection{\texttt{PID PS\_level\_scheduler(LEVEL l);}}
677
%----------------------------------------------------------------------------
678
 
679
This scheduler is used by the Module if the Module is registered
680
specifying that it can not use the idle time left by other
681
Modules. It always return \texttt{NIL} (meaning that the module
682
has nothing to schedule).
683
 
684
%----------------------------------------------------------------------------
685
\subsubsection{\texttt{PID PS\_level\_schedulerbackground(LEVEL l);}}
686
%----------------------------------------------------------------------------
687
 
688
This scheduler is used by the Module if the Module is registered
689
specifying that it can use the idle time left by other Modules. It
690
sets a flag in the \texttt{flags} field to remember that the
691
Module is scheduling a task in background, after that it returns
692
the first task in the wait queue. The scheduler is disactived in
693
case the task scheduled by the server is blocked on a
694
synchronization (look at the function \texttt{PS\_public\_block}).
695
 
696
%----------------------------------------------------------------------------
697
\subsubsection{\texttt{int PS\_level\_guaranteeRM(LEVEL l, bandwidth\_t *freebandwidth);}}
698
%----------------------------------------------------------------------------
699
 
700
%----------------------------------------------------------------------------
701
\subsubsection{\texttt{int PS\_level\_guaranteeEDF(LEVEL l, bandwidth\_t *freebandwidth);}}
702
%----------------------------------------------------------------------------
703
 
704
These two functions implements the internal guarantee of the
705
Module, simply decrementing when possible the available bandwidth.
706
the difference between the two functions is that the first
707
function allow to schedule until a used bandwidth of 0.69, and the
708
second one allow a scheduling limit of 1. The structure of this
709
function is similar to that of \texttt{EDF\_public\_guarantee},
710
except that the guarantee is done on the server and not on each
711
task handled by the server..
712
 
713
%----------------------------------------------------------------------------
714
\subsection{Task Calls}
715
%----------------------------------------------------------------------------
716
 
717
%----------------------------------------------------------------------------
718
\subsubsection{\texttt{int PS\_public\_create(LEVEL l, PID p, TASK\_MODEL *m);}}
719
%----------------------------------------------------------------------------
720
 
721
This functions checks if the Task Model passed can be handled by
722
the Module. The Module simply handles all the Soft Task Models
723
that specify a periodicity equal to APERIODIC, ignoring each
724
additional parameters. This function sets the \texttt{nact} field
725
on the new task according to the requirements of the task model.
726
The function does not set the flag \texttt{CONTROL\_CAP}.
727
 
728
%----------------------------------------------------------------------------
729
\subsubsection{\texttt{void PS\_public\_detach(LEVEL l, PID p);}}
730
%----------------------------------------------------------------------------
731
 
732
This function does nothing, because in the
733
\texttt{PS\_public\_create} function no dynamic data structures
734
were allocated, and because the tasks served by do not require
735
individual guarantee (the guarantee is done for the whole Server).
736
 
737
%----------------------------------------------------------------------------
738
\subsubsection{\texttt{int PS\_public\_eligible(LEVEL l, PID p);}}
739
%----------------------------------------------------------------------------
740
 
741
The function always returns 0 because the PS tasks are always
742
eligible.
743
 
744
%----------------------------------------------------------------------------
745
\subsubsection{\texttt{void PS\_public\_dispatch(LEVEL l, PID p, int nostop);}}
746
%----------------------------------------------------------------------------
747
 
748
A task can be dispatched if it is in the wait queue or if it is
749
inserted into the Master Module.
750
 
751
In the first case the task is extracted from the \texttt{wait}
752
queue, in the latter case the private function
753
\texttt{private\_dispatch} is called to signal to the Master
754
Module to dispatch the task.
755
 
756
Then, a capacity event is generated (only if the parameter
757
\texttt{nostop} is \texttt{0} (the parameter is 0 if there is no
758
substitution due to the shadow chain mechanism). The capacity
759
event is created using the \texttt{cap\_timer} field. In this way
760
the event will be removed by the Generic Kernel.
761
 
762
%----------------------------------------------------------------------------
763
\subsubsection{\texttt{void PS\_public\_epilogue(LEVEL l, PID p);}}
764
%----------------------------------------------------------------------------
765
 
766
This function implements the suspension of the running task due to
767
a preemption or a capacity exhaustion.
768
 
769
First, the function updates the server capacity using the
770
\texttt{cap\_lasttime} and \texttt{schedule\_time} variables. If
771
the server capacity is exhausted, the task that is inserted into
772
the Master Module (if the task is not scheduled in background)
773
terminates with a \texttt{private\_extract}, and then it is
774
inserted in the wait queue.
775
 
776
If the server capacity is not exhausted, there are two cases: if
777
the Module is scheduling a task in background, the task will be
778
inserted on the head of the wait queue, otherwise the
779
\texttt{private\_epilogue} function will be called to signal the
780
Master Module a task preemption.
781
 
782
%----------------------------------------------------------------------------
783
\subsubsection{\texttt{void PS\_public\_activate(LEVEL l, PID p);}}
784
%----------------------------------------------------------------------------
785
 
786
This function activates a task. If the task passed as parameter is
787
the task currently inserted in the Master Module, or if the task
788
is already inserted into the \texttt{wait} queue, the activation
789
is stored and the nact field is incremented (only if the task has
790
specified in the task model passed at its creation to save the
791
activations).
792
 
793
Otherwise the normal activation actions are done:
794
 
795
\begin{itemize}
796
\item the field \texttt{request\_time} of the task descriptor is
797
updated; \item The task is activated using the internal
798
\texttt{PS\_activation} function if there aren't tasks in the
799
Module and the server capacity is positive, otherwise the task is
800
queued into the wait queue.
801
\end{itemize}
802
 
803
%----------------------------------------------------------------------------
804
\subsubsection{\texttt{void PS\_public\_block(LEVEL l, PID p);}}
805
%----------------------------------------------------------------------------
806
 
807
The function should implement the synchronization blocking. The
808
function should block the whole server, calling eventually the
809
\texttt{private\_extract} guest call on the Master Module and
810
setting the \texttt{PS\_BACKGROUND\_BLOCK} flag to block every
811
background schedule.
812
 
813
%----------------------------------------------------------------------------
814
\subsubsection{\texttt{void PS\_public\_unblock(LEVEL l, PID p);}}
815
%----------------------------------------------------------------------------
816
 
817
The function should reactivate a blocked task. The task
818
reactivation consists of its insertion into the \texttt{wait}
819
queue and of the reset of the flags set in the
820
\texttt{public\_block} function.
821
 
822
%----------------------------------------------------------------------------
823
\subsubsection{\texttt{int PS\_public\_endcycle(LEVEL l, PID p, void *m);}}
824
%----------------------------------------------------------------------------
825
 
826
The function implement the task\_endcycle behavior and does the
827
following steps:
828
 
829
\begin{itemize}
830
 
831
\item The server capacity is updated, or the background scheduling
832
feature is disabled if it was active;
833
 
834
\item The task was extracted
835
from the Master Module through a call to the private function
836
\texttt{private\_extract}, otherwise it is extracted from the
837
\texttt{wait} queue;
838
 
839
\item If the task has some pending
840
activations, it is inserted at the end of the \texttt{wait} queue,
841
otherwise the task state is set to \texttt{SLEEP}.
842
 
843
\item If
844
possible a new task is extracted from the top of the \texttt{wait}
845
queue, through a call to the function \texttt{PS\_activation};
846
\end{itemize}
847
 
848
%----------------------------------------------------------------------------
849
\subsubsection{\texttt{void PS\_public\_end(LEVEL l, PID p);}}
850
%----------------------------------------------------------------------------
851
 
852
The function directly insert the task into the \texttt{freedesc}
853
queue.
854
 
855
%----------------------------------------------------------------------------
856
\subsection{Private functions}
857
%----------------------------------------------------------------------------
858
 
859
The private functions are not defined (the defaults are used).
860
 
861
%----------------------------------------------------------------------------
862
\subsection{Functions exported by the Module}
863
%----------------------------------------------------------------------------
864
 
865
Finally, the PS Module exports two functions that can be used by
866
the user.
867
 
868
The first function is the registration function, used to register
869
the Module in the system and to init the internal data structures.
870
This function registers also a initialization function that posts
871
the first server deadline event. This event cannot be created in
872
the registration function because the registration function is
873
called when the OS Lib is not initialized yet.
874
 
875
The second function, \texttt{PS\_usedbandwidth}, can be used to
876
obtain the allocated bandwidth of the Module, and it is similar to
877
the function \texttt{EDF\_usedbandwidth}.
878
 
879
 
880
%----------------------------------------------------------------------------
881
\section{PI (Priority Inheritance) Resource Module}
882
%----------------------------------------------------------------------------
883
 
884
In this Section an implementation of the shared resource access
885
protocol Priority Inheritance (PI) \cite{Sha90} is described; it
886
has the following characteristics:
887
 
888
\begin{itemize}
889
\item support for the Generic Kernel mutex interface;
890
 
891
\item use of
892
the shadow mechanism provided by the Generic Kernel;
893
 
894
\item
895
independence from the data structures used internally by the
896
Scheduling Modules;
897
 
898
\item possibility of a static initialization
899
of the used mutexes.
900
\end{itemize}
901
 
902
The Module is contained in \texttt{modules/pi}.
903
 
904
%----------------------------------------------------------------------------
905
\subsection{Used approach}
906
%----------------------------------------------------------------------------
907
 
908
The key idea of the implementation are:
909
 
910
\begin{itemize}
911
\item when a task enters into a critical section locking a mutex,
912
the Module registers which is the task that owns the mutex,
913
because it is used if other tasks try to lock the mutex, and
914
because only that task can unlock it;
915
 
916
\item the Module registers
917
the number of mutexes that owns the tasks, to check that the task
918
does not die with some mutexes locked.
919
 
920
\item when a task tries to
921
block a busy mutex, its shadow pointer will be set to the blocking
922
task;
923
 
924
\item when a mutex is unlocked, all the task blocked by it
925
are freed, so all the blocked tasks can try to acquire the mutex
926
(the mutex will be locked by the first task blocked scheduled,
927
usually the higher priority task that was blocked);
928
\end{itemize}
929
 
930
%----------------------------------------------------------------------------
931
\subsection{Private data structures}
932
%----------------------------------------------------------------------------
933
 
934
The PI Module defines the structure \texttt{mutex\_resource\_des}
935
that handle the interface exported by the Resource Modules. The
936
private data structures added by the Module to the interface are
937
the following:
938
 
939
\begin{description}
940
\item [\texttt{nlocked}]this array stores the number of mutexes
941
that each task currently locks;
942
 
943
\item [\texttt{blocked}]this array
944
is used to track the blocked tasks on a mutex. Each PI mutex has a
945
pointer to the first blocked task; the other tasks are queued in
946
this structure (look at Figure\ref{Examples_PI_blocked}). The data
947
structure can be allocated locally to the Module because a task
948
can be blocked on only one
949
mutex.
950
 
951
\begin{figure}
952
\begin{center}
953
\includegraphics[width=1.0\columnwidth]{images/example_PI_blocked.eps}
954
\end{center}
955
\label{Examples_PI_blocked}
956
\caption{Use of the \texttt{blocked} array. The example describes a structure
957
\texttt{mutex\_t} initialized with the Priority Inheritance protocol. The field
958
\texttt{firstblocked} is the first element of the blocked task queue on a
959
specific mutex.}
960
\end{figure}
961
 
962
\end{description}
963
 
964
Each mutex handled by the Priority Inheritance protocol uses a
965
dynamically allocated internal data structure called
966
\texttt{PI\_mutex\_t}, that has the following fields:
967
 
968
\begin{description}
969
\item [\texttt{owner}]When the mutex is free this field is
970
\texttt{NIL}, else it is the PID of the task that locks the mutex;
971
 
972
\item [\texttt{nblocked}]This is the number of tasks actually
973
blocked on a mutex;
974
 
975
\item [\texttt{firstblocked}]When the field
976
\texttt{nblocked} is different from 0 this field is the first task
977
blocked on a mutex (the following tasks can be found following the
978
blocked list ).
979
\end{description}
980
 
981
Finally, to init a PI mutex, a correct parameter must be passed to
982
\texttt{mutex\_init}. That parameter must be of type
983
\texttt{PI\_mutexattr\_t} and it does not add any other parameter
984
to the default attribute.
985
 
986
%----------------------------------------------------------------------------
987
\subsection{Internal and Interface Functions}
988
%----------------------------------------------------------------------------
989
 
990
%----------------------------------------------------------------------------
991
\subsubsection{\texttt{int PI\_res\_register(RLEVEL l, PID p, RES\_MODEL *r);}}
992
%----------------------------------------------------------------------------
993
 
994
This function always return -1 because it will never be called by
995
the Generic Kernel (because the Module does not accept any
996
Resource Model).
997
 
998
%----------------------------------------------------------------------------
999
\subsubsection{\texttt{void PI\_res\_detach(RLEVEL l, PID p);}}
1000
%----------------------------------------------------------------------------
1001
 
1002
This function simply controls that the task that is still ending
1003
does not lock any mutexes. If not, an exception is raised. Such a
1004
situation is very dangerous because, when a task is died, the
1005
shadow data structures are not consistent, and this will probably
1006
cause a system crash.
1007
 
1008
%----------------------------------------------------------------------------
1009
\subsubsection{\texttt{int PI\_init(RLEVEL l, mutex\_t *m, const mutexattr\_t *a);}}
1010
%----------------------------------------------------------------------------
1011
 
1012
This function inits a mutex to be used with the PI Protocol. A
1013
structure of type \texttt{PI\_mutex\_t} is allocated and all the
1014
fields are initialized..
1015
 
1016
 
1017
%----------------------------------------------------------------------------
1018
\subsubsection{\texttt{int PI\_destroy(RLEVEL l, mutex\_t *m);}}
1019
%----------------------------------------------------------------------------
1020
 
1021
This function should destroy a mutex. The mutex has to be
1022
correctly initialized and it must be free (not locked by a task).
1023
 
1024
%----------------------------------------------------------------------------
1025
\subsubsection{\texttt{int PI\_lock(RLEVEL l, mutex\_t *m);}}
1026
%----------------------------------------------------------------------------
1027
 
1028
This function should implement a mutex lock. First, a check is
1029
done to see if the mutex was initializated statically. In that
1030
case, the initialization of the data structures is completed.
1031
 
1032
At this point, a check is done to see if the task already owns the
1033
mutex. If not, a cycle is done. In the body the shadow field is
1034
set, and the system is rescheduled. The cycle is needed because
1035
when the mutex will be unlocked, all the blocked tasks will be
1036
woken up to fight for the locking of the mutex.
1037
 
1038
Finally, When the mutex will be found free, it is locked.
1039
 
1040
%----------------------------------------------------------------------------
1041
\subsubsection{\texttt{int PI\_trylock(RLEVEL l, mutex\_t *m);}}
1042
%----------------------------------------------------------------------------
1043
 
1044
This function is similar to the previous one, except that the task
1045
is never blocked if the mutex is busy.
1046
 
1047
%----------------------------------------------------------------------------
1048
\subsubsection{\texttt{int PI\_unlock(RLEVEL l, mutex\_t *m);}}
1049
%----------------------------------------------------------------------------
1050
 
1051
This function should free the mutex. First, a check is done to see
1052
if the task that unlocks really owns the mutex. Then, the mutex is
1053
unlocked and all the blocked tasks are woken up (the shadow field
1054
is reset to point to the blocked tasks themselves). Then, the
1055
system is rescheduled to see if a preemption should be done (the
1056
Module does not know if a preemption will occurs or not, because
1057
it does not know which are the modules registered!).
1058
 
1059
%----------------------------------------------------------------------------
1060
\subsubsection{\texttt{void PI\_register\_module(void);}}
1061
%----------------------------------------------------------------------------
1062
 
1063
This function will register the Module in the system. This
1064
function is very similar to the Scheduling Modules Registration
1065
function.