160 algorithm for a single-processor system.\footnote{We shall come back |
163 algorithm for a single-processor system.\footnote{We shall come back |
161 later to the case of PIP on multi-processor systems.} Our model of |
164 later to the case of PIP on multi-processor systems.} Our model of |
162 PIP is based on Paulson's inductive approach to protocol |
165 PIP is based on Paulson's inductive approach to protocol |
163 verification \cite{Paulson98}, where the \emph{state} of a system is |
166 verification \cite{Paulson98}, where the \emph{state} of a system is |
164 given by a list of events that happened so far. \emph{Events} in PIP fall |
167 given by a list of events that happened so far. \emph{Events} in PIP fall |
165 into five categories defined as the datatype |
168 into five categories defined as the datatype: |
166 |
169 |
167 \begin{isabelle}\ \ \ \ \ %%% |
170 \begin{isabelle}\ \ \ \ \ %%% |
168 \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l} |
171 \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l} |
169 \isacommand{datatype} event |
172 \isacommand{datatype} event |
170 & @{text "="} & @{term "Create thread priority"}\\ |
173 & @{text "="} & @{term "Create thread priority"}\\ |
231 |
235 |
232 \noindent |
236 \noindent |
233 In this definition @{term "length s"} stands for the length of the list |
237 In this definition @{term "length s"} stands for the length of the list |
234 of events @{text s}. Again the default value in this function is @{text 0} |
238 of events @{text s}. Again the default value in this function is @{text 0} |
235 for threads that have not been created yet. A \emph{precedence} of a thread @{text th} in a |
239 for threads that have not been created yet. A \emph{precedence} of a thread @{text th} in a |
236 state @{text s} is a pair of natural numbers defined as |
240 state @{text s} is the pair of natural numbers defined as |
237 |
241 |
238 \begin{isabelle}\ \ \ \ \ %%% |
242 \begin{isabelle}\ \ \ \ \ %%% |
239 @{thm (rhs) preced_def[where thread="th"]} |
243 @{thm preced_def[where thread="th"]} |
240 \end{isabelle} |
244 \end{isabelle} |
241 |
245 |
242 \noindent |
246 \noindent |
243 The point of precedences is to schedule threads not according to priorities (because what should |
247 The point of precedences is to schedule threads not according to priorities (because what should |
244 we do in case two threads have the same priority), but according to precedences. |
248 we do in case two threads have the same priority), but according to precedences. |
245 Precedences allow us to always discriminate two threads with equal priority by |
249 Precedences allow us to always discriminate between two threads with equal priority by |
246 tacking into account the time when the priority was last set. We order precedences so |
250 tacking into account the time when the priority was last set. We order precedences so |
247 that threads with the same priority get a higher precedence if their priority has been |
251 that threads with the same priority get a higher precedence if their priority has been |
248 set earlier, since for such threads it is more urgent to finish. In an impementation |
252 set earlier, since for such threads it is more urgent to finish their work. In an impementation |
249 this choice would translate to a quite natural a FIFO-scheduling of processes with |
253 this choice would translate to a quite natural a FIFO-scheduling of processes with |
250 the same priority. |
254 the same priority. |
251 |
255 |
252 Next, we introduce the concept of \emph{waiting queues}. They are |
256 Next, we introduce the concept of \emph{waiting queues}. They are |
253 lists of threads associated with every resource. The first thread in |
257 lists of threads associated with every resource. The first thread in |
254 this list is chosen to be in the one that is in possession of the |
258 this list (the head, or short @{term hd}) is chosen to be in the one |
|
259 that is in possession of the |
255 ``lock'' of the corresponding resource. We model waiting queues as |
260 ``lock'' of the corresponding resource. We model waiting queues as |
256 functions, below abbreviated as @{text wq}, taking a resource as |
261 functions, below abbreviated as @{text wq}, taking a resource as |
257 argument and returning a list of threads. This allows us to define |
262 argument and returning a list of threads. This allows us to define |
258 when a thread \emph{holds}, respectively \emph{waits}, for a |
263 when a thread \emph{holds}, respectively \emph{waits} for, a |
259 resource @{text cs} given a waiting queue function. |
264 resource @{text cs} given a waiting queue function. |
260 |
265 |
261 \begin{isabelle}\ \ \ \ \ %%% |
266 \begin{isabelle}\ \ \ \ \ %%% |
262 \begin{tabular}{@ {}l} |
267 \begin{tabular}{@ {}l} |
263 @{thm s_holding_def[where thread="th"]}\\ |
268 @{thm cs_holding_def[where thread="th"]}\\ |
264 @{thm s_waiting_def[where thread="th"]} |
269 @{thm cs_waiting_def[where thread="th"]} |
265 \end{tabular} |
270 \end{tabular} |
266 \end{isabelle} |
271 \end{isabelle} |
267 |
272 |
268 \noindent |
273 \noindent |
269 In this definition we assume @{text "set"} converts a list into a set. |
274 In this definition we assume @{text "set"} converts a list into a set. |
|
275 Using @{term "holding"} and @{term waiting}, we can introduce \emph{Resource Allocation Graphs} |
|
276 (RAG), which represent the dependencies between threads and resources. |
|
277 We represent RAGs as relations using pairs of the form |
|
278 |
|
279 \begin{isabelle}\ \ \ \ \ %%% |
|
280 @{term "(Th th, Cs cs)"} \hspace{5mm}{\rm and}\hspace{5mm} |
|
281 @{term "(Cs cs, Th th)"} |
|
282 \end{isabelle} |
|
283 |
|
284 \noindent |
|
285 where the first stands for a \emph{waiting edge} and the second for a |
|
286 \emph{holding edge} (@{term Cs} and @{term Th} are constructors of a |
|
287 datatype for vertices). Given a waiting queue function, a RAG is defined |
|
288 as |
|
289 |
|
290 \begin{isabelle}\ \ \ \ \ %%% |
|
291 @{thm cs_depend_def} |
|
292 \end{isabelle} |
|
293 |
|
294 \noindent |
|
295 An instance of a RAG is as follows: |
|
296 |
|
297 \begin{center} |
|
298 Picture |
|
299 \end{center} |
|
300 |
|
301 \noindent |
|
302 The use or relations for representing RAGs allows us to conveninetly define |
|
303 the notion of the \emph{dependants} of a thread. This is defined as |
|
304 |
|
305 \begin{isabelle}\ \ \ \ \ %%% |
|
306 @{thm cs_dependents_def} |
|
307 \end{isabelle} |
|
308 |
|
309 \noindent |
|
310 This definition needs to account for all threads that wait for tread to |
|
311 release a resource. This means we need to include threads that transitively |
|
312 wait for a resource being realeased (in the picture this means also @{text "th\<^isub>3"}, |
|
313 which cannot make any progress unless @{text "th\<^isub>2"} makes progress which |
|
314 in turn waits for @{text "th\<^isub>1"}). If there is a cirle in a RAG, then clearly |
|
315 we have a deadlock. Therefore when we state our correctness property for PIP |
|
316 we must ensure that RAGs are not circular. This allows us to define the notion |
|
317 of the \emph{current precedence} of a thread @{text th} in a state @{text s}. |
|
318 |
|
319 \begin{isabelle}\ \ \ \ \ %%% |
|
320 @{thm cpreced_def2}\\ |
|
321 \end{isabelle} |
|
322 |
|
323 |
|
324 |
270 |
325 |
271 \begin{isabelle}\ \ \ \ \ %%% |
326 \begin{isabelle}\ \ \ \ \ %%% |
272 \begin{tabular}{@ {}l} |
327 \begin{tabular}{@ {}l} |
273 @{thm s_depend_def}\\ |
328 @{thm s_depend_def}\\ |
274 \end{tabular} |
329 \end{tabular} |