File: AA-D-5.html

package info (click to toggle)
ada-reference-manual 20021112web-3
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny, sarge
  • size: 18,652 kB
  • ctags: 8,921
  • sloc: makefile: 52; sh: 20
file content (241 lines) | stat: -rw-r--r-- 18,436 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
    <TITLE>AARM95 - Dynamic Priorities</TITLE>
    <META NAME="Author" CONTENT="JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor">
    <META NAME="GENERATOR" CONTENT="Arm_Form.Exe, Ada Reference Manual generator">
    <STYLE type="text/css">
    DIV.paranum {position: absolute; font-family: Arial, Helvetica, sans-serif; left: 0.5 em; top: auto}
    TT {font-family: "Courier New", monospace}
    DT {display: compact}
    DIV.Normal {font-family: "Times New Roman", Times, serif; margin-bottom: 0.6em}
    DIV.Wide {font-family: "Times New Roman", Times, serif; margin-top: 0.6em; margin-bottom: 0.6em}
    DIV.Annotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
    DIV.WideAnnotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0.6em; margin-bottom: 0.6em}
    DIV.Index {font-family: "Times New Roman", Times, serif}
    DIV.SyntaxSummary {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
    DIV.Notes {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.6em}
    DIV.NotesHeader {font-family: "Times New Roman", Times, serif; margin-left: 2.0em}
    DIV.SyntaxIndented {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
    DIV.Indented {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-bottom: 0.6em}
    DIV.CodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
    DIV.SmallIndented {font-family: "Times New Roman", Times, serif; margin-left:  10.0em; margin-bottom: 0.6em}
    DIV.SmallCodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-bottom: 0.6em}
    DIV.Examples {font-family: "Courier New", monospace; margin-left: 2.0em; margin-bottom: 0.6em}
    DIV.SmallExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 7.5em; margin-bottom: 0.6em}
    DIV.IndentedExamples {font-family: "Courier New", monospace; margin-left: 8.0em; margin-bottom: 0.6em}
    DIV.SmallIndentedExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left:  15.0em; margin-bottom: 0.6em}
    UL.Bulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.SmallBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.NestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.SmallNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.IndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.CodeIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.CodeIndentedNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.SyntaxIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.NotesBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
    UL.NotesNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    DL.Hanging {font-family: "Times New Roman", Times, serif; margin-top: 0em; margin-bottom: 0.6em}
    DD.Hanging {margin-left: 6.0em}
    DL.IndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
    DD.IndentedHanging {margin-left: 2.0em}
    DL.HangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
    DD.HangingInBulleted {margin-left: 4.0em}
    DL.SmallHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
    DD.SmallHanging {margin-left: 7.5em}
    DL.SmallIndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-top: 0em; margin-bottom: 0.6em}
    DD.SmallIndentedHanging {margin-left: 2.0em}
    DL.SmallHangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    DD.SmallHangingInBulleted {margin-left: 5.0em}
    DL.Enumerated {font-family: "Times New Roman", Times, serif; margin-right: 0.0em; margin-top: 0em; margin-bottom: 0.5em}
    DD.Enumerated {margin-left: 2.0em}
    DL.SmallEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
    DD.SmallEnumerated {margin-left: 2.5em}
    DL.NestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
    DL.SmallNestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
    </STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFF0" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<P><A HREF="AA-TOC.html">Contents</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-0-29.html">Index</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-D-4.html">Previous</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-D-6.html">Next</A></P>
<HR>
<H1> D.5 Dynamic Priorities</H1>
<DIV Class="Paranum"><FONT SIZE=-2>1</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;[This clause specifies how the base priority of
a task can be modified or queried at run time.] </DIV>

