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{Synchronization and communication}
3
%----------------------------------------------------------------------------
4
 
5
This chapter describes the task's interaction capabilities provided by the
6
S.Ha.R.K. kernel. In order to improve the programming flexibility without
7
jeopardizing the hard tasks' a priori guarantee, the kernel implements different
8
mechanisms.
9
 
10
In general, hard tasks should not use system calls that can cause an unbounded
11
(or unknown) blocking time, since they can jeopardize the system schedulability.
12
 
13
\begin{figure}
14
\begin{center}\includegraphics{over.eps}\end{center}
15
\caption{EDF Scheduling - Overload due to a task\_delay().}
16
\label{fg:semaf-over}
17
\end{figure}
18
 
19
For example, consider Figure~\ref{fg:semaf-over}: in this case there are two
20
periodic tasks, $\tau_{1}$ (execution time $C_{1}=5$ and period $T_{1}=15$) and
21
$\tau_{2}$ (execution time $C_{2}=2$ and period $T_{2}=4$). Since the total
22
utilization factor is $U=1/2+1/3=5/6<1$, the system is schedulable by EDF, but
23
if $\tau_{1}$ blocks for $8$ time units at time $t=4$, $\tau_{2}$ misses a
24
deadline at time $t=16$.
25
 
26
For efficiency reasons, the system does not perform any check to avoid the use
27
of blocking primitives in hard tasks; so this aspect is left to the programmer
28
responsibility.
29
 
30
%----------------------------------------------------------------------------
31
\section{POSIX Semaphores}
32
%----------------------------------------------------------------------------
33
 
34
The primitives described in this Section covers the semaphore mechanism
35
interface that can be used by the S.Ha.R.K. applications. The semaphore
36
interface directly follows the POSIX semaphore interface; the S.Ha.R.K. Kernel
37
add also some other primitives that allows to increment/decrement the semaphore
38
counter by more than one unit at a time.
39
 
40
These primitives can be used both for synchronization and mutual exclusion. It
41
is worth noting that the traditional semaphore mechanism can cause unbounded
42
\emph{priority inversion}, so it is not suitable for hard real-time tasks.
43
Concerning the synchronization, we note that the guarantee mechanism does not
44
take synchronization into account; therefore the programmer should avoid to
45
explicitly synchronize hard tasks by means of blocking primitives. It is instead
46
possible to use a weak synchronization between hard real-time tasks, realized
47
through non-blocking semaphores.
48
 
49
Only \texttt{SEM\_NSEMS\_MAX} semaphores can be created in the system. If an
50
application needs to use the POSIX semaphores, it have to add the call to the
51
function
52
 
53
\texttt{void SEM\_register\_module(void);}
54
 
55
into the \texttt{\_\_kernel\_register\_levels\_\_} function of the
56
initialization file (see Volume III - S.Ha.R.K. Modules).
57
 
58
In this section will be briefly described the POSIX semaphore interface
59
\footnote{This section only described unnamed semaphores. The interface for
60
named semaphores is also provided, althoutgh it does not use a file system but
61
resolve the names internally (as allowed by the POSIX 1003.13 PSE51 profile).}.
62
For a complete reference see the POSIX standard (the Linux manpage also works
63
well).
64
 
65
%----------------------------------------------------------------------------
66
\begin{intest}
67
SEM\_INIT\index{sem\_init()}
68
\end{intest}
69
 
70
\begin{description}
71
 
72
\item [\textbf{int sem\_init(sem\_t {*}sem, int pshared, unsigned int value);}]
73
 
74
\item [\textbf{Description:}] It is used to initialize a semaphore referred by
75
sem. The value of the initialized semaphore is \texttt{value}. The pshared
76
argument is ignored. After the call to the primitive, the sem value can bve used
77
to refer the semaphore.
78
 
79
\item [\textbf{Return value:}] on successful completion, the function
80
initializes the semaphore in sem and returns 0. Otherwise, it returns -1 and
81
\texttt{errno} is set according to the POSIX standard.
82
 
83
\item [\textbf{See also}:] sem\_wait(), sem\_trywait, sem\_post(),
84
sem\_destroy().
85
 
86
\end{description}
87
 
88
\begin{description}
89
\item \texttt{[Example]}
90
\end{description}
91
 
92
\begin{verbatim}
93
sem_t mutex;
94
 
95
TASK demo(void *arg) {
96
    ...
97
 
98
    /* The task enters a critical section protected by a mutex semaphore */
99
    sem_wait(&mutex);
100
    <critical section>
101
    sem_post(&mutex);
102
    ...
103
}
104
 
105
int main(int argc, char**argv) {
106
    ...
107
    sem_init(&mutex, 0, 1);
108
    ...
109
}
110
\end{verbatim}
111
 
112
%----------------------------------------------------------------------------
113
\begin{intest}
114
SEM\_DESTROY\index{sem\_destroy()}
115
\end{intest}
116
 
117
\begin{description}
118
 
119
\item [\textbf{int sem\_destroy(sem\_t {*}sem);}]
120
 
121
\item [\textbf{Description:}] It is used to destroy the semaphore indicated by
122
sem. Only a semaphore that was created using sem\_init() may be destroyed using
123
sem\_destroy(). \textbf{Warning}: This system call does not check if the
124
semaphore queue is empty or not, and does not awake tasks blocked on the
125
semaphore. The programmer has to make sure that \texttt{s} is free before
126
destroying it.
127
 
128
\item [\textbf{Return value}:] on successful completion, the function destroys
129
the sem semaphore and returns 0. Otherwise, it returns -1 and \texttt{errno} is
130
set according to the POSIX standard.
131
 
132
\item [\textbf{See also}:] sem\_init().
133
 
134
\end{description}
135
 
136
%----------------------------------------------------------------------------
137
\begin{intest}
138
SEM\_WAIT\index{sem\_wait()} and SEM\_TRYWAIT\index{sem\_trywait()}
139
\end{intest}
140
 
141
\begin{description}
142
 
143
\item [\textbf{int sem\_wait(sem\_t {*}sem);}]
144
 
145
\item [\textbf{int sem\_trywait(sem\_t {*}sem);}]
146
 
