Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1676 tullio 1
%----------------------------------------------------------------------------
2
\chapter{System Start-up and Termination}
3
%----------------------------------------------------------------------------
4
 
5
Each S.Ha.R.K. application starts as a sequential C program, with
6
the classical main funcion. The multitasking environment \index{system initialization}
7
is already initialized when the application starts. From the main
8
task you can call any system primitive.
9
 
10
The system finishes when a sys\_end or sys\_abort function is called,
11
or when the last user task is terminated. For more information, see
12
\emph{The Generic Kernel Internals} chapter of the S.Ha.R.K. Kernel
13
Architecture Manual.
14
 
15
The \texttt{sys\_atrunlevel()} primitive\index{sys\_atexit()} allows
16
to post some handlers, which are automatically executed by the kernel
17
when it changes runlevel. Such functions can be issued either in the
18
target execution environment (generally MS-DOS) or just before terminating
19
the S.Ha.R.K. kernel, depending on the third argument of the primitive.
20
The handlers posted through \texttt{sys\_atrunlevel()} may also be
21
called on a kernel abort due to fatal errors.
22
 
23
%----------------------------------------------------------------------------
24
\section{Initialization File\label{sec:InitFile}}
25
%----------------------------------------------------------------------------
26
 
27
When the system starts, one of the things to be done before going
28
in multitasking mode is to initialize the devices, the resources and
29
the schedulers which will be used by the application. To do that,
30
the Kernel calls the \_\_kernel\_register\_levels\_\_ function, that
31
usually registers the following modules (see the S.Ha.R.K. Kernel
32
architecture Manual for more details):
33
 
34
\begin{description}
35
\item [Scheduling~Modules]A scheduling module implements a particular
36
Scheduling Algorithm (for example EDF, RM, Round Robin, and so on).
37
\item [Resource~Modules]A resource module implements a shared resource
38
access protocol (for example the semaphores, the mutexes, and so on).
39
\item [Other~devices]Such for example the File System, and other devices
40
that need to be initialized when the Multitasking Mode is not started
41
yet.
42
\end{description}
43
 
44
The function returns a TICK value (in microseconds) that is the time
45
that will be used for programming the periodic timer interrupt of
46
the PC. If a value of 0 is returned, the one-shot timer is used instead
47
(see the OSLib documentation for more informations). Typical return
48
values range from 250 to 2000 microseconds.
49
 
50
Here is a typical initialization function:
51
 
52
\begin{verbatim}
53
TIME __kernel_register_levels__(void *arg) {
54
    struct multiboot_info *mb = (struct multiboot_info *)arg;
55
    LEVEL EDF_level;
56
 
57
    EDF_level = EDF_register_level(EDF_ENABLE_ALL);
58
    RR_register_level(RRTICK, RR_MAIN_YES, mb);
59
    CBS_register_level(CBS_ENABLE_ALL, EDF_level);
60
    dummy_register_level();
61
 
62
    SEM_register_module();
63
    CABS_register_module();
64
 
65
    return 1000;
66
}
67
\end{verbatim}
68
 
69
As you can see, the system initialization function registers an EDF,
70
a Round Robin and a CBS module. Then, It register a dummy Module (that
71
usually is the last of the Scheduling Modules). For more informations
72
about the Scheduling policies, see Section \ref{sec:sched}. Finally,
73
Semaphores and CABS are registered, and a value of 1 ms Tick time
74
is returned to initialize the PC's real-time clock.
75
 
76
For a survey of the architecture of the Scheduling Modules and the
77
Resource Modules see theKernel Overview Chapter of the S.Ha.R.K. Kernel
78
Architecture Manual. A set of Initialization functions can be found
79
on the kernel/init directory of the S.Ha.R.K. source tree. An explanation
80
of each registration function for each Module can be found in the
81
S.Ha.R.K. Module Repository Manual.
82
 
83
After the registration of the modules in the system, the Kernel switch
84
in Multitasking mode, and starts the execution of the handlers that
85
the modules have posted with the \texttt{sys\_atrunlevel} primitive.
86
Usually at least one Module will create and activate a task (for example,
87
the Round Robin Scheduling Module does that) that will start when
88
all the handlers will be processed. The body of that task is usually
89
called \_\_init\_\_() and provides an initialization for the most
90
commonly used devices (such the keyboard, and so on) and modules.
91
As the last thing, the function simply call the main() function, that
92
is, the user application starts. A sample of a typical \_\_init\_\_()
93
function is showed below:
94
 
95
\begin{verbatim}
96
TASK __init__(void *arg) {
97
    struct multiboot_info *mb = (struct multiboot_info *)arg;
98
 
99
    HARTPORT_init();
100
    __call_main__(mb);
101
    return (void *)0;
102
}
103
\end{verbatim}
104
 
105
The source code of the \_\_init\_\_() function is usually inserted
106
in the initialization file after the \_\_kernel\_register\_levels\_\_
107
function. For more information on \_\_call\_main\_\_ see the \texttt{include/kernel/func.h}
108
include file.
109
 
110
Using the new driver layer the \_\_init()\_\_ function slightly change.
111
First is executed the HARTPORT\_init function that initialize the
112
Hartik Port layer (if required), then a task that close all drivers
113
is created. The next step is the initialization of all used drivers,
114
followed by the registration of the shutdown task that will be executed
115
during the system shutdown procedure. At the end the function 'main'
116
is executed. A tipical example with the new \_\_init()\_\_ function
117
is:
118
 
119
\begin{verbatim}
120
TASK __init__(void *arg) {
121
    struct multiboot_info *mb = (struct multiboot_info *)arg;
122
 
123
    HARTPORT_init();
124
 
125
    /* Create the shutdown task. */
126
    /* It will be activated at RUNLEVEL SHUTDOWN */
127
    set_shutdown_task();
128
 
129
    /* Init the drivers */
130
    device_drivers_init();
131
 
132
    /* Set the shutdown task activation */
133
    sys_atrunlevel(call_shutdown_task, NULL, RUNLEVEL_SHUTDOWN);
134
    __call_main__(mb);
135
 
136
    return (void *)0;
137
}
138
 \end{verbatim}
139
 
140
ATTENTION! In some initialization files the function that activate
141
the shutdown task is in the form:
142
 
143
\begin{verbatim}
144
#define SHUTDOWN_TIMEOUT_SEC 3
145
 