<H4 ALIGN=CENTER>Static Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>2</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em">&nbsp;&nbsp;&nbsp;The following language-defined
library package exists: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3</FONT></DIV>
<DIV Class="Examples"><TT><B>with</B>&nbsp;System;<BR>
<B>with</B>&nbsp;Ada.Task_Identification;&nbsp;<I>--&nbsp;See&nbsp;<A HREF="AA-C-7-1.html">C.7.1</A></I><BR>
<B>package</B>&nbsp;Ada.Dynamic_Priorities&nbsp;<B>is</B><A NAME="I6830"></A><A NAME="I6831"></A><A NAME="I6832"></A></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4</FONT></DIV>
<DIV Class="Examples"><TT>&nbsp;&nbsp;&nbsp;&nbsp;<B>procedure</B>&nbsp;<A NAME="I6833"></A><A NAME="I6834"></A>Set_Priority(Priority&nbsp;:&nbsp;<B>in</B>&nbsp;System.Any_Priority;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;:&nbsp;<B>in</B>&nbsp;Ada.Task_Identification.Task_ID&nbsp;:=<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ada.Task_Identification.Current_Task);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>5</FONT></DIV>
<DIV Class="Examples"><TT>&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;<A NAME="I6835"></A><A NAME="I6836"></A>Get_Priority&nbsp;(T&nbsp;:&nbsp;Ada.Task_Identification.Task_ID&nbsp;:=<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ada.Task_Identification.Current_Task)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>return</B>&nbsp;System.Any_Priority;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6</FONT></DIV>
<DIV Class="Examples"><TT><B>end</B>&nbsp;Ada.Dynamic_Priorities;</TT></DIV>

<H4 ALIGN=CENTER>Dynamic Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>7</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;The procedure Set_Priority sets the base priority
of the specified task to the specified Priority value. Set_Priority has
no effect if the task is terminated.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;The function Get_Priority returns T's current
base priority. <A NAME="I6837"></A>Tasking_Error is raised if the task
is terminated. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>There is no harm
in setting the priority of a terminated task. A previous version of Ada
9X made this a run-time error. However, there is little difference between
setting the priority of a terminated task, and setting the priority of
a task that is about to terminate very soon; neither case should be an
error. Furthermore, the run-time check is not necessarily feasible to
implement on all systems, since priority changes might be deferred due
to inter-processor communication overhead, so the error might not be
detected until after Set_Priority has returned.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>However, we wish to allow implementations
to avoid storing ``extra'' information about terminated tasks. Therefore,
we make Get_Priority of a terminated task raise an exception; the implementation
need not continue to store the priority of a task that has terminated.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;<A NAME="I6838"></A>Program_Error is raised by
Set_Priority and Get_Priority if T is equal to Null_Task_ID.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;Setting the task's base priority to the new value
takes place as soon as is practical but not while the task is performing
a protected action. This setting occurs no later then the next abort
completion point of the task T (see <A HREF="AA-9-8.html">9.8</A>). </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation Note: </B>When
Set_Priority is called by a task T1 to set the priority of T2, if T2
is blocked, waiting on an entry call queued on a protected object, the
entry queue needs to be reordered. Since T1 might have a priority that
is higher than the ceiling of the protected object, T1 cannot, in general,
do the reordering. One way to implement this is to wake T2 up and have
T2 do the work. This is similar to the disentangling of queues that needs
to happen when a high-priority task aborts a lower-priority task, which
might have a call queued on a protected object with a low ceiling. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10.b</FONT></DIV>
<DIV Class="Annotations" Style="margin-bottom: 0.4em"><FONT SIZE=-1><B>Reason:
</B>A previous version of Ada 9X made it a run-time error for a high-priority
task to set the priority of a lower-priority task that has a queued call
on a protected object with a low ceiling. This was changed because: </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10.c</FONT></DIV>
<UL Class="SmallBulleted"><FONT SIZE=-1><LI TYPE=DISC>The check was not feasible to implement on all systems,
since priority changes might be deferred due to inter-processor communication
overhead. The calling task would continue to execute without finding
out whether the operation succeeded or not.</LI></FONT></UL>
<DIV Class="Paranum"><FONT SIZE=-2>10.d</FONT></DIV>
<UL Class="SmallBulleted"><FONT SIZE=-1><LI TYPE=DISC>The run-time check would tend to cause intermittent system
failures -- how is the caller supposed to know whether the other task
happens to have a queued call at any given time? Consider for example
an interrupt that needs to trigger a priority change in some task. The
interrupt handler could not safely call Set_Priority without knowing
exactly what the other task is doing, or without severely restricting
the ceilings used in the system. If the interrupt handler wants to hand
the job off to a third task whose job is to call Set_Priority, this won't
help, because one would normally want the third task to have high priority.
</LI></FONT></UL>