147
\item [\textbf{Description:}] is used to lock the semaphore referenced by
148
\texttt{sem}. If the semaphore value is currently zero, then the calling task
149
shall not return from the call to \texttt{sem\_wait}() until it either locks the
150
semaphore. \texttt{sem\_trywait} locks the semaphore referenced by \texttt{sem}
151
only if the semaphore is currently not locked; that is, if the semaphore value
152
is currently positive. Otherwise, it does not lock the semaphore.
153
\texttt{sem\_wait} is a cancellation point.
154
 
155
\item [\textbf{Return value:}] on successful completion the functions return 0.
156
Otherwise, they return -1 and \texttt{errno} is set according to the POSIX
157
standard.
158
 
159
\item [\textbf{See also}:] sem\_post().
160
 
161
\end{description}
162
 
163
%----------------------------------------------------------------------------
164
\begin{intest}
165
SEM\_XWAIT\index{sem\_wait()}
166
\end{intest}
167
 
168
\begin{description}
169
 
170
\item [\textbf{BYTE sem\_xwait(sem\_t {*}s, int n, int wait);}]
171
 
172
\item [Description:]\texttt{sem\_xwait()} is a non-portable extension to the
173
POSIX semaphores that decreases the semaphore counter by \texttt{n}. If the
174
counter is greater than or equal to \texttt{n} and there are no tasks blocked on
175
semaphore \texttt{s}, the counter is decreased by \texttt{n} and
176
\texttt{sem\_xwait} returns 0, otherwise the system call's behavior depends on
177
the \texttt{b} parameter. If \texttt{wait} is \texttt{BLOCK}, the calling task
178
blocks on the semaphore, if \texttt{wait} is \texttt{NON\_BLOCK}
179
\texttt{sem\_xwait} returns -1, errno is set to EAGAIN and the calling task does
180
not block. The semaphore queue is ordered using a FIFO strategy, in order to
181
avoid starvation. Hard tasks should not use blocking system calls, so it is
182
suggested to use \texttt{sem\_trywait()/xwait()} (only with \texttt{b =
183
NON\_BLOCK}). \texttt{sem\_xwait} is a cancellation point.
184
 
185
\item [\textbf{Return value:}] on successful completion, the function returns 0.
186
Otherwise, it returns -1 and \texttt{errno} is set according to the POSIX
187
standard.
188
 
189
\item [\textbf{See also}:] sem\_wait(), sem\_trywait(), sem\_post().
190
 
191
\end{description}
192
 
193
\begin{description}
194
\item [\textbf{Example:}]
195
\end{description}
196
 
197
\begin{verbatim}
198
sem_t sync;
199
 
200
TASK demo(void *arg) {
201
    ...
202
    /* The demo task synchronizes itself */
203
    /* with the wake task, waiting */
204
    /* for 5 signals on the sync semaphore */
205
    sem_xwait(&sync, 5, BLOCK);
206
    ...
207
}
208
 
209
TASK wake(void *arg) {
210
    while (1) {
211
        ...
212
        sem_xsignal(sync, 1);
213
        ...
214
        task_endcycle();
215
    }
216
}
217
 
218
void main(void) {
219
    ...
220
    sem_init(&sync, 0, 0);
221
    ...
222
}
223
\end{verbatim}
224
 
225
%----------------------------------------------------------------------------
226
\begin{intest}
227
SEM\_POST\index{sem\_post()}
228
\end{intest}
229
 
230
\begin{description}
231
 
232
\item [\textbf{int sem\_post(sem\_t {*}sem);}]
233
 
234
\item [\textbf{Description:}]It unlocks the semaphore referenced by sem by
235
performing the semaphore unlock operation on that semaphore. If the semaphore
236
queue is not empty and the first task in the queue requests a feasible counter
237
decrement, it can be awaken. The task is put in the ready queue and the
238
scheduler is invoked: for this reason this system call can cause a preemption.
239
The semaphore queue is a FIFO queue: tasks are awoken in a FIFO order according
240
to resource availability.
241
 
242
\item [\textbf{Return value:}] on successful completion, the function destroys
243
the sem semaphore and returns 0. Otherwise, it returns -1 and \texttt{errno} is
244
set according to the POSIX standard.
245
 
246
\item [\textbf{See also}:] sem\_wait(), sem\_trywait().
247
 
248
\end{description}
249
 
250
%----------------------------------------------------------------------------
251
\begin{intest}
252
SEM\_XPOST\index{sem\_xpost()}
253
\end{intest}
254
 
255
\begin{description}
256
 
257
\item [\textbf{int sem\_xpost(sem\_t {*}s, int n);}]
258
 
259
\item [\textbf{Description:}]\texttt{sem\_xpost()} is a non-portable extension
260
to the POSIX semaphores that implements the classical signal primitive on
261
semaphore \texttt{s}, increasing the counter by \texttt{n}. If the semaphore
262
queue is not empty and the first task in the queue requests a feasible counter
263
decrement, it can be awaken. The task is put in the \texttt{READY} queue and the
264
scheduler is invoked: for this reason this system call can cause a preemption.
265
The semaphore queue is a FIFO queue: tasks are awoken in a FIFO order according
266
to resource availability.
267
 
268
\item [\textbf{Return value:}] on successful completion, the function destroys
269
the sem semaphore and returns 0. Otherwise, it returns -1 and \texttt{errno} is
270
set according to the POSIX standard.
271
 
272
\item [\textbf{See also}:] \texttt{sem\_init(), sem\_wait(), sem\_destroy()}.
273
 
274
\item [Example:]see \texttt{sem\_wait()}.
275
 
276
\end{description}
277
 
278
%----------------------------------------------------------------------------
279
\begin{intest}
280
SEM\_GETVALUE\index{sem\_getvalue()}
281
\end{intest}
282
 
283
\begin{description}
284
 
285
\item [\textbf{int sem\_getvalue(sem\_t {*}sem, int {*}sval);}]
286
 
287
\item [\textbf{Description:}]\texttt{sem\_getvalue()} updates the location
288
referenced by the sval argument to have the value of the semaphore referenced by
289
sem without affecting the state of the semaphore. If sem is locked the value
290
returned by sem\_getvalue is a negative number whose absolute value represents
291
the number of processes waiting for the semaphore at some unspecified time
292
during the call.
293
 