146
void call_shutdown_task(void *arg) {
147
    struct timespec t;
148
 
149
    sys_gettime(&t);
150
    t.tv_sec += SHUTDOWN_TIMEOUT_SEC;
151
 
152
    /* Emergency timeout to exit from RUNLEVEL_SHUTDOWN
153
    kern_event_post(&t,(void *)((void *)sys_abort_shutdown), (void *)0);
154
 
155
    task_activate(shutdown_task_PID);
156
}
157
\end{verbatim}
158
 
159
This implementation say that the task has 3 seconds to perform drivers
160
stop. After that interval the system is forced to close even is some
161
drivers are not closed. If a longer time is needed a greater value
162
for \texttt{SHUTDOWN\_TIMEOUT\_SEC} constant must be used. If a shutdown
163
without the timer is preferred the function could be in the simpler
164
form:
165
 
166
\begin{verbatim}
167
void call_shutdown_task(void *arg) {
168
    task_activate(shutdown_task_PID);
169
}
170
\end{verbatim}
171
 
172
%----------------------------------------------------------------------------
173
\subsection{Information about the dependencies among modules}
174
%----------------------------------------------------------------------------
175
 
176
Some modules, drivers and ports need to use the semaphores managed
177
by specific resource sharing modules. In that case, the modules, drivers
178
and ports expect the semaphores to be initialized by the application
179
into the initialization file. Here there is a brief list of the modules
180
which require other module initialization \footnote{All those dependancies wish to be removed.}.
181
 
182
The HARTIK ports (module HARTPORT) use the semaphores, so you must
183
include and initialize the semaphores if your application or a module
184
used by your application uses the HARTIK ports.
185
 
186
The HARTIK ports are used by the following modules:
187
 
188
\begin{itemize}
189
\item ports/first
190
\item drivers/net
191
\item drivers/input
192
\item drivers/oldchar
193
\end{itemize}
194
The semaphores are also used by:
195
 
196
\begin{itemize}
197
\item ports/tftp
198
\item drivers/oldsnd.
199
\end{itemize}
200
 
201
%----------------------------------------------------------------------------
202
\section{System primitives}
203
%----------------------------------------------------------------------------
204
 
205
Here is a list of primitives whose use is related to the system initialization.
206
 
207
%----------------------------------------------------------------------------
208
\begin{intest}
209
SYS\_ATRUNLEVEL\index{SYS\_ATRUNLEVEL}
210
\end{intest}
211
 
212
\begin{description}
213
\item [\texttt{int}]\texttt{sys\_atrunlevel(void (*func\_code)(void *),void
214
*parm, BYTE when);}
215
\item [Description:]The Generic Kernel supports the specification of the
216
functions to be called at system initialization and termination. These
217
functions can be registered through this system primitive; the parameters
218
for that function are:
219
\item [\texttt{f}]the function to be registered;
220
\item [\texttt{p}]the parameter to be passed to function \texttt{f} when
221
the function will be called;
222
\item [\texttt{when}]is the situation in witch that function will be called.
223
The correct values are the following:
224
 
225
\begin{description}
226
\item [\texttt{RUNLEVEL\_INIT}]Used when programming Modules;
227
\item [\texttt{RUNLEVEL\_SHUTDOWN}]The function will be called after a
228
call to \texttt{sys\_abort} or \texttt{sys\_end}; The system is still
229
in multitasking mode;
230
\item [\texttt{RUNLEVEL\_BEFORE\_EXIT}]The function will be called when
231
the Kernel exits from multitasking mode;
232
\item [\texttt{RUNLEVEL\_AFTER\_EXIT}]The function is called before the
233
system hangs (or returns to the host OS, if the proprietary extender
234
is used).
235
 
236
\end{description}
237
 
238
It is also possible to specify with an OR operator a flag \texttt{NO\_AT\_ABORT}
239
that disables the call to the functions if the system is exiting with
240
a \texttt{sys\_abort} function.
241
 
242
\end{description}
243
 
244
You can post at most \texttt{MAX\_RUNLEVEL\_FUNC} functions. See the
245
S.Ha.R.K. Kernel Architecture Manual for more details.
246
 
247
\begin{description}
248
\item [See]\textbf{also}: \texttt{sys\_init()}, \texttt{sys\_end()}.
249
\end{description}
250
 
251
%----------------------------------------------------------------------------
252
\begin{intest}
253
EXIT\index{exit}
254
\end{intest}
255
 
256
\begin{description}
257
\item [\texttt{void exit(int status);}]
258
\item [Description:]This function call terminates the Kernel. In this phase,
259
the Kernel tries to correctly close all the initialized modules and
260
drivers. The functions eventually posted with the \texttt{sys\_at\_runlevel}
261
call are also executed.
262
 
263
If called inside an event or inside an ISR, it does return to the
264
caller. The system shutdown will start when all the current interrupts
265
have been serviced, and the system has been rescheduled. Otherwise,
266
this function follows the POSIX specification.
267
\item [See]\textbf{also}: \texttt{\_exit()}, \texttt{sys\_panic()}, \texttt{sys\_atrunlevel()}.
268
\end{description}
269
 
270
%----------------------------------------------------------------------------
271
\begin{intest}
272
\_EXIT\index{\_exit}
273
\end{intest}
274
 
275
\begin{description}
276
\item [\texttt{void \_exit(int status);}]
277
\item [Description:]Same as \texttt{exit()}. functions posted through \texttt{sys\_at\_runlevel}
278
with \texttt{NO\_AT\_ABORT} set or functions posted with \texttt{atexit()}
279
are not executed.
280
\item [See]\textbf{also}: \texttt{exit()}, \texttt{atexit()}, \texttt{sys\_panic()},
281
\texttt{sys\_atrunlevel()}.
282
\end{description}
283
 
284
%----------------------------------------------------------------------------
285
\begin{intest}
286
SYS\_PANIC\index{sys\_end}
287
\end{intest}
288
 
289
\begin{description}
290
\item [\texttt{void sys\_panic(const char * fmt, ...);}]
291
\item [Description:]This function call print a message then call sys\_abort(333).
292
\item [See]\textbf{also}: \texttt{sys\_abort()}, \texttt{sys\_end()}, \texttt{sys\_atrunlevel()}.
293
\end{description}
294
 
295
%----------------------------------------------------------------------------
296
\begin{intest}
297
SYS\_SHUTDOWN\_MESSAGE\index{sys\_\_shutdown\_message}
298
\end{intest}
299
 
300
\begin{description}
301
\item [\texttt{int sys\_shutdown\_message(char *fmt,...);}]
302
\item [Description:]This function call saves a message in a reserved area,
303
that will be printed at system shutdown. It does not end the system.
304
\item [See]\textbf{also}: \texttt{sys\_panic()}.
305
\end{description}
306
 
307
%----------------------------------------------------------------------------
308
\begin{intest}
309
SYS\_ABORT\_SHUTDOWN\index{sys\_abort\_shutdown}
310
\end{intest}
311
 
312
\begin{description}
313
\item [\texttt{int sys\_abort\_shutdown(int err);}]
314
\item [Description:]This function will force the system to end the \texttt{SHUTDOWN}
315
runlevel if there are system tasks which cannot be stopped. If called
316
when the system is still in the \texttt{RUNLEVEL\_RUNNING} runlevel,
317
the function behaves like \texttt{exit()}. If called inside an OSLib
318
event or inside an IRQ,it does return to the caller. The system shutdown
319
will start when all the current interrupts have been serviced, and
320
the system has been rescheduled. Otherwise, this function does not
321
return.
322
\end{description}
323
 
324
%----------------------------------------------------------------------------
325
\begin{intest}
326
SYS\_SET\_REBOOT\index{sys\_set\_reboot}
327
\end{intest}
328
 
329
\begin{description}
330
\item [\texttt{int sys\_set\_reboot(int mode);}]
331
\item [Description:]This function sets the reboot \texttt{mode}, which
332
specifies what will happen after the system end. \texttt{mode} options
333
are:
334
\item [EXIT\_MODE\_HALT:]the system will call the halt (\texttt{HLT}) instruction.
335
\item [EXIT\_MODE\_COLD:]the system will perform the cold reboot (slow
336
reboot).
337
\item [EXIT\_MODE\_WARM:]the system will perform the warm reboot (fast
338
reboot).
339
\item [EXIT\_MODE\_REAL:]the system will return to the real mode (\textbf{default
340
selection}).
341
\end{description}
342
 
343
%----------------------------------------------------------------------------
344
\chapter{Task Management}
345
%----------------------------------------------------------------------------
346
 
347
%----------------------------------------------------------------------------
348
\section{Task Model}
349
%----------------------------------------------------------------------------
350
 
351
S.Ha.R.K. tasks are defined using standard C functions which return
352
a \texttt{void *} type \footnote{for readability, that type has been called TASK.} and can have one void * argument, which is passed when the task
353
is created. A task is identified by a system-wide unique process identifier
354
(\texttt{PID}) and a consecutive number \footnote{a task with PID p has a consecutive number that is proc\_table{[}p{]}.task\_ID.}.
355
 
356
A task has tipically a set of Quality of Service requirements that
357
need to be fullfilled by the Kernel. The kernel uses its registered
358
Scheduling Modules to meet the QoS required by a specified task. The
359
QoS reuired is specified at creation time through a Task Model, that
360
is passed to the task creation primitives.
361
 
362
A Task, can be \textit{Periodic} or \textit{Aperiodic}. Periodic tasks
363
are automatically activated by the kernel with a desired period, whereas
364
aperiodic tasks can either be activated by an explicit system call
365
or upon the occurrence of a desired event.
366
 
367
The typical task code consists of an optional initialization of local
368
variables and resources, followed by a (finite or infinite) loop,
369
representing the task's body. The last instruction of such a loop
370
must be the primitive \texttt{task\_endcycle()}\index{task\_endcycle()}
371
or the primitive \texttt{task\_sleep()} \index{task\_sleep()} which
372
signals the end of a generic job.
373
 
374
The task can access a local and a global context by following the
375
C scoping rules; the local context is defined by the local variables
376
and the single optional input argument. The following example shows
377
a typical task code fragment:
378
 
379
\begin{verbatim}
380
void *my_task(void *par) {
381
 
382
    /* Local Context*/
383
    int a, b, c;
384
 
385
    /* Initialization */
386
    b = c = (int)par + 1;
387
    a = (int)par / 2;
388
    ...
389
 
390
    while (1) {
391
 
392
        /* Body here!*/
393
        ...
394
 
395
        task_endcycle();
396
    }
397
}
398
\end{verbatim}
399
 