<H4 ALIGN=CENTER>Bounded (Run-Time) Errors</H4>
<DIV Class="Paranum"><FONT SIZE=-2>11</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;<A NAME="I6839"></A>If a task is blocked on a
protected entry call, and the call is queued, it is a bounded error to
raise its base priority above the ceiling priority of the corresponding
protected object. When an entry call is cancelled, it is a bounded error
if the priority of the calling task is higher than the ceiling priority
of the corresponding protected object. <A NAME="I6840"></A>In either
of these cases, either Program_Error is raised in the task that called
the entry, or its priority is temporarily lowered, or both, or neither.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Note that
the error is ``blamed'' on the task that did the entry call, not the
task that called Set_Priority. This seems to make sense for the case
of a task blocked on a call, since if the Set_Priority had happened a
little bit sooner, before the task queued a call, the entry-calling task
would get the error. In the other case, there is no reason not to raise
the priority of a task that is executing in an <FONT FACE="Arial, Helvetica">abortable_part</FONT>,
so long as its priority is lowered before it gets to the end and needs
to cancel the call. The priority might need to be lowered to allow it
to remove the call from the entry queue, in order to avoid violating
the ceiling. This seems relatively harmless, since there is an error,
and the task is about to start raising an exception anyway.</FONT></DIV>

<H4 ALIGN=CENTER>Erroneous Execution</H4>
<DIV Class="Paranum"><FONT SIZE=-2>12</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;<A NAME="I6841"></A>If any subprogram in this
package is called with a parameter T that specifies a task object that
no longer exists, the execution of the program is erroneous. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Note that
this rule overrides the above rule saying that Program_Error is raised
on Get_Priority of a terminated task. If the task object still exists,
and the task is terminated, Get_Priority raises Program_Error. However,
if the task object no longer exists, calling Get_Priority causes erroneous
execution. </FONT></DIV>

<H4 ALIGN=CENTER>Metrics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>13</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em">&nbsp;&nbsp;&nbsp;&nbsp;The implementation
shall document the following metric: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>14</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>The execution time of a call to Set_Priority, for the nonpreempting
case, in processor clock cycles. This is measured for a call that modifies
the priority of a ready task that is not running (which cannot be the
calling one), where the new base priority of the affected task is lower
than the active priority of the calling task, and the affected task is
not on any entry queue and is not executing a protected operation. </LI></UL>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>15</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>22&nbsp;&nbsp;Setting a task's base
priority affects task dispatching. First, it can change the task's active
priority. Second, under the standard task dispatching policy it always
causes the task to move to the tail of the ready queue corresponding
to its active priority, even if the new base priority is unchanged.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>16</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>23&nbsp;&nbsp;Under the priority queuing
policy, setting a task's base priority has an effect on a queued entry
call if the task is blocked waiting for the call. That is, setting the
base priority of a task causes the priority of a queued entry call from
that task to be updated and the call to be removed and then reinserted
in the entry queue at the new priority (see <A HREF="AA-D-4.html">D.4</A>),
unless the call originated from the <FONT FACE="Arial, Helvetica">triggering_statement</FONT>
of an <FONT FACE="Arial, Helvetica">asynchronous_select</FONT>.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>17</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>24&nbsp;&nbsp;The effect of two or more
Set_Priority calls executed in parallel on the same task is defined as
executing these calls in some serial order.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>17.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Proof: </B>This follows from
the general reentrancy requirements stated near the beginning of <A HREF="AA-A.html">Annex
A</A>, ``<A HREF="AA-A.html">Predefined Language Environment</A>''.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>18</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>25&nbsp;&nbsp;The rule for when Tasking_Error
is raised for Set_Priority or Get_Priority is different from the rule
for when Tasking_Error is raised on an entry call (see <A HREF="AA-9-5-3.html">9.5.3</A>).
In particular, setting or querying the priority of a completed or an
abnormal task is allowed, so long as the task is not yet terminated.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>19</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>26&nbsp;&nbsp;Changing the priorities
of a set of tasks can be performed by a series of calls to Set_Priority
for each task separately. For this to work reliably, it should be done
within a protected operation that has high enough ceiling priority to
guarantee that the operation completes without being preempted by any
of the affected tasks.</FONT></DIV>

<HR>
<P><A HREF="AA-TOC.html">Contents</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-0-29.html">Index</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-D-4.html">Previous</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-D-6.html">Next</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-TTL.html">Legal</A></P>
</BODY>
</HTML>