294
\item [\textbf{Return value:}] on successful completion, the function destroys
295
the sem semaphore and returns 0. Otherwise, it returns -1 and \texttt{errno} is
296
set according to the POSIX standard.
297
 
298
\item [\textbf{See also}:] \texttt{sem\_init(), sem\_wait(), sem\_destroy()}.
299
 
300
\end{description}
301
 
302
%----------------------------------------------------------------------------
303
\section{Internal Semaphores}
304
%----------------------------------------------------------------------------
305
 
306
When developing a complex driver of the kernel, a designer usually needs to
307
manage a lot of shared resources that have to be accessed in mutual exclusion,
308
and needs also a lot of synchronization points that are not cancellation points.
309
For these pourposes the POSIX semaphores are not good because they are limited
310
in number and they are cancellation points.
311
 
312
For this pourpose the S.Ha.R.K. Kernel provides a sort of lightweight semaphores
313
called \emph{internal} semaphores, that fulfill the designer needs \footnote{The
314
existence of two type of semaphores is not new in Kernel development; For
315
example, the Linux Kernel differentiate the semaphores used by the applications
316
and the semaphors used by the Kernel.}: they are not cancellation points and
317
there is no limit on the number of semaphores that can be created in a system
318
\footnote{Only 8 bytes are taken for each internal semaphore. In some sense the
319
internal semaphores are similar to the POSIX mutexes...}. The interface of the
320
Internal semaphores is very similar to POSIX semaphore interface.
321
 
322
To use the Internal Semaphores, you don't need to call any registration function
323
at kernel startup time.
324
 
325
%----------------------------------------------------------------------------
326
\begin{intest}
327
INTERNAL\_SEM\_INIT\index{internal\_sem\_init()}
328
\end{intest}
329
 
330
\begin{description}
331
 
332
\item [\textbf{void internal\_sem\_init(internal\_sem\_t {*}s, int value);}]
333
 
334
\item [\textbf{Description:}]It initializes the internal semaphore \texttt{s}
335
with a specified \texttt{value}.
336
 
337
\end{description}
338
 
339
%----------------------------------------------------------------------------
340
\begin{intest}
341
INTERNAL\_SEM\_WAIT\index{internal\_sem\_wait()}
342
\end{intest}
343
 
344
\begin{description}
345
 
346
\item [\textbf{void internal\_sem\_wait(internal\_sem\_t {*}s);}]
347
 
348
\item [\textbf{Description:}]It implements a blocking wait. the semaphore
349
counter is decremented by one.
350
 
351
\end{description}
352
 
353
%----------------------------------------------------------------------------
354
\begin{intest}
355
INTERNAL\_SEM\_TRYWAIT\index{internal\_sem\_trywait()}
356
\end{intest}
357
 
358
\begin{description}
359
 
360
\item [\textbf{int internal\_sem\_trywait(internal\_sem\_t {*}s);}]
361
 
362
\item [\textbf{Description:}]It implements a non-blocking wait. It returns 0 if
363
the counter is decremented, -1 if not.
364
 
365
\end{description}
366
 
367
%----------------------------------------------------------------------------
368
\begin{intest}
369
INTERNAL\_SEM\_POST\index{internal\_sem\_post()}
370
\end{intest}
371
 
372
\begin{description}
373
 
374
\item [\textbf{void internal\_sem\_post(internal\_sem\_t {*}s);}]
375
 
376
\item [\textbf{Description:}]It implements a post operation.
377
 
378
\end{description}
379
 
380
%----------------------------------------------------------------------------
381
\begin{intest}
382
INTERNAL\_SEM\_GETVALUE\index{internal\_sem\_getvalue()}
383
\end{intest}
384
 
385
\begin{description}
386
 
387
\item [\textbf{int internal\_sem\_getvalue(internal\_sem\_t {*}s);}]
388
 
389
\item [\textbf{Description:}]It returns a value greater or equal 0 if there are
390
no tasks blocked on s, -1 otherwise.
391
 
392
\end{description}
393
 
394
%----------------------------------------------------------------------------
395
\section{Mutexes and Condition Variables}
396
%----------------------------------------------------------------------------
397
 
398
The primitives described in this section allows the user to define and use
399
\emph{mutexes} and \emph{condition variables}. A mutex can be thought as a
400
binary semaphore initialized to 1. In that way, a critical section can be
401
specified using the \emph{mutex\_lock} and \emph{mutex\_unlock} primitives.
402
Moreover, using condition variables a task can block itself waiting for an
403
event.
404
 
405
The provided implementation extends the POSIX standard mutex functions
406
implementing protocols like Stack Resource Policy and Non Preemptive
407
Protocol, that are not part of the standard. To do that, the mutex
408
initialization interface is different from the standard to allow the
409
specification of the various policies. In any case, the standard interface
410
is provided based on the extended interface.
411
 
412
%----------------------------------------------------------------------------
413
\subsection{Mutex attributes}
414
%----------------------------------------------------------------------------
415
 
416
A mutex can be used to implement critical sections that uses different
417
policies (for example, the Priority Inheritance, Priority Ceiling
418
or Stack Resource Policy protocol). The S.Ha.R.K. Kernel provides
419
a set of structures derived from the basic structure mutexattr\_t
420
\footnote{Similar to the pthread\_mutexattr\_t structures of the POSIX
421
standard.} that allow to handle the specification of different policies.
422
 
423
The mutex attributes are different foe every policy, that is implemented
424
by a Resouce Module. To see the the description of the mutex attributes
425
for every policy, look at the S.Ha.R.K. Modules Manual.
426
 
427
%----------------------------------------------------------------------------
428
\subsection{Functions}
429
%----------------------------------------------------------------------------
430
 
431
This subsection describes the functions that handle mutexes and condition
432
variables.
433
 
434
%----------------------------------------------------------------------------
435
\begin{intest}
436
MUTEX\_INIT\index{mutex\_init()}
437
\end{intest}
438
 
439
\begin{description}
440
 
441
\item [\textbf{int mutex\_init(mutex\_t {*}mutex, const mutexattr\_t {*}attr);}]
442
 