400
\noindent \texttt{my\_task()} has just one integer input argument
401
(passed through the void * parameter) and three local variables\index{local task context}.
402
The life-cycle of the local variables is the same as the task one,
403
since they are allocated on the task's stack. Obviously they retain
404
their values between two consecutive jobs.
405
 
406
\noindent One of the most important parameters for a real-time task
407
$\tau_{i}$ is the \emph{deadline}, defined as the maximum time allowed
408
for a task job to terminate. More precisely, we distinguish between
409
the \emph{absolute deadline} (denoted by $d_{i}$) specified with
410
respect to time 0, and the \emph{Relative Deadline} (denoted by $D_{i}$)
411
specified with respect to the activation time $r_{i,k}$ of the $k$-th
412
job of task $\tau_{i}$. We have that:
413
\[
414
d_{i}=r_{i,k}+D_{i}.
415
\]
416
 
417
\noindent Tasks can also have different level of criticality, for
418
example:
419
 
420
\begin{itemize}
421
\item \texttt{HARD}\index{HARD} tasks are the most critical in the system.
422
For this reason, they are subjected to a guarantee algorithm at creation
423
time. The system enforces a strict compliance to the deadline constraint
424
for this kind of tasks%
425
\footnote{The guarantee algorithm tries to verify that both the newly activated
426
hard task and the previously existing ones will finish within their
427
deadlines%
428
}. If a hard deadline is missed, the system raises an exception which,
429
by default, results in the program termination. Recovery actions can
430
be programmed for this kind of exception (as shown below).
431
\item \texttt{SOFT}\index{SOFT} tasks can miss some deadline, and are scheduled
432
in order not to jeopardize HARD tasks' schedulability. This is done
433
through a service mechanism (see \ref{sec:sched}) which guarantees
434
each soft task a predefined bandwidth (i.e., a fraction of processor
435
utilization) while preserving the guarantee performed on hard tasks.
436
\item \texttt{NRT}\index{NRT} (Non Real-Time) tasks are scheduled in background
437
according to their relative fixed priority. Typically, they are used
438
for monitoring or debugging purposes.
439
\end{itemize}
440
The Task criticality, periodicity and the deadlines are coded into
441
the Task Model that is passed to the creation primitive. Each new
442
Scheduling Module can use its own Task Model to include the specific
443
task QoS requirements.
444
 
445
Each task can be in one of a set of states; the states that a task
446
can be in depend on each particular Module. For example, typical Task
447
states can be:
448
 
449
\begin{itemize}
450
\item \texttt{\textbf{EXE}}\index{EXE}: at any time, in the system there
451
is only one task in the EXE state, and it is the task actually executing.
452
\item \texttt{\textbf{READY}}\index{READY}: it includes all active tasks
453
ready to execute, except for the currently running task.
454
\item \texttt{\textbf{SLEEP}}\index{SLEEP}: it includes all aperiodic tasks
455
which terminated a job and are waiting for the next activation. Moreover,
456
each created task (periodic or aperiodic) that has not been activated
457
is put in the SLEEP state.
458
\item \texttt{\textbf{IDLE}}\index{IDLE}: is the state of those periodic
459
tasks which terminated a job and are waiting for the next activation.
460
\item \texttt{\textbf{BLOCKED}}\index{BLOCKED}: it includes all the tasks
461
blocked on a semaphore.
462
\end{itemize}
463
 
