147 is that such issues clearly show up and cannot be overlooked as in |
147 is that such issues clearly show up and cannot be overlooked as in |
148 informal reasoning (since we have to analyse all possible behaviours |
148 informal reasoning (since we have to analyse all possible behaviours |
149 of threads, i.e.~\emph{traces}, that could possibly happen).\medskip |
149 of threads, i.e.~\emph{traces}, that could possibly happen).\medskip |
150 |
150 |
151 \noindent |
151 \noindent |
152 {\bf Contributions:} There have been earlier formal investigations |
152 {\bf Contributions:} There have been earlier formal investigations |
153 into PIP, but ...\cite{Faria08} |
153 into PIP \cite{conf/fase/JahierHR09,WellingsBSB07,Faria08}, but they |
|
154 are using model checking technology. As far as we are aware, this is |
|
155 the first formalised proof for the correctness of PIP. In contrast |
|
156 to model checking, our formalisation provides insight into why PIP |
|
157 is correct and allows us to prove stronger properties. For this Isar |
|
158 and Isabelle/HOL is an attractive tool for exploring definitions and |
|
159 keeping proofs consistent. |
|
160 |
|
161 For example, we find through formalization that the choice of next |
|
162 thread to take a lock when a resource is released is irrelevant for |
|
163 the very basic property of PIP to hold. |
|
164 |
|
165 Despite the wide use of Priority Inheritance Protocol in real time |
|
166 operating system, it’s correctness has never been formally proved |
|
167 and mechanically checked. All existing verification are based on |
|
168 model checking technology. Full automatic verification gives little |
|
169 help to understand why the protocol is correct. And results such |
|
170 obtained only apply to models of limited size. This paper presents a |
|
171 formal verification based on theorem proving. Machine checked formal |
|
172 proof does help to get deeper understanding. We found the fact which |
|
173 is not mentioned in the literature, that the choice of next thread |
|
174 to take over when an critical resource is release does not affect |
|
175 the correctness of the protocol. The paper also shows how formal |
|
176 proof can help to construct correct and efficient implementation. |
154 |
177 |
155 vt (valid trace) was introduced earlier, cite |
178 vt (valid trace) was introduced earlier, cite |
156 |
179 |
157 distributed PIP |
180 |
158 |
|
159 Paulson's method has not been used outside security field, except |
181 Paulson's method has not been used outside security field, except |
160 work by Zhang et al. |
182 work by Zhang et al. |
161 |
183 |
162 no clue about multi-processor case according to \cite{Steinberg10} |
184 How did Sha et al prove it....they did not use Paulson's method. |
163 *} |
185 *} |
164 |
186 |
165 section {* Formal Model of the Priority Inheritance Protocol *} |
187 section {* Formal Model of the Priority Inheritance Protocol *} |
166 |
188 |
167 text {* |
189 text {* |
282 At the beginning, that is in the state where no thread is created yet, |
304 At the beginning, that is in the state where no thread is created yet, |
283 the waiting queue function will be the function that returns the |
305 the waiting queue function will be the function that returns the |
284 empty list for every resource. |
306 empty list for every resource. |
285 |
307 |
286 \begin{isabelle}\ \ \ \ \ %%% |
308 \begin{isabelle}\ \ \ \ \ %%% |
287 @{abbrev all_unlocked} |
309 @{abbrev all_unlocked}\hfill\numbered{allunlocked} |
288 \end{isabelle} |
310 \end{isabelle} |
289 |
311 |
290 \noindent |
312 \noindent |
291 Using @{term "holding"} and @{term waiting}, we can introduce \emph{Resource Allocation Graphs} |
313 Using @{term "holding"} and @{term waiting}, we can introduce \emph{Resource Allocation Graphs} |
292 (RAG), which represent the dependencies between threads and resources. |
314 (RAG), which represent the dependencies between threads and resources. |
381 The first function is a waiting queue function (that is it takes a resource @{text "cs"} and returns the |
403 The first function is a waiting queue function (that is it takes a resource @{text "cs"} and returns the |
382 corresponding list of threads that wait for it), the second is a function that takes |
404 corresponding list of threads that wait for it), the second is a function that takes |
383 a thread and returns its current precedence (see \eqref{cpreced}). We assume the usual getter and |
405 a thread and returns its current precedence (see \eqref{cpreced}). We assume the usual getter and |
384 setter methods for such records. |
406 setter methods for such records. |
385 |
407 |
386 In the initial state, the scheduler starts with all resources unlocked and the |
408 In the initial state, the scheduler starts with all resources unlocked (see \eqref{allunlocked}) and the |
387 current precedence of every thread is initialised with @{term "Prc 0 0"}; that means |
409 current precedence of every thread is initialised with @{term "Prc 0 0"}; that means |
388 \mbox{@{abbrev initial_cprec}}. Therefore |
410 \mbox{@{abbrev initial_cprec}}. Therefore |
389 we have |
411 we have |
390 |
412 |
391 \begin{isabelle}\ \ \ \ \ %%% |
413 \begin{isabelle}\ \ \ \ \ %%% |
433 \end{tabular} |
455 \end{tabular} |
434 \end{isabelle} |
456 \end{isabelle} |
435 |
457 |
436 \noindent |
458 \noindent |
437 The clause for event @{term "V th cs"} is similar, except that we need to update the waiting queue function |
459 The clause for event @{term "V th cs"} is similar, except that we need to update the waiting queue function |
438 so that the thread that possessed the lock is deleted from the corresponding thread list. For this we use |
460 so that the thread that possessed the lock is deleted from the corresponding thread list. For this |
|
461 list transformation, we use |
439 the auxiliary function @{term release}. A simple version of @{term release} would |
462 the auxiliary function @{term release}. A simple version of @{term release} would |
440 just delete this thread and return the rest, namely |
463 just delete this thread and return the rest, namely |
441 |
464 |
442 \begin{isabelle}\ \ \ \ \ %%% |
465 \begin{isabelle}\ \ \ \ \ %%% |
443 \begin{tabular}{@ {}lcl} |
466 \begin{tabular}{@ {}lcl} |
529 \end{center} |
552 \end{center} |
530 |
553 |
531 \noindent |
554 \noindent |
532 The first rule states that a thread can only be created, if it does not yet exists. |
555 The first rule states that a thread can only be created, if it does not yet exists. |
533 Similarly, the second rule states that a thread can only be terminated if it was |
556 Similarly, the second rule states that a thread can only be terminated if it was |
534 running and does not lock any resources anymore. The event @{text Set} can happen |
557 running and does not lock any resources anymore (to simplify ). The event @{text Set} can happen |
535 if the corresponding thread is running. |
558 if the corresponding thread is running. |
536 |
559 |
537 \begin{center} |
560 \begin{center} |
538 @{thm[mode=Rule] thread_set[where thread=th]} |
561 @{thm[mode=Rule] thread_set[where thread=th]} |
539 \end{center} |
562 \end{center} |
540 |
563 |
541 \noindent |
564 \noindent |
542 If a thread wants to lock a resource, then the thread needs to be running and |
565 If a thread wants to lock a resource, then the thread needs to be |
543 also we have to make sure that the resource lock doe not lead to a cycle in the |
566 running and also we have to make sure that the resource lock does |
544 RAG. Similarly, if a thread wants to release a lock on a resource, then it must |
567 not lead to a cycle in the RAG. In practice, ensuring the latter is |
545 be running and in the possession of that lock. This is formally given by the |
568 of course the responsibility of the programmer. Here in our formal |
546 last two inference rules of @{term step}. |
569 model we just exclude such problematic cases in order to make |
|
570 some meaningful statements about PIP.\footnote{This situation is |
|
571 similar to the infamous occurs check in Prolog: in order to say |
|
572 anything meaningful about unification, we need to perform an occurs |
|
573 check; but in practice the occurs check is ommited and the |
|
574 responsibility to avoid problems rests with the programmer.} |
|
575 Similarly, if a thread wants to release a lock on a resource, then |
|
576 it must be running and in the possession of that lock. This is |
|
577 formally given by the last two inference rules of @{term step}. |
547 |
578 |
548 \begin{center} |
579 \begin{center} |
549 \begin{tabular}{c} |
580 \begin{tabular}{c} |
550 @{thm[mode=Rule] thread_P[where thread=th]}\medskip\\ |
581 @{thm[mode=Rule] thread_P[where thread=th]}\medskip\\ |
551 @{thm[mode=Rule] thread_V[where thread=th]}\\ |
582 @{thm[mode=Rule] thread_V[where thread=th]}\\ |
567 properties that show our version of PIP is correct. |
598 properties that show our version of PIP is correct. |
568 *} |
599 *} |
569 |
600 |
570 section {* Correctness Proof *} |
601 section {* Correctness Proof *} |
571 |
602 |
572 text {* TO DO *} |
603 |
|
604 (*<*) |
|
605 context extend_highest_gen |
|
606 begin |
|
607 (*>*) |
|
608 |
|
609 print_locale extend_highest_gen |
|
610 thm extend_highest_gen_def |
|
611 thm extend_highest_gen_axioms_def |
|
612 thm highest_gen_def |
|
613 text {* |
|
614 Main lemma |
|
615 |
|
616 \begin{enumerate} |
|
617 \item @{term "s"} is a valid state (@{text "vt_s"}): |
|
618 @{thm vt_s}. |
|
619 \item @{term "th"} is a living thread in @{term "s"} (@{text "threads_s"}): |
|
620 @{thm threads_s}. |
|
621 \item @{term "th"} has the highest precedence in @{term "s"} (@{text "highest"}): |
|
622 @{thm highest}. |
|
623 \item The precedence of @{term "th"} is @{term "Prc prio tm"} (@{text "preced_th"}): |
|
624 @{thm preced_th}. |
|
625 \end{enumerate} |
|
626 |
|
627 |
|
628 \begin{lemma} |
|
629 @{thm[mode=IfThen] moment_blocked} |
|
630 \end{lemma} |
|
631 |
|
632 \begin{theorem} |
|
633 @{thm[mode=IfThen] runing_inversion_2} |
|
634 \end{theorem} |
|
635 |
|
636 |
|
637 |
|
638 |
|
639 TO DO |
|
640 |
|
641 *} |
|
642 |
|
643 (*<*) |
|
644 end |
|
645 (*>*) |
573 |
646 |
574 section {* Properties for an Implementation *} |
647 section {* Properties for an Implementation *} |
575 |
648 |
576 text {* TO DO *} |
649 text {* TO DO *} |
577 |
650 |