443
\item [\textbf{Description:}]The mutex\_init function inituializes the mutex
444
referenced by \emph{mutex} with attributes specified by \emph{attr}. \emph{attr}
445
shall be not equal NULL. Upon successful initialization, the state
446
of the mutex becomes initialized and unlocked.
447
 
448
\item [\textbf{Return value:}] on successful completion the functions return
449
0. Otherwise, they return -1 and \texttt{errno} is set according to
450
the POSIX standard.
451
 
452
\item [\textbf{See also}:] mutex\_destroy().
453
 
454
\end{description}
455
 
456
%----------------------------------------------------------------------------
457
\begin{intest}
458
MUTEX\_DESTROY\index{mutex\_destroy()}
459
\end{intest}
460
 
461
\begin{description}
462
 
463
\item [\textbf{int mutex\_destroy(mutex\_t {*}mutex);}]
464
 
465
\item [\textbf{Description:}]The mutex\_destroy function destroys the mutex
466
object
467
referenced by mutex. It is safe to destroy an initialize mutex that
468
is unlocked.
469
 
470
\item [\textbf{Return value:}] on successful completion the functions return
471
0. Otherwise, they return -1 and \texttt{errno} is set according to
472
the POSIX standard.
473
 
474
\item [\textbf{See also}:] mutex\_init().
475
 
476
\end{description}
477
 
478
%----------------------------------------------------------------------------
479
\begin{intest}
480
MUTEX\_LOCK\index{mutex\_lock()}
481
\end{intest}
482
 
483
\begin{description}
484
 
485
\item [\textbf{int mutex\_lock(mutex\_t {*}mutex);}]
486
 
487
\item [\textbf{Description:}]The mutex\_lock function locks an unlocked mutex.
488
If
489
the mutex is already locked , the calling thread waits until the mutex
490
becomes available. the behaviour of the function may change depending
491
on the particular policy passed with the mutexattr\_t parameter at
492
mutex initialization. The function is \emph{not} a cancellation point.
493
 
494
\item [\textbf{Return value:}] on successful completion the functions return
495
0. Otherwise, they return -1 and \texttt{errno} is set according to
496
the POSIX standard.
497
 
498
\end{description}
499
 
500
\pagebreak
501
 
502
%----------------------------------------------------------------------------
503
\begin{intest}
504
MUTEX\_TRYLOCK\index{mutex\_trylock()}
505
\end{intest}
506
 
507
\begin{description}
508
 
509
\item [\textbf{int mutex\_lock(mutex\_t {*}mutex);}]
510
 
511
\item [\textbf{Description:}]The mutex\_trylock function is identycal to
512
mutex\_lock
513
except that if the mutex us locked when the function is called, the
514
calling task does not block but returns -1 and an errno value of EBUSY,
515
as specified by the POSIX standard.
516
 
517
\item [\textbf{Return value:}] on successful completion the functions return
518
0. Otherwise, they return -1 and \texttt{errno} is set according to
519
the POSIX standard.
520
 
521
\end{description}
522
 
523
%----------------------------------------------------------------------------
524
\begin{intest}
525
MUTEX\_UNLOCK\index{mutex\_unlock()}
526
\end{intest}
527
 
528
\begin{description}
529
 
530
\item [\textbf{int mutex\_unlock(mutex\_t {*}mutex);}]
531
 
532
\item [\textbf{Description:}]The mutex\_unlock function is called by the owner
533
of
534
the mutex object to release it. If there are thread blocked on the
535
mutex object referenced by mutex when mutex\_lock is called, the mutex
536
becomes available, and the task that will acquire the mutex depends
537
on the policy with that the mutex was initialized.
538
 
539
\item [\textbf{Return value:}] on successful completion the functions return
540
0. Otherwise, they return -1 and \texttt{errno} is set according to
541
the POSIX standard.
542
 
543
\end{description}
544
 
545
%----------------------------------------------------------------------------
546
\begin{intest}
547
COND\_INIT\index{cond\_init()}
548
\end{intest}
549
 
550
\begin{description}
551
 
552
\item [\textbf{int cond\_init(cond\_t {*}cond);}]
553
 
554
\item [\textbf{Description:}]The function initializes the condition variable
555
referenced
556
by cond.
557
 
558
\item [\textbf{Return value:}] on successful completion the functions return
559
0. Otherwise, they return -1 and \texttt{errno} is set according to
560
the POSIX standard.
561
 
562
\end{description}
563
 
564
%----------------------------------------------------------------------------
565
\begin{intest}
566
COND\_DESTROY\index{cond\_destroy()}
567
\end{intest}
568
 
569
\begin{description}
570
 
571
\item [\textbf{int cond\_destroy(cond\_t {*}cond);}]
572
 
573
\item [\textbf{Description:}]The function destroys the given condition variable
574
specified by cond.
575
 
576
\item [\textbf{Return value:}] on successful completion the functions return
577
0. Otherwise, they return -1 and \texttt{errno} is set according to
578
the POSIX standard.
579
 
580
\end{description}
581
 
582
%----------------------------------------------------------------------------
583
\begin{intest}
584
COND\_SIGNAL\index{cond\_signal()} and COND\_BROADCAST\index{cond\_broadcast()}
585
\end{intest}
586
 
587
\begin{description}
588
 
589
\item [\textbf{int cond\_signal(cond\_t {*}cond);}]
590
 
591
\item [\textbf{int cond\_broadcast(cond\_t {*}cond);}]
592
 
593
\item [\textbf{Description:}]The function cond\_signal unblocks at least one of
594
the threads that are blocked on the specified condition variable cond.
595
The function cond\_broadcast unblocks all threads currently blocked
596
on the specified condition variable cond. These functions have no
597
effect if there are no threads currently blocked on cond.
598
 
599
\item [\textbf{Return value:}] on successful completion the functions return
600
0. Otherwise, they return -1 and \texttt{errno} is set according to
601
the POSIX standard.
602
 
603
\end{description}
604
 
605
%----------------------------------------------------------------------------
606
\begin{intest}
607
COND\_WAIT\index{cond\_wait()} and COND\_TIMEDWAIT\index{cond\_timedwait()}
608
\end{intest}
609
 
610
\begin{description}
611
 