464
%----------------------------------------------------------------------------
465
\section{The scheduling policy%
466
\footnote{This section is derived from the Kernel overview chapter of the S.Ha.R.K.
467
Architecture Manual.%
468
}\label{sec:sched} }
469
%----------------------------------------------------------------------------
470
 
471
The S.Ha.R.K. scheduling architecture is based on a \emph{Generic
472
Kernel}, which does not implement any particular scheduling algorithm,
473
but postpones scheduling decisions to external entities, the \emph{scheduling
474
modules}. External modules can implement periodic scheduling algorithms,
475
soft task management through real-time servers, semaphore protocols,
476
and resource management policies.
477
 
478
The Generic Kernel provides the mechanisms used by the modules to
479
perform scheduling and resource management thus allowing the system
480
to abstract from the specific algorithms that can be implemented.
481
The Generic Kernel simply provides the primitives without specifying
482
any algorithm, whose implementation resides in external modules, configured
483
at run-time with the Initialization function.
484
 
485
Scheduling Modules are used by the Generic Kernel to schedule tasks,
486
or serve aperiodic requests using an aperiodic server. The Scheduling
487
Modules are organized into levels, one Module for each level. These
488
levels can be thought as priority scheduling levels (their priority
489
correspond to the order which they appear in the Initialization function).
490
When the Generic Kernel has to perform a scheduling decision, it asks
491
the modules for the task to schedule, according to fixed priorities:
492
first, it invokes a scheduling decision to the highest priority module,
493
then (if the module does not manage any task ready to run), it asks
494
the next high priority module, and so on. The Generic Kernel schedules
495
the first task of the highest priority non empty module's queue.
496
 
497
In this way, the Scheduling policy can be tuned simply modifying the
498
Initialization function. The standard distribution of the S.Ha.R.K.
499
Kernel includes a set of predefined Initialization functions that
500
can be used when developing a new application. For more informations
501
see the S.Ha.R.K. Module Manual, where each Scheduling Modules and
502
each predefined initialization functioon are described in detail.
503
 
504
%----------------------------------------------------------------------------
505
\section{Task Creation\index{task creation}}
506
%----------------------------------------------------------------------------
507
 
508
In order to run a S.Ha.R.K. task, three steps have to be performed:
509
parameters definition, creation, and activation. To improve the system
510
flexibility, each task can be characterized by a large number of parameters,
511
most of which are optional. For this reason, a set of structures derived
512
from \texttt{TASK\_MODEL}\index{MODEL} structure have been introduced
513
to simplify the parameters' definition phase. The first thing to do
514
in order to define a task is to declare a Model variable and initialize
515
it using the pmacro provided (see the S.Ha.R.K. Module Manual for
516
more informations).
517
 
518
\noindent Once the task's parameters have been set, the task can be
519
created using the \texttt{task\_create} or the \texttt{task\_createn}
520
system call.
521
 
522
%----------------------------------------------------------------------------
523
\begin{intest}
524
TASK\_CREATEN\index{task\_createn()} and TASK\_CREATE\index{task\_create()}
525
\end{intest}
526
 
527
\begin{description}
528
\item [\texttt{PID task\_createn(char *name, TASK (*body)(),
529
TASK\_MODEL *m, ...);}]
530
\item [\texttt{PID task\_create(char *name, TASK (*body)(),
531
TASK\_MODEL *m, RES\_MODEL *r);}]
532
\item [Description:]\texttt{task\_createn} creates a new task. \texttt{name}
533
is a pointer to a string representing the task name; \texttt{body()}
534
is a pointer to the task body (i.e. the name of the C function containing
535
the task code); \texttt{m} specifies the Model that contain the QoS
536
specification of the task (the value can not be equal to NULL). Then,
537
follow a list of Resource Models terminated with NULL (see the S.Ha.R.K.
538
Module Manual for the available Task Models and Resource Models).
539
\texttt{task\_create} is a redefinition of \texttt{task\_createn}
540
that can be used when there is at least one Resource Model to be passed
541
to the creation primitive.
542
\item [Return]\textbf{value}: The function returns the identifier of the
543
newly created task, or -1 if the task creation fails (in this case
544
the \texttt{errno()} system call can be used to determine the error's
545
cause).
546
\item [See]\textbf{also}: \texttt{task\_activate()}, \texttt{task\_kill()}.
547
\item [Example]~
548
\end{description}
549
 
550
\begin{verbatim}
551
int main(int argc, char **argv) {
552
    HARD_TASK_MODEL m;
553
    hard_task_default_model(m);
554
    hard_task_def_wcet(m,ASTER_WCET);
555
    hard_task_def_mit(m,10000);
556
    hard_task_def_group(m,1);
557
    hard_task_def_ctrl_jet(m);
558
 
559
    p1 = task_create("Aster", aster, &m, NULL);
560
    if (p1 == -1) {
561
        perror("Error: Could not create task <aster> ...");
562
        exit(1);
563
    }
564
}
565
\end{verbatim}
566
 
567
 
568
%----------------------------------------------------------------------------
569
\section{Group Creation}
570
%----------------------------------------------------------------------------
571
 
572
Group creation is a feature provided by S.Ha.R.K. that allows a user
573
to create a set of tasks. The group creation differs from the creation
574
made by the task\_create and task\_createn primitives because in group
575
creation the acceptance test is done for the whole set of task (and
576
not for every task in sequence) only when every task which belong
577
to the set has been initialized in the system. After the acceptance
578
test, the user have to inquire the Scheduling Module to see the tasks
579
that have been accepted and successfully created in the system.
580
 
581
The primitives provided by S.Ha.R.K. to support group creation are:
582
 
583
\begin{itemize}
584
\item group\_create
585
\item group\_create\_accept
586
\item group\_create\_reject
587
\end{itemize}
588
The documentation about group creation can be found in the \emph{Group
589
creation HOWTO} available on the S.Ha.R.K. website.
590
 
591
%----------------------------------------------------------------------------
592
\section{Task Activation and Termination}
593
%----------------------------------------------------------------------------
594
 
595
When a task is created, it is put in the \texttt{SLEEP} state, where
596
it is kept until activation, which can be triggered by an external
597
interrupt or by an explicit \texttt{task\_activate()} primitive).
598
Periodic jobs that complete execution are handled by the registered
599
Scheduling Modules (usually they are put in an \texttt{IDLE} state
600
or similar), from which they will be automatically re-activated by
601
the system timer. Aperiodic jobs that complete execution return to
602
the \texttt{SLEEP} state, where they wait for an explicit re-activation.
603
 
604
Some scheduling models (such as the EDF and RM modules) support release
605
offsets. In an offset is given in the task model, the \texttt{task\_activate()}
606
will put the task in the \texttt{IDLE} state, waiting for the first
607
release to occur.
608
 
609
A task can be destroyed using the \texttt{task\_kill()} system call,
610
that frees its descriptor. A task can kill itself using the \texttt{task\_abort()}
611
system call.
612
 
613
In S.Ha.R.K., tasks can be members of groups to allow simultaneous
614
activation or termination. A task can be put in a group through a
615
macro that works on the task model passed at task creation. The name
616
of the macro depends on the name of the Task Model used; usually its
617
name is like \texttt{XXX\_task\_def\_group(group\_number)}, where
618
XXX is the name of the task Model; the group\_number 0 indicates that
619
a task belongs to no groups.
620
 
621
Task cancellation, join, the cleanup handlers and the task specific
622
data works as the POSIX standard; only the name of the primitives
623
are changed from \texttt{pthread\_XXX} to \texttt{task\_XXX}. In any
624
case, the \texttt{pthread\_XXX} versions are available for POSIX compatibility.
625
 
626
\textbf{Warning}: \texttt{task\_kill()} kills a task only if the cancellation
627
type of the task is set to asynchronous. If the cancellation type
628
is set to deferred, the task will terminate only when it reach a cancellation
629
point.
630
 
631
%----------------------------------------------------------------------------
632
\begin{intest}
633
TASK\_ACTIVATE\index{task\_activate()}
634
\end{intest}
635
 
636
\begin{description}
637
\item [\texttt{int task\_activate(PID p);}]
638
\item [Description:]It activates task \texttt{p}. Usually the activation
639
will insert the task into the ready queue. (If the task has an offset,
640
the task will be put in the ready queue after the offset.) Returns
641
 
642
is set to \texttt{EUNVALID\_TASK\_ID}.
643
\item [See]\textbf{also}: \texttt{task\_create(), task\_kill(), group\_activate()}.
644
\end{description}
645
 
646
%----------------------------------------------------------------------------
647
\begin{intest}
648
TASK\_KILL\index{task\_kill()}
649
\end{intest}
650
 
651
\begin{description}
652
\item [\texttt{int task\_kill(PID p);}]
653
\item [Description:]It asks for a cancellation of the task p. It returns
654
-1 in case of error, 0 otherwise. If an error occurred, the errno
655
variable is set to \texttt{EINVALID\_KILL}. A task which has the NO\_KILL
656
flag set can not be killed. If the task has already been killed but
657
it is not died yet, the primitive does nothing. A task that has the
658
cancellation type set to asynchronous will die just when it will be
659
scheduled again by the system; instead, if the cancellation type is
660
set to deferred, the task will die only at the reaching of a cancellation
661
point. This function is the correspondent of the \texttt{pthread\_cancel()}
662
primitive.
663
\item [See]\textbf{also}: \texttt{task\_create(), task\_activate(), group\_kill()}.
664
\end{description}
665
\pagebreak
666
 
667
%----------------------------------------------------------------------------
668
\begin{intest}
669
TASK\_ABORT\index{task\_abort()}
670
\end{intest}
671
 
672
\begin{description}
673
\item [\texttt{void task\_abort(void *returnvalue);}]
674
\item [Description:]It aborts the calling task, removing it from the system.
675
If the task is joinable, the return value will be stored by the kernel
676
and given to any task that calls a task\_join primitive on the died
677
task.
678
\item [See]\textbf{also}: \texttt{task\_create(), task\_activate(), task\_kill()}.
679
\end{description}
680
 
681
%----------------------------------------------------------------------------
682
\begin{intest}
683
TASK\_BLOCK\_ACTIVATION\index{task\_block\_activation()}
684
\end{intest}
685
 
686
\begin{description}
687
\item [\texttt{int task\_block\_activation(PID p);}]
688
\item [Description:]It blocks all explicit activation of a task made with
689
\texttt{task\_activate} and \texttt{group\_activate}. The activations
690
made after this call are buffered (counted) in an internal counter.
691
It returns 0 in case of success or -1 in case of error. In the latter
692
case, \texttt{errno} is set to \texttt{EUNVALID\_TASK\_ID}. If the
693
activations were already blocked, it does nothing.
694
\item [See]\textbf{also}: \texttt{task\_unblock\_activation(), task\_activate()}.
695
\end{description}
696
 
697
%----------------------------------------------------------------------------
698
\begin{intest}
699
TASK\_UNBLOCK\_ACTIVATION\index{task\_unblock\_activation()}
700
\end{intest}
701
 
702
\begin{description}
703
\item [\texttt{int task\_unblock\_activation(PID p);}]
704
\item [Description:]It unblocks the activations of a task after a call
705
to task\_block\_activation. After this call, the task can be explicitly
706
activated. It returns the number of buffered activations, or -1 if
707
an error occurred. If an error occurred, the errno variable is set
708
to EUNVALID\_TASK\_ID. If the activations were not blocked, it simply
709
returns 0. Note that the primitive simply returns the number of buffered
710
activations, \emph{without} activating the task.
711
\item [See]\textbf{also}: \texttt{task\_block\_activation(), task\_activate()}.
712
\end{description}
713
 
714
%----------------------------------------------------------------------------
715
\begin{intest}
716
GROUP\_ACTIVATE\index{group\_activate()}
717
\end{intest}
718
 
719
\begin{description}
720
\item [\texttt{int group\_activate(WORD g);}]
721
\item [Description:]It activates all tasks belonging to group \texttt{g}.
722
Returns 0 in case of success or -1 in case of error; the \texttt{errno}
723
variable is set to \texttt{EUNVALID\_GROUP}.
724
\item [See]\textbf{also}: \texttt{task\_create(), task\_activate(), group\_kill()}.
725
\end{description}
726
 
727
%----------------------------------------------------------------------------
728
\begin{intest}
729
GROUP\_KILL\index{group\_kill()}
730
\end{intest}
731
 
732
\begin{description}
733
\item [\texttt{void group\_kill(WORD g);}]
734
\item [Descrizione:]It kills all tasks belonging to group \texttt{g}. It
735
returns -1 in case of error, 0 otherwise. If an error occurred, the
736
errno variable is set to \texttt{EUNVALID\_GROUP}. The kill request
737
to a single task that belong to a group is done in a way similar to
738
that done in the primitive \texttt{task\_kill()}.
739
\item [See]\textbf{also}: \texttt{task\_create(), task\_activate(), group\_activate()},
740
\texttt{task\_kill()}.
741
\end{description}
742
 