612
\item [\textbf{int cond\_wait(cond\_t {*}cond, mutex\_t {*}mutex);}]
613
 
614
\item [\textbf{int cond\_timedwait(cond\_t {*}cond, mutex\_t {*}mutex,
615
const struct timespec {*}abstime);}]
616
 
617
\item [\textbf{Description:}]These functions are used to block on a condition
618
variable.
619
They shall be called with \emph{mutex} locked by the calling task.
620
These functions release mutex and cause the calling task to block
621
on the condition variable cond. Upon successful return, the mutex
622
is locked and is owned by the calling task. When using condition variables,
623
there is always a Boolean predicate involving shared variables associated
624
with each condition wait that is true if the thread should proceed.
625
Spurious wakeups from the \texttt{cond\_wait} or \texttt{cond\_timedwait}
626
functions may occur. Since the return from \texttt{cond\_wait} or
627
\texttt{cond\_timedwait} does not imply anything about the value of
628
this predicate, the predicate should be re-evaluated upon each return.
629
 
630
The \texttt{cond\_wait} and cond\_timedwait functions are cancellation
631
points. When the cancelability enable state of a task is set to
632
\texttt{TASK\_CANCEL\_DEFERRED},
633
a side effect of acting upon a cancellation request while in a condition
634
wait is that the mutex is (in effect) reaquired before calling the
635
first cancellation cleanup handler. To ensure a correct cancellation,
636
a cleanup function should be pushed before the \texttt{cond\_wait}
637
call (in case of cancellation it simply unlock the mutex).
638
 
639
The \texttt{cond\_timedwait} function is the same as the \texttt{cond\_wait}
640
function except that an error is returned if the absolute time specified
641
by abstime passes before the condition cond is signaled or broadcasted,
642
or if the absolute time specified by abstime has already been passed
643
at the time of the call.
644
 
645
\item [\textbf{Return value:}] on successful completion the functions return
646
0. Otherwise, they return -1 and \texttt{errno} is set according to
647
the POSIX standard.
648
 
649
\end{description}
650
 
651
%
652
% Tool: still in use?
653
%
654
 