743
%----------------------------------------------------------------------------
744
\section{Task Instances}
745
%----------------------------------------------------------------------------
746
 
747
S.Ha.R.K. supports the concept of instance for its task. A typical
748
task function is composed by an initialization part and a body part
749
that does the work for that the task was created; for example:
750
 
751
\begin{verbatim}
752
void *mytask(void *arg) {
753
    /* initialization part */
754
 
755
    for (;;) {
756
        /* body */
757
        ...
758
 
759
        task_endcycle();
760
    }
761
}
762
\end{verbatim}
763
 
764
In the example, the task will never terminate, and it also calls the
765
\texttt{task\_endcycle} primitive to say to the Kernel that the current instance
766
is terminated \footnote{The concept of instance is introduced into S.Ha.R.K.
767
because in that way the Kernel can directly support task Quality Of Service
768
parameters like deadlines, periods and so on in a native way. Note that the
769
concept of instance is not covered by the POSIX standard, that only support a
770
fixed priority scheduler. In POSIX, a periodic task can only be implemented
771
using the Real-Time extensions and in particular using the Timer feature.
772
S.Ha.R.K. implements also that approach, however the native primitives are
773
better in terms of efficiency.}.
774
 
775
%----------------------------------------------------------------------------
776
\begin{intest}
777
TASK\_ENDCYCLE\index{task\_endcycle()}
778
\end{intest}
779
 
780
\begin{description}
781
\item [\texttt{void task\_endcycle(void);}]
782
\item [Description:]It terminates the currently executing job of the calling
783
task. The behaviour of this primitive may sligtly change depending
784
on the Scheduling Module registered at initialization time. Tipically,
785
the \texttt{task\_endcycle} primitive suspends the task until an automatic
786
reactivation that is made internally by the Kernel. Moreover, the
787
\texttt{task\_endcycle()} primitive usually keeps track of pending
788
activations \footnote{There is a pending activation when a task is activated before the
789
current instance has finished. In this case, if the \texttt{task\_endcycle()}
790
primitive is called and there is a pending activation, it simply does
791
nothing.}. Previous versions of the kernel supported a \texttt{task\_sleep()}\index{task\_sleep()}
792
primitive with similar behavior. That function is currently unsupported.
793
The primitive is a cancellation point.
794
\item [Implementation:]This primitive is implemented as task\_message(NULL, 1);
795
\footnote{Note on the implementation: this primitive is implemented as
796
\texttt{task\_message(NULL, 1);}}
797
\item [See]\textbf{also:} \texttt{task\_activate}.
798
\end{description}
799
 
800
%----------------------------------------------------------------------------
801
\section{Task (thread) specific data}
802
%----------------------------------------------------------------------------
803
 
804
These functions works in a way equal to their POSIX counterparts.
805
These primitives are used for managing task specific data, that are
806
a few data variables that can be referred in a common way independently
807
from the task that asks for it. The system also ensures a proper cleanup
808
when the task is killed. As an example, the \texttt{errno} variable
809
can be thought as a task specific data. In this manual only their
810
interfaces are described; for more informations, see the POSIX standard.
811
 
812
%----------------------------------------------------------------------------
813
\begin{intest}
814
TASK\_KEY\_CREATE\index{task\_key\_create()}
815
\end{intest}
816
 
817
\begin{description}
818
\item [\texttt{int task\_key\_create(task\_key\_t *key, void
819
(*destructor)(void *));}]
820
\item [Description:]It creates a task key that can be used to refer a task\_specific
821
data. The name of the POSIX counterpart is \texttt{pthread\_key\_create}.
822
\end{description}
823
\pagebreak
824
 
825
%----------------------------------------------------------------------------
826
\begin{intest}
827
TASK\_GETSPECIFIC\index{task\_getspecific()}
828
\end{intest}
829
 
830
\begin{description}
831
\item [\texttt{void *task\_getspecific(task\_key\_t key);}]
832
\item [Description:]It gets the current value for the key (note that the
833
value of the key vary from task to task). The name of the POSIX counterpart
834
is \texttt{pthread\_getspecific}.
835
\end{description}
836
 
837
%----------------------------------------------------------------------------
838
\begin{intest}
839
TASK\_SETSPECIFIC\index{task\_setspecific()}
840
\end{intest}
841
 
842
\begin{description}
843
\item [\texttt{int task\_setspecific(task\_key\_t key, const void
844
*value); }]
845
\item [Description:]It sets the current value for the key. The name of
846
the POSIX counterpart is \texttt{pthread\_setspecific}.
847
\end{description}
848
 
849
%----------------------------------------------------------------------------
850
\begin{intest}
851
TASK\_KEY\_DELETE\index{task\_key\_delete()}
852
\end{intest}
853
 
854
\begin{description}
855
\item [\texttt{int task\_key\_delete(task\_key\_t key);}]
856
\item [Description:]It deletes the current key. The name of the POSIX counterpart
857
is \texttt{pthread\_key\_delete}.
858
\end{description}
859
 
860
%----------------------------------------------------------------------------
861
\section{Task cancellation}
862
%----------------------------------------------------------------------------
863
 
864
These primitives are used when managing task cancellation. They are
865
directly derived from the POSIX standard. Nothe that the POSIX interface
866
is also available.
867
 
868
%----------------------------------------------------------------------------
869
\begin{intest}
870
TASK\_CLEANUP\_PUSH\index{task\_cleanup\_push()}
871
\end{intest}
872
 
873
\begin{description}
874
\item [\texttt{void task\_cleanup\_push(void (*routine)(void
875
*), void *arg);}]
876
\item [Description:]It pushes the specified cancellation cleanup handler
877
routine onto the cancellation cleanup stack. The name of the POSIX
878
counterpart is \texttt{pthread\_cleanup\_push}.
879
\end{description}
880
 
881
%----------------------------------------------------------------------------
882
\begin{intest}
883
TASK\_CLEANUP\_POP\index{task\_cleanup\_pop()}
884
\end{intest}
885
 
886
\begin{description}
887
\item [\texttt{void task\_cleanup\_pop(int execute);}]
888
\item [Description:]It removes the routine at the top of the cancellation
889
cleanup stack of the calling thread. If \texttt{execute} is not equal
890
0, the routine previously pushed is called. The name of the POSIX
891
counterpart is \texttt{pthread\_cleanup\_pop}.
892
\end{description}
893
 
894
%----------------------------------------------------------------------------
895
\begin{intest}
896
TASK\_TESTCANCEL\index{task\_testcancel()}
897
\end{intest}
898
 
899
\begin{description}
900
\item [\texttt{void task\_testcancel(void);}]
901
\item [Description:]creates a cancellation point in the calling task. The
902
primitive has no effect if cancelability is disabled. The name of
903
the POSIX counterpart is \texttt{pthread\_testcancel}.
904
\end{description}
905
 
906
\pagebreak
907
 
908
%----------------------------------------------------------------------------
909
\begin{intest}
910
TASK\_SETCANCELSTATE\index{task\_setcancelstate()}
911
\end{intest}
912
 
913
\begin{description}
914
\item [\texttt{int task\_setcancelstate(int state, int *oldstate);}]
915
\item [Description:]This primitive sets the cancelability state of the
916
calling thread to the indicate \emph{state} \emph{and} returns the
917
previous cancelability state at the location referenced by \emph{oldstate}.
918
Legal values for state are \texttt{TASK\_CANCEL\_ENABLE} and \texttt{TASK\_CANCEL\_DISABLE}.
919
\texttt{pthread\_setcancelstate} is the name of the POSIX counterpart.
920
\end{description}
921
 
922
%----------------------------------------------------------------------------
923
\begin{intest}
924
TASK\_SETCANCELTYPE\index{task\_setcanceltype()}
925
\end{intest}
926
 
927
\begin{description}
928
\item [int task\_setcanceltype(int type, int *oldtype);]
929
\item [Description:]This primitive sets the cancelability type of the calling
930
thread to the indicate \emph{type} and returns the previous cancelability
931
type at the location referenced by \emph{oldtype}. Legal values for
932
state are \texttt{TASK\_CANCEL\_DEFERRED} and \texttt{TASK\_CANCEL\_ASINCHRONOUS}.
933
The name of the POSIX counterpart is \texttt{pthread\_setcanceltype}.
934
\end{description}
935
 
936
%----------------------------------------------------------------------------
937
\section{Join}
938
%----------------------------------------------------------------------------
939
 
940
The join primitives allow a task to wait for the termination of another task
941
\footnote{not of an instance of a task!}. The return value of the terminated
942
task is passed to the join primitive and the caller can use the value. These
943
primitives are directly derived from the POSIX standard. It means that a join
944
can be done only on a joinable task. But note that when a task created with the
945
creation primitives \footnote{\texttt{task\_create}, \texttt{task\_createn},
946
\texttt{group\_create}} starts it is \emph{not} in the joinable state
947
\footnote{this is done to remain similar to the previous versions of the Hartik
948
Kernel...}. This behaviour differs from the standard behavior of the POSIX
949
standard, which specifies that every new task shall be in the joinable state.
950
However, S.Ha.R.K. provides also the \texttt{pthread\_create} primitive that is
951
\emph{fully compliant} with the standard. Finally, a S.Ha.R.K. task can switch
952
between the jonable and non-joinable state using the primitives
953
\texttt{task\_joinable} and \texttt{task\_unjoinable} \footnote{In the POSIX
954
standard, only the \texttt{pthread\_detach} primitive is available.}.
955
 
956
%----------------------------------------------------------------------------
957
\begin{intest}
958
TASK\_JOIN\index{task\_join()}
959
\end{intest}
960
 
961
\begin{description}
962
\item [\texttt{int task\_join(PID p, void **value);}]
963
\item [Description:]The primitive suspends the execution of the calling
964
task until the task p terminates, unless the task p has already terminated.
965
On return from a successful \texttt{task\_join} call with a non-\texttt{NULL}
966
\emph{value} argument, the value returned by the thread through a
967
task\_abort shall be made available in the location referenced by
968
\emph{value}. When the primitive returns successfully the target task
969
has been terminated. The primitive returns 0 in case of success, otherwise
970
it returns \texttt{EINVAL} if the value \texttt{p} does not refer
971
to a task that can be joined, \texttt{ESRCH} if the value \texttt{p}
972
does not refer to a valid task, and \texttt{EDEADLK} if a deadlock
973
was detected. The name of the POSIX counterpart is \texttt{pthread\_join}.
974
\end{description}
975
 
976
%----------------------------------------------------------------------------
977
\begin{intest}
978
TASK\_JOINABLE\index{task\_joinable()}
979
\end{intest}
980
 
981
\begin{description}
982
\item [\texttt{int task\_joinable(PID p);}]
983
\item [Description:]This function set the detach state of a task p to joinable.
984
This function is not present in Posix standard. It returns ESRCH if
985
p is non a valid task.
986
\end{description}
987
\pagebreak
988
 
989
%----------------------------------------------------------------------------
990
\begin{intest}
991
TASK\_UNJOINABLE\index{task\_unjoinable()}
992
\end{intest}
993
 
994
\begin{description}
995
\item [\texttt{int task\_unjoinable(PID p);}]
996
\item [Description:]This function sets the detach state of a task to detached.
997
The name of the POSIX counterpart is \texttt{pthread\_detach}. The
998
function returns \texttt{EINVAL} if \texttt{p} can not be joined (or
999
currently a task has done a join on it), or \texttt{ESRCH} if \texttt{p}
1000
is not correct.
1001
\end{description}
1002
 
1003
%----------------------------------------------------------------------------
1004
\section{Preemption control}
1005
%----------------------------------------------------------------------------
1006
 
1007
S.Ha.R.K. provides two primitives that set the preemptability of a
1008
task. A non-preemptive task can not be preempted by another task;
1009
interrupts are handled in the usual way. These primitives can be used
1010
to implement short critical sections. Note the difference between
1011
this kind of non -preemption and the interrupt disabling done using
1012
kern\_cli and kern\_sti: in the latter case, interrupt can not preempt
1013
the critical sections. A new task usually starts in a preemptive state.
1014
 
1015
%----------------------------------------------------------------------------
1016
\begin{intest}
1017
TASK\_NOPREEMPT\index{task\_nopreempt()}
1018
\end{intest}
1019
 
1020
\begin{description}
1021
\item [void task\_nopreempt(void);]
1022
\item [Description:]After the call of this primitive, the task is non-preemptive.
1023
\end{description}
1024
 
1025
%----------------------------------------------------------------------------
1026
\begin{intest}
1027
TASK\_PREEMPT\index{task\_preempt()}
1028
\end{intest}
1029
 
1030
\begin{description}
1031
\item [void task\_nopreempt(void);]
1032
\item [Description:]After the call of this primitive, the task become again
1033
preemptive.
1034
\end{description}
1035
 
1036
%----------------------------------------------------------------------------
1037
\section{Suspending a task}
1038
%----------------------------------------------------------------------------
1039
 