655
% %----------------------------------------------------------------------------
656
% \section{Communication Ports \footnote{The S.Ha.R.K. communication ports are
657
% directly derived from the previous varsions of the Hartik Kernel.}}
658
% %----------------------------------------------------------------------------
659
% 
660
% S.Ha.R.K. communication ports allow tasks to exchange messages. Each
661
% port is uniquely identified by a symbolic name (i.e., a string of
662
% characters); a task willing to use this communication facility has
663
% to open the channel using the \texttt{port\_create()} call, thus becoming
664
% the owner of the resource. Any other task that wants to use this communication
665
% end-point to send or receive data needs to connect to it by using
666
% the \texttt{port\_connect()} primitive.
667
% 
668
% S.Ha.R.K. offers three types of ports:
669
% 
670
% \begin{itemize}
671
% 
672
% \item \texttt{STREAM}: it is a one-to-one communication facility, which
673
% can be opened either by the reader or by the writer task. The task
674
% executing the \texttt{port\_create()} must specify the message size
675
% and maximum number of messages in the queue. The task executing the
676
% 
677
% \texttt{port\_connect()} must only specify the size of the messages
678
% it wants to receive/send, which can be different from the one specified
679
% by the owner. For example, a task may open a port for reading messages
680
% of 4 bytes, while another task can connect to it to write one-byte
681
% messages. This mechanism turns out to be useful for character oriented
682
% device drivers which need to fill a given structure, before the message
683
% can be processed further by a higher-level task.
684
% 
685
% \item \texttt{MAILBOX}: it is a many-to-one communication facility, thought
686
% for being used in classical client/server mechanisms. This kind of
687
% port can only be opened by the reader task (the server) which wants
688
% to receive data from writer tasks (the clients). Message size is fixed
689
% and defined by the reader.
690
% 
691
% \item \texttt{STICK}: it is a one-to-many communication facility intended
692
% to be used for exchanging periodic state-messages, for which the most
693
% recent information is relevant. It can be opened only by the (unique)
694
% writer task and the reading tasks must connect to it. It contains
695
% just one message and any new message posted by the writer will overwrite
696
% the previous one. Messages are non-consumable: a reader task can perform
697
% many readings of a given message until the writer posts a new one. 
698
% \end{itemize}
699
% 
700
% The first two kinds of port implement the synchronous communication
701
% paradigm, while \texttt{STICK} ports implement an asynchronous (state-message)
702
% paradigm. It is worth noting that in order to protect the internal
703
% data structures, \texttt{STREAM} ports use semaphores for synchronizing
704
% the accesses, \texttt{STICK} ports just use a mutual exclusion semaphore,
705
% and the \texttt{MAILBOX} ports use both kinds of semaphores.
706
% 
707
% For this reason, \texttt{MAILBOX} and \texttt{STICK} ports should
708
% not be used by critical tasks, whereas \texttt{STREAM} ports can be
709
% used by any task requiring a state-message non-blocking semantics.
710
% Moreover, the execution time of a transaction depends on the message
711
% size (the message is copied in/from the buffer when a send/receive
712
% is performed). The semantics associated with each port is graphically
713
% illustrated in Figure \ref{fg:port-type}.
714
% 
715
% An application that uses the communication ports, must register the
716
% HARTPORT Module. Please see Volume III - S.Ha.R.K. Modules for details.
717
% 
718
% \begin{figure}
719
% \begin{center}\includegraphics[width=8cm]{port.eps}\end{center}
720
% \caption{HARTIK ports.\label{fg:port-type}}
721
% \end{figure}
722
% 
723
% %----------------------------------------------------------------------------
724
% \begin{intest}
725
% PORT\_CREATE\index{port\_create()}
726
% \end{intest}
727
% 
728
% \begin{description}
729
% 
730
% \item [\textbf{PORT port\_create(char {*}name, int dim, int num,
731
% int type, int mode);}]
732
% 
733
% \item [\textbf{Description:}]It opens the port identified by the string
734
% \texttt{name}.
735
% The argument \texttt{dim} specifies the message size in bytes, \texttt{num}
736
% specifies the queue size, \texttt{type} the port type (\texttt{STREAM},
737
% \texttt{MAILBOX}, or \texttt{STICK}), and \texttt{mode} the access
738
% mode (\texttt{READ} or \texttt{WRITE}). 
739
% 
740
% \item [\textbf{Return Value:}] The primitive returns the port identifier,
741
% which identifies the connection between the port and the task, and
742
% not the port itself, which is identified through its name. A return
743
% value -1 indicates that an error is occurred. 
744
% 
745
% \item [\textbf{See also}:] \texttt{port\_delete(), port\_connect(),
746
% port\_disconnect(), port\_send(), port\_receive()}.
747
% 
748
% \end{description}
749
% 
750
% \begin{description}
751
% \item [Example:\label{pg:port-ex}]
752
% \item \texttt{TASK demo(void)} \{
753
% \item \texttt{~~PORT p; }
754
% \item \texttt{~~char msg{[}6{]}; }
755
% \item \texttt{~~\ldots{}}
756
% \item \texttt{~~/{*} Demo task, of NRT type, opens the \char`\"{}goofy\char`\"{}
757
% port {*}/}
758
% \item \texttt{~~/{*} and sends a message of 6 bytes. {*}/}
759
% \item \texttt{~~p = port\_create(\char`\"{}goofy\char`\"{}, 6, 8, STREAM,
760
% WRITE);}
761
% \item \texttt{~~\ldots{}}
762
% \item \texttt{~~port\_send(p, msg, BLOCK); }
763
% \item \texttt{\}}
764
% \item \texttt{~}
765
% \item \texttt{TASK duro(void)} \{
766
% \item \texttt{~~PORT q; }
767
% \item \texttt{~~char msg{[}2{]}; }
768
% \item \texttt{~~/{*} Duro task (HARD) connects to the \char`\"{}goofy\char`\"{}
769
% {*}/}
770
% \item \texttt{~~/{*} port and receives messages of 2 bytes {*}/ }
771
% \item \texttt{~~q = port\_connect(\char`\"{}goofy\char`\"{}, 2, STREAM,
772
% READ);}
773
% \item \texttt{~~while (condition) \{}
774
% \item \texttt{~~~~\ldots{}}
775
% \item \texttt{~~~~if (port\_receive(q, msg, NON\textbackslash{}\_BLOCK) \{}
776
% \item \texttt{~~~~~~<action 1>;~/{*} Ready Message! {*}/}
777
% \item \texttt{~~~~\}}
778
% \item \texttt{~~~~else \{}
779
% \item \texttt{~~~~~~<action 2>;~/{*} Message not Ready! {*}/}
780
% \item \texttt{~~~~\}}
781
% \item \texttt{~~~~\ldots{}}
782
% \item \texttt{~~~~task\_endcycle();}
783
% \item \texttt{~~\}}
784
% \item \texttt{\}}
785
% 
786
% \end{description}
787
% 
788
% %----------------------------------------------------------------------------
789
% \begin{intest}
790
% PORT\_DELETE\index{port\_delete()}
791
% \end{intest}
792
% 
793
% \begin{description}
794
% 
795
% \item [\textbf{void port\_delete(PORT p)};]
796
% 
797
% \item [\textbf{Description:}]It destroys the port identified by \texttt{p}. 
798
% 
799
% \item [\textbf{See also}:] \texttt{port\_create(), port\_connect(),
800
% port\_disconnect(),
801
% port\_send(), port\_receive()}. 
802
% 
803
% \item [\textbf{Example:}]see the example at page \pageref{pg:port-ex}. 
804
% 
805
% \end{description}
806
% 
807
% %----------------------------------------------------------------------------
808
% \begin{intest}
809
% PORT\_CONNECT\index{port\_connect()}
810
% \end{intest}
811
% 
812
% \begin{description}
813
% 
814
% \item [\textbf{PORT port\_connect(char {*}name, int dim, int type,
815
% int mode);}]
816
% 
817
% \item [\textbf{Description:}]It connects the calling task to the port identified
818
% by \texttt{name}. The argument \texttt{dim} specifies the message
819
% size in bytes, \texttt{type} the port type (\texttt{STREAM}, \texttt{MAILBOX},
820
% or \texttt{STICK}), and \texttt{mode} the access mode (\texttt{READ}
821
% or \texttt{WRITE}). If the port has not been opened by \texttt{port\_create()},
822
% the task is blocked, waiting for port creation. To avoid synchronization
823
% delays, connection should be established only \underbar{after} opening
824
% the port. 
825
% 
826
% \item [\textbf{Return value:}] The function returns the port identification
827
% number in the case of successful operation; else -1 is returned. 
828
% 
829
% \item [\textbf{See also}:] \texttt{port\_create(), port\_delete(),
830
% port\_disconnect(), port\_send(), port\_receive()}. 
831
% 
832
% \end{description}
833
% 
834
% %----------------------------------------------------------------------------
835
% \begin{intest}
836
% PORT\_DISCONNECT\index{port\_disconnect()}
837
% \end{intest}
838
% 
839
% \begin{description}
840
% 
841
% \item [\textbf{void port\_disconnect(PORT p)};]
842
% 
843
% \item [\textbf{Description:}]It closes the connection identified by \texttt{p}. 
844
% 
845
% \item [\textbf{See also}:] \texttt{port\_create(), port\_connect(),
846
% port\_delete(), port\_send(), port\_receive()}. 
847
% 
848
% \end{description}
849
% 
850
% %----------------------------------------------------------------------------
851
% \begin{intest}
852
% PORT\_SEND\index{port\_send()}
853
% \end{intest}
854
% 
855
% \begin{description}
856
% 
857
% \item [\textbf{int port\_send(PORT p, char {*}msg, BYTE b);}]
858
% 
859
% \item [\textbf{Description:}]It sends a message pointed by \texttt{msg} to the
860
% port identified by \texttt{p}. Message dimension is defined through
861
% \texttt{port\_create()}
862
% or \texttt{port\_connect()} and cannot be dynamically changed. The
863
% argument \texttt{b} can be \texttt{BLOCK} or \texttt{NON\_BLOCK}.
864
% If \texttt{b = BLOCK} and the port queue is full, then the task is
865
% blocked until the buffer is freed. If \texttt{b = NON\_BLOCK} and
866
% the port queue is full, then the primitive returns 0 and the message
867
% is not sent. 
868
% 
869
% \item [\textbf{Return value:}] 1 (TRUE) if the operation can be performed,
870
% 0 otherwise. 
871
% 
872
% \item [\textbf{See also}:] \texttt{port\_create(), port\_connect(),
873
% port\_disconnect(),
874
% port\_send(), port\_receive()}. 
875
% 
876
% \item [\textbf{Example:}]see the example at page \pageref{pg:port-ex}. 
877
% 
878
% \end{description}
879
% 
880
% %----------------------------------------------------------------------------
881
% \begin{intest}
882
% PORT\_RECEIVE\index{port\_receive()}
883
% \end{intest}
884
% 
885
% \begin{description}
886
% 
887
% \item [\textbf{int port\_receive(PORT p, char {*}msg, BYTE b);}]
888
% 
889
% \item [\textbf{Description:}]It receives a message from the port identified by
890
% \texttt{p} and copies it in a memory buffer pointed by \texttt{msg}. Message
891
% dimension is defined through \texttt{port\_create()} or \texttt{port\_connect()}
892
% and cannot be dynamically changed. The argument \texttt{b} can be
893
% \texttt{BLOCK} or \texttt{NON\_BLOCK}. If \texttt{b = BLOCK} and the
894
% port queue is empty, then the task is blocked until a message is available.
895
% If \texttt{b = NON\_BLOCK} and the port queue is empty, then the primitive
896
% returns 0 and no message is received. 
897
% 
898
% \item [\textbf{Return value:}] 1 (TRUE) if the operation can be performed,
899
% 0 otherwise. 
900
% 
901
% \item [\textbf{See also}:] \texttt{port\_create(), port\_connect(),
902
% port\_disconnect(), port\_send(), port\_receive()}. 
903
% 
904
% \item [\textbf{Example:}]see the example at page \pageref{pg:port-ex}. 
905
% 
906
% \end{description}
907
 
908
%----------------------------------------------------------------------------
909
\section{Cyclical Asynchronous Buffers}
910
%----------------------------------------------------------------------------
911
 
912
\textbf{Cyclical Asynchronous Buffers} (or CABs) represent a particular
913
mechanism purposely designed for the cooperation among periodic activities
914
with different activation rates. See \cite{But97} for implementation
915
details.
916
 
917
A CAB provides a one-to-many communication channel, which at any instant
918
contains the most recent message inserted into it. A message is not
919
consumed (that is, extracted) by a receiving process but is maintained
920
into the CAB structure until a new message is overwritten. As a consequence,
921
once the first message is put in a CAB, a task can never be blocked
922
during a receive operation. Similarly, since a new message overwrites
923
the old one, a sender can never be blocked.
924
 
925
Notice that, using such a semantics, a message can be read more than
926
once if the receiver is faster than the sender, while messages can
927
be lost if the sender is faster than the receiver. However, this is
928
not a problem in many control applications, where tasks are interested
929
only in fresh sensory data rather than in the complete message history
930
produced by a sensory acquisition task.
931
 
932
Notice that more tasks can simultaneously access the same buffer in
933
a CAB for reading. Also, if a task $P$ reserves a CAB for writing
934
while another task $Q$ is using that CAB, a new buffer is created,
935
so that $P$ can write its message without interfering with $Q$.
936
As $P$ finishes writing, its message becomes the most recent one
937
in that CAB. The maximum number of buffers that can be created in
938
a CAB is specified as a parameter in the \emph{cab\_create} primitive.
939
To avoid blocking, this number must be equal to the number of tasks
940
that use the CAB plus one.
941
 
942
CABs can be created and initialized by the \emph{cab\_create} primitive,
943
which requires the CAB name, the dimension of the message, and the
944
number of messages that the CAB may contain simultaneously. The
945
\emph{cab\_delete}
946
primitive removes a CAB from the system and releases the memory space
947
used by its data structures.
948
 
949
To insert a message in a CAB, a task must first reserve a buffer from
950
the CAB memory space, then copy the message into the buffer, and finally
951
put the buffer into the CAB structure, where it becomes the most recent
952
message. This is done according to the following scheme:
953
 
954
\vspace{5mm} \begin{tt}
955
\begin{tabbing}
956
\={b}uf\_pointer = {\textbf{cab\_reserve}}(cab\_id);\\
957
\>\(<\)copy message in *buf\_pointer\(>\)\\
958
\>{\textbf{cab\_putmes}}(cab\_id, buf\_pointer);\\
959
\end{tabbing}
960
\end{tt}
961
 
962
\noindent Similarly, to get a message from a CAB, a task has to get
963
the pointer to the most recent message, use the data, and release
964
the pointer. This is done according to the following scheme:
965
 
966
\vspace{5mm} \begin{tt}
967
\begin{tabbing}
968
\={m}es\_pointer = {\textbf{cab\_getmes}}(cab\_id);\\
969
\>\(<\)use message\(>\)\\
970
\>{\textbf{cab\_unget}}(cab\_id, mes\_pointer);
971
\end{tabbing}
972
\end{tt} A simple example of CABs' usage is reported below.
973
 
974
\label{pg:cab-ex} \begin{minipage}{\columnwidth}
975
\begin{small}
976
\begin{tt}
977
\begin{verbatim}
978
CAB cc;
979
 
980
void main(void) {
981
    SYS_PARMS parms = BASE_SYS;
982
 
983
    /* global declaration */
984
    sys_def_tick(parms, 1, mSec);
985
    sys_init(&parms);
986
 
987
    /* The CAB named cc contains a message of */
988
    /* 5 floats and can be used by two tasks */
989
    cc = cab_create("my_cab", 5 * sizeof(float), 3);
990
    task_activate(task_create("ll", read, HARD, APERIODIC, 100, NULL));
991
    task_activate(task_create("ss", write, HARD, PERIODIC, 333, NULL));
992
    ...
993
}
994
 
995
/*---------------------------------------------------------------------*/
996
TASK write(void) {
997
    float msg[5];
998
    char *pun;
999
    ...
1000
 
1001
    while (1) {
1002
 
1003
        /* send a message to the `cc' cab */
1004
        pun = cab_reserve(cc);                /* reserve a buffer */
1005
        memcpy(pun, msg, 5 * sizeof(float));
1006
        cab_putmes(cc, pun);                  /* release the buffer */
1007
        task_endcycle();
1008
    }
1009
}
1010
 
1011
/*---------------------------------------------------------------------*/
1012
TASK read(void) {
1013
    float msg[5];
1014
    char *pun;
1015
    ...
1016
 
1017
    while (1) {
1018
 
1019
        /* get a message from the  `cc' CAB */
1020
        pun = cab_getmes(cc);                /* reserve a buffer */
1021
        memcpy(msg, pun, 5 * sizeof(float));
1022
        cab_unget(cc, pun);                  /* release the buffer */
1023
        task_endcycle();
1024
 }
1025
}
1026
\end{verbatim}
1027
\end{tt}
1028
\end{small}
1029
\end{minipage}
1030
 
1031
%----------------------------------------------------------------------------
1032
\vspace{7mm} \begin{intest}
1033
CAB\_CREATE\index{cab\_create()}
1034
\end{intest}
1035
 
1036
\begin{description}
1037
 
1038
\item [\textbf{CAB cab\_create(char {*}name, int dim\_mes, BYTE num\_mes)}]
1039
 
1040
\item [\textbf{Description:}]It initializes a CAB. \texttt{name} is a pointer to
1041
an identification string (used only for debugging purposes); \texttt{dim}
1042
is the size of the messages contained in the CAB; \texttt{numbuf}
1043
is the number of buffers the CAB is composed of. Notice that such
1044
a number must be greater than or equal to the number of tasks that
1045
use the CAB plus one.
1046
 
1047
\item [\textbf{Return value:}] It returns the index of the created CAB.
1048
 
1049
\item [\textbf{See also}:] \texttt{cab\_delete(), cab\_reserve(), cab\_putmes(),
1050
cab\_getmes(), cab\_unget()}.
1051
 
1052
\end{description}
1053
 
1054
%----------------------------------------------------------------------------
1055
\vspace{7mm} \begin{intest}
1056
CAB\_DELETE\index{cab\_delete()}
1057
\end{intest}
1058
 
1059
\begin{description}
1060
 
1061
\item [\textbf{void cab\_delete(CAB cc);}]
1062
 
1063
\item [\textbf{Description:}]It removes the \texttt{cc} CAB from the system,
1064
deallocating
1065
its buffers and data structures.
1066
 
1067
\item [\textbf{See also}:] \texttt{cab\_create(), cab\_reserve(), cab\_putmes(),
1068
cab\_getmes(), cab\_unget()}.
1069
 
1070
\end{description}
1071
 
1072
%----------------------------------------------------------------------------
1073
\vspace{7mm} \begin{intest}
1074
CAB\_RESERVE\index{cab\_reserve()}
1075
\end{intest}
1076
 
1077
\begin{description}
1078
 
1079
\item [\textbf{char {*}cab\_reserve(CAB cc);}]
1080
 
1081
\item [\textbf{Description:}]it reserves a buffer belonging to the \texttt{cc}
1082
CAB and returns a pointer to it. The primitive has to be used only by
1083
writers and \emph{never} by readers.
1084
 
1085
\item [\textbf{Return value:}] it returns a pointer to the reserved buffer.
1086
 
1087
\item [\textbf{See also}:] \texttt{cab\_delete(), cab\_create(), cab\_putmes(),
1088
cab\_getmes(), cab\_unget()}.
1089
 
1090
\end{description}
1091
 
1092
\pagebreak
1093
 
1094
%----------------------------------------------------------------------------
1095
\begin{intest}
1096
CAB\_PUTMES\index{cab\_putmes()}
1097
\end{intest}
1098
 
1099
\begin{description}
1100
 
1101
\item [\textbf{void cab\_putmes(CAB id, char {*}pun)}]
1102
 
1103
\item [\textbf{Description:}]It inserts the message pointed by \texttt{pun} into
1104
the CAB identified by \texttt{id}. This primitive must be used \emph{only}
1105
by writing tasks.
1106
 
1107
\item [\textbf{See also}:] \texttt{cab\_delete(), cab\_create(), cab\_reserve(),
1108
cab\_getmes(), cab\_unget()}.
1109
 
1110
\end{description}
1111
 
1112
%----------------------------------------------------------------------------
1113
\vspace{7mm} \begin{intest}
1114
CAB\_GETMES\index{cab\_getmes()}
1115
\end{intest}
1116
 
1117
\begin{description}
1118
 
1119
\item [\textbf{char {*}cab\_getmes(CAB cc);}]
1120
 
1121
\item [\textbf{Description:}]It returns a pointer to the latest message written
1122
into the \texttt{cc} CAB. This primitive must be used \emph{only}
1123
by reading tasks.
1124
 
1125
\item [\textbf{Returned value:}] It returns a pointer to the most recent
1126
message contained in the CAB.
1127
 
1128
\item [\textbf{See also}:] \texttt{cab\_delete(), cab\_create(), cab\_putmes(),
1129
cab\_reserve(), cab\_unget()}.
1130
 
1131
\end{description}
1132
 
1133
%----------------------------------------------------------------------------
1134
\vspace{7mm} \begin{intest}
1135
CAB\_UNGET\index{cab\_unget()}
1136
\end{intest}
1137
 
1138
\begin{description}
1139
 
1140
\item [\textbf{void cab\_unget(CAB cc, char {*}pun);}]
1141
 
1142
\item [\textbf{Description:}]it notifies the system that the buffer pointed by
1143
\texttt{pun} belonging to the \texttt{cc} CAB is no longer used by the calling
1144
task.
1145
 
1146
\item [\textbf{See also}:] \texttt{cab\_delete(), cab\_create(), cab\_reserve(),
1147
cab\_getmes(), cab\_putmes()}.
1148
 
1149
\end{description}
1150
 
1151
\section{POSIX Message Queues}
1152
 
1153
S.Ha.R.K. provides the message passing function defined in the POSIX
1154
standard. For more information, see Section 15 of the POSIX standard,
1155
Message Passing.