1040
The following system calls can be used by a task to suspend itself
1041
for a known or unknown time. (Note: it is dangerous to use these system
1042
calls in a hard real-time task.)
1043
 
1044
%----------------------------------------------------------------------------
1045
\begin{intest}
1046
TASK\_DELAY\index{task\_delay()}
1047
\end{intest}
1048
 
1049
\begin{description}
1050
\item [\texttt{void task\_delay(DWORD t);}]
1051
\item [Description:]It causes the calling task to be blocked for at least
1052
\texttt{t} microseconds. Note that \texttt{t} is the \emph{minimum}
1053
delay time. In facts, after \texttt{t} microseconds the task is inserted
1054
in the ready queue and can be delayed by higher priority tasks. This
1055
function was inherited from the previous versions of Hartik. Please,
1056
use the POSIX counterpart \texttt{nanosleep} instead!
1057
\end{description}
1058
 
1059
%----------------------------------------------------------------------------
1060
\section{Job ExecutionTime (JET) estimation}
1061
%----------------------------------------------------------------------------
1062
 
1063
S.Ha.R.K. provides a set of primitives that allows to precisely estimate
1064
the system load. These primitives can be used to tune the parameters
1065
that are given at task creation, and to get statistics about the system
1066
load.
1067
 
1068
The execution time estimation is done on a task basis. That is, S.Ha.R.K.
1069
provides three primitives that allows the user to estimate the JET
1070
of every task. For every task, it is possible to know the mean execution
1071
time, the maximum execution time, the time consumed by the current
1072
instance and the time consumed by the last \texttt{JET\_TABLE\_DIM}
1073
instances.
1074
 
1075
The user have to explicitly enable the Kernel to record the JET informations
1076
for a specific task. This is done at task creation time; usually a
1077
macro that enable the JET is provided in the definition of every task
1078
model (see the S.Ha.R.K. Module Manual).
1079
 
1080
Here is an example of the use of the JET functions:
1081
 
1082
\begin{verbatim}
1083
/* The Goofy Task */
1084
void *goofy(void *arg) {
1085
    int i;
1086
    for (;;) {
1087
        for (i = 0; i < 100; i++)
1088
            kern_printf("Yuk!");
1089
        task_endcycle();
1090
    }
1091
}
1092
 
1093
PID goofy_PID;
1094
 
1095
/* a NRT task that never finish */
1096
 
1097
void *jetcontrol(void *arg) {
1098
    TIME sum, max, curr, last[5];
1099
    int nact;
1100
 
1101
    for (;;) {
1102
        if (jet_getstat(p, &sum, &max, &nact, &curr) == -1)
1103
            continue;
1104
        for (j = 0; j < 5; j++) last[j] = 0;
1105
        jet_gettable(p, &last[0], 5);
1106
        printf_xy(1, 20, WHITE,"goofy_PID=%d mean=%d max=%d nact=%d",
1107
            goofy_PID, sum / (nact == 0 ? 1 : nact), max, nact);
1108
        printf_xy(1, 21, WHITE, "L1=%d L2=%d L3=%d L4=%d L5=%d",
1109
            last[0], last[1], last[2], last[3], last[4]);
1110
    }
1111
}
1112
 
1113
*int main(int argc, char **argv) {
1114
    ...
1115
 
1116
    /* The task goofy is created, specifying that the Kernel
1117
        should take care of the JET data */
1118
 
1119
    HARD_TASK_MODEL m;
1120
 
1121
    hard_task_default_model(m);
1122
 
1123
    /* ... other hard_task_XXX macros */
1124
    hard_task_def_ctrl_jet(m); /* JET enabling */
1125
    goofy_PID = task_create("Goofy", goofy, &m, NULL);
1126
 
1127
    /* ... creation of the JET control task, and so on */
1128
}
1129
\end{verbatim}
1130
 
1131
%----------------------------------------------------------------------------
1132
\begin{intest}
1133
JET\_GETSTAT\index{jet\_getstat()}
1134
\end{intest}
1135
 
1136
\begin{description}
1137
\item [int jet\_getstat(PID p, TIME *sum, TIME *max, int *n, TIME
1138
*curr);]
1139
\item [Description:]This primitive returns some JET informations about
1140
the task p. The informations retrieved are stored into the following
1141
parameters:
1142
 
1143
\begin{description}
1144
\item [\texttt{sum}]is the task total execution time since it was created
1145
or since the last call to the \texttt{jet\_delstat} function;
1146
\item [\texttt{max}]is the maximum time used by a task instance since it
1147
was created or since the last call to the \texttt{jet\_delstat} function;
1148
\item [\texttt{n}]is the number of terminated instances which sum and max
1149
refers to;
1150
\item [\texttt{curr}]is the total execution time of the current instance.
1151
\end{description}
1152
 
1153
If a parameter is passed as \texttt{NULL} the information is not returned.
1154
The function returns 0 if the \texttt{PID} passed is correct, \texttt{-1}
1155
if the PID passed does not correspond to a valid PID or the task does
1156
not have the \texttt{JET\_ENABLE} bit set.
1157
 
1158
\end{description}
1159
 
1160
%----------------------------------------------------------------------------
1161
\begin{intest}
1162
JET\_DELSTAT\index{jet\_delstat()}
1163
\end{intest}
1164
 
1165
\begin{description}
1166
\item [int jet\_delstat(PID p);]
1167
\item [Description:]The primitive voids the actual task execution time
1168
data mantained by the Generic Kernel. The function returns 0 if the
1169
PID passed is correct, \texttt{-1} if the PID passed does not correspond
1170
to a valid PID or the task does not have the \texttt{JET\_ENABLE}
1171
bit set.
1172
\end{description}
1173
 
1174
%----------------------------------------------------------------------------
1175
\begin{intest}
1176
JET\_GETTABLE\index{jet\_gettable()}
1177
\end{intest}
1178
 
1179
\begin{description}
1180
\item [int jet\_gettable(PID p, TIME *table, int n);]
1181
\item [Description:]The primitive returns the last \texttt{n} execution
1182
times of the task \texttt{p}. If the parameter n is less than 0, it
1183
returns only the last values stored since the last call to \texttt{jet\_gettable}
1184
(up to a maximum of \texttt{JET\_TABLE\_DIM} values). If the value
1185
is greater than 0, the function returns the last \texttt{min(n,~JET\_TABLE\_DIM)}
1186
values registered. The return value is \texttt{-1} if the task passed
1187
as parameter does not exist or the task does not have the \texttt{JET\_ENABLE}
1188
bit set, otherwise the number of values stored into the array is returned.
1189
The table passed as parameter should store at least \texttt{JET\_TABLE\_DIM}
1190
elements.
1191
\end{description}
1192