421 ``time-slicing'' threads with equal priority, but found that it does not lead to |
421 ``time-slicing'' threads with equal priority, but found that it does not lead to |
422 advantages in practice. On the contrary, according to their work having a policy |
422 advantages in practice. On the contrary, according to their work having a policy |
423 like our FIFO-scheduling of threads with equal priority reduces the number of |
423 like our FIFO-scheduling of threads with equal priority reduces the number of |
424 tasks involved in the inheritance process and thus minimises the number |
424 tasks involved in the inheritance process and thus minimises the number |
425 of potentially expensive thread-switches. |
425 of potentially expensive thread-switches. |
426 |
426 |
427 \endnote{{\bf NEEDED?} We will also need counters for @{term P} and @{term V} events of a thread @{term th} |
427 %\endnote{{\bf NEEDED?} We will also need counters for @{term P} and @{term V} events of a thread @{term th} |
428 in a state @{term s}. This can be straightforwardly defined in Isabelle as |
428 %in a state @{term s}. This can be straightforwardly defined in Isabelle as |
429 |
429 % |
430 \begin{isabelle}\ \ \ \ \ %%% |
430 %\begin{isabelle}\ \ \ \ \ %%% |
431 \mbox{\begin{tabular}{@ {}l} |
431 %\mbox{\begin{tabular}{@ {}l} |
432 @{thm cntP_def}\\ |
432 %@{thm cntP_def}\\ |
433 @{thm cntV_def} |
433 %@{thm cntV_def} |
434 \end{tabular}} |
434 %\end{tabular}} |
435 \end{isabelle} |
435 %\end{isabelle} |
436 |
436 % |
437 \noindent using the predefined function @{const count} for lists.} |
437 %\noindent using the predefined function @{const count} for lists.} |
438 |
438 |
439 Next, we introduce the concept of \emph{waiting queues}. They are |
439 Next, we introduce the concept of \emph{waiting queues}. They are |
440 lists of threads associated with every resource. The first thread in |
440 lists of threads associated with every resource. The first thread in |
441 this list (i.e.~the head, or short @{term hd}) is chosen to be the one |
441 this list (i.e.~the head, or short @{term hd}) is chosen to be the one |
442 that is in possession of the |
442 that is in possession of the |
526 |
526 |
527 \noindent |
527 \noindent |
528 If there is no cycle, then every RAG can be pictured as a forrest of trees, as |
528 If there is no cycle, then every RAG can be pictured as a forrest of trees, as |
529 for example in Figure~\ref{RAGgraph}. |
529 for example in Figure~\ref{RAGgraph}. |
530 |
530 |
531 Because of the RAGs, we will need to formalise some results about graphs. |
531 Because of the RAGs, we will need to formalise some results about |
532 While there are few formalisations for graphs already implemented in |
532 graphs. While there are few formalisations for graphs already |
533 Isabelle, we choose to introduce our own library of graphs for |
533 implemented in Isabelle, we choose to introduce our own library of |
534 PIP. The reason for this is that we wanted to be able to reason with |
534 graphs for PIP. The justification for this is that we wanted to be able to |
535 potentially infinite graphs (in the sense of infinitely branching |
535 reason about potentially infinite graphs (in the sense of infinitely |
536 and infinite size): the property that our RAGs are actually forrests |
536 branching and infinite size): the property that our RAGs are |
537 of finitely branching trees having only an finite depth should be |
537 actually forrests of finitely branching trees having only an finite |
538 something we can \emph{prove} for our model of PIP---it should not |
538 depth should be something we can \emph{prove} for our model of |
539 be an assumption we build already into our model. It seemed for our |
539 PIP---it should not be an assumption we build already into our |
540 purposes the most convenient represeantation of graphs are binary |
540 model. It seemed for our purposes the most convenient |
541 relations given by sets of pairs from \eqref{pairs}. The pairs stand for the edges in |
541 represeantation of graphs are binary relations given by sets of |
|
542 pairs shown in \eqref{pairs}. The pairs stand for the edges in |
542 graphs. This relation-based representation is convenient since we |
543 graphs. This relation-based representation is convenient since we |
543 can use the notions of transitive closure operations @{term "trancl |
544 can use the notions of transitive closure operations @{term "trancl |
544 DUMMY"} and @{term "rtrancl DUMMY"}, as well as relation composition |
545 DUMMY"} and @{term "rtrancl DUMMY"}, as well as relation |
545 @{term "DUMMY O DUMMY"}. A \emph{forrest} is defined as the |
546 composition. A \emph{forrest} is defined as the relation @{text |
546 relation @{text rel} that is \emph{single valued} and |
547 rel} that is \emph{single valued} and \emph{acyclic}: |
547 \emph{acyclic}: |
|
548 |
548 |
549 \begin{isabelle}\ \ \ \ \ %%% |
549 \begin{isabelle}\ \ \ \ \ %%% |
550 \begin{tabular}{@ {}l} |
550 \begin{tabular}{@ {}l} |
551 @{thm single_valued_def[where ?r="rel", THEN eq_reflection]}\\ |
551 @{thm single_valued_def[where ?r="rel", THEN eq_reflection]}\\ |
552 @{thm acyclic_def[where ?r="rel", THEN eq_reflection]} |
552 @{thm acyclic_def[where ?r="rel", THEN eq_reflection]} |
553 \end{tabular} |
553 \end{tabular} |
554 \end{isabelle} |
554 \end{isabelle} |
555 |
555 |
556 \noindent |
556 \noindent |
557 The \emph{children}, \emph{subtree} and \emph{ancestors} of a node in a graph are |
557 The \emph{children}, \emph{subtree} and \emph{ancestors} of a node in a graph |
558 defined as |
558 can be easily defined relationally as |
559 |
559 |
560 \begin{isabelle}\ \ \ \ \ %%% |
560 \begin{isabelle}\ \ \ \ \ %%% |
561 \begin{tabular}{@ {}l} |
561 \begin{tabular}{@ {}l} |
562 @{thm children_def[where ?r="rel" and ?x="node", THEN eq_reflection]}\\ |
562 @{thm children_def[where ?r="rel" and ?x="node", THEN eq_reflection]}\\ |
563 @{thm subtree_def[where ?r="rel" and ?x="node", THEN eq_reflection]}\\ |
563 @{thm subtree_def[where ?r="rel" and ?x="node", THEN eq_reflection]}\\ |
572 |
572 |
573 \endnote{ |
573 \endnote{ |
574 \begin{isabelle}\ \ \ \ \ %%% |
574 \begin{isabelle}\ \ \ \ \ %%% |
575 @{thm rtrancl_path.intros} |
575 @{thm rtrancl_path.intros} |
576 \end{isabelle} |
576 \end{isabelle} |
577 |
577 |
578 \begin{isabelle}\ \ \ \ \ %%% |
578 %\begin{isabelle}\ \ \ \ \ %%% |
579 @{thm rpath_def} |
579 %@{thm rpath_def} |
580 \end{isabelle}} |
580 %\end{isabelle} |
581 |
581 } |
582 |
582 |
583 \endnote{{\bf Lemma about overlapping paths}} |
583 |
|
584 %\endnote{{\bf Lemma about overlapping paths}} |
584 |
585 |
585 The locking mechanism of PIP ensures that for each thread node, |
586 The locking mechanism of PIP ensures that for each thread node, |
586 there can be many incoming holding edges in the RAG, but at most one |
587 there can be many incoming holding edges in the RAG, but at most one |
587 out going waiting edge. The reason is that when a thread asks for |
588 out going waiting edge. The reason is that when a thread asks for |
588 resource that is locked already, then the thread is blocked and |
589 resource that is locked already, then the thread is blocked and |
829 |
830 |
830 \begin{center} |
831 \begin{center} |
831 @{thm[mode=Rule] thread_set[where thread=th]} |
832 @{thm[mode=Rule] thread_set[where thread=th]} |
832 \end{center} |
833 \end{center} |
833 |
834 |
834 \noindent |
835 \noindent If a thread wants to lock a resource, then the thread |
835 If a thread wants to lock a resource, then the thread needs to be |
836 needs to be running and also we have to make sure that the resource |
836 running and also we have to make sure that the resource lock does |
837 lock does not lead to a cycle in the RAG (the prurpose of the second |
837 not lead to a cycle in the RAG. In practice, ensuring the latter |
838 premise in the rule below). In practice, ensuring the latter is the |
838 is the responsibility of the programmer. In our formal |
839 responsibility of the programmer. In our formal model we brush |
839 model we brush aside these problematic cases in order to be able to make |
840 aside these problematic cases in order to be able to make some |
840 some meaningful statements about PIP.\footnote{This situation is |
841 meaningful statements about PIP.\footnote{This situation is similar |
841 similar to the infamous \emph{occurs check} in Prolog: In order to say |
842 to the infamous \emph{occurs check} in Prolog: In order to say |
842 anything meaningful about unification, one needs to perform an occurs |
843 anything meaningful about unification, one needs to perform an |
843 check. But in practice the occurs check is omitted and the |
844 occurs check. But in practice the occurs check is omitted and the |
844 responsibility for avoiding problems rests with the programmer.} |
845 responsibility for avoiding problems rests with the programmer.} |
845 |
846 |
846 |
847 |
847 \begin{center} |
848 \begin{center} |
848 @{thm[mode=Rule] thread_P[where thread=th]} |
849 @{thm[mode=Rule] thread_P[where thread=th]} |
979 priority are created in @{text "s'"}. We will actually prove a |
983 priority are created in @{text "s'"}. We will actually prove a |
980 stronger statement where we also provide the current precedence of |
984 stronger statement where we also provide the current precedence of |
981 the blocking thread. |
985 the blocking thread. |
982 |
986 |
983 However, this correctness criterion hinges upon a number of |
987 However, this correctness criterion hinges upon a number of |
984 assumptions about the states @{text s} and @{text "s' @ s"}, the |
988 natural assumptions about the states @{text s} and @{text "s' @ s"}, the |
985 thread @{text th} and the events happening in @{text s'}. We list |
989 thread @{text th} and the events happening in @{text s'}. We list |
986 them next: |
990 them next: |
987 |
991 |
988 \begin{quote} |
992 \begin{quote} |
989 {\bf Assumptions on the states {\boldmath@{text s}} and |
993 {\bf Assumptions on the states {\boldmath@{text s}} and |
1014 {\bf Assumptions on the events in {\boldmath@{text "s'"}:}} We want to prove that @{text th} cannot |
1018 {\bf Assumptions on the events in {\boldmath@{text "s'"}:}} We want to prove that @{text th} cannot |
1015 be blocked indefinitely. Of course this can happen if threads with higher priority |
1019 be blocked indefinitely. Of course this can happen if threads with higher priority |
1016 than @{text th} are continuously created in @{text s'}. Therefore we have to assume that |
1020 than @{text th} are continuously created in @{text s'}. Therefore we have to assume that |
1017 events in @{text s'} can only create (respectively set) threads with equal or lower |
1021 events in @{text s'} can only create (respectively set) threads with equal or lower |
1018 priority than @{text prio} of @{text th}. We also need to assume that the |
1022 priority than @{text prio} of @{text th}. We also need to assume that the |
1019 priority of @{text "th"} does not get reset and also that @{text th} does |
1023 priority of @{text "th"} does not get reset and all other reset priorities are either |
|
1024 less or equal. Moreover, we assume that @{text th} does |
1020 not get ``exited'' in @{text "s'"}. This can be ensured by assuming the following three implications. |
1025 not get ``exited'' in @{text "s'"}. This can be ensured by assuming the following three implications. |
1021 \begin{isabelle}\ \ \ \ \ %%% |
1026 \begin{isabelle}\ \ \ \ \ %%% |
1022 \begin{tabular}{l} |
1027 \begin{tabular}{l} |
1023 {If}~~@{text "Create th' prio' \<in> set s'"}~~{then}~~@{text "prio' \<le> prio"}\\ |
1028 {If}~~@{text "Create th' prio' \<in> set s'"}~~{then}~~@{text "prio' \<le> prio"}\\ |
1024 {If}~~@{text "Set th' prio' \<in> set s'"}~~{then}~~@{text "th' \<noteq> th"}~~{and}~~@{text "prio' \<le> prio"}\\ |
1029 {If}~~@{text "Set th' prio' \<in> set s'"}~~{then}~~@{text "th' \<noteq> th"}~~{and}~~@{text "prio' \<le> prio"}\\ |
1046 |
1051 |
1047 \noindent This theorem ensures that the thread @{text th}, which has |
1052 \noindent This theorem ensures that the thread @{text th}, which has |
1048 the highest precedence in the state @{text s}, is either running in |
1053 the highest precedence in the state @{text s}, is either running in |
1049 state @{term "s' @ s"}, or can only be blocked in the state @{text |
1054 state @{term "s' @ s"}, or can only be blocked in the state @{text |
1050 "s' @ s"} by a thread @{text th'} that already existed in @{text s} |
1055 "s' @ s"} by a thread @{text th'} that already existed in @{text s} |
1051 and requested or had a lock on at least one resource---that means |
1056 and requested a resource or had a lock on at least one resource---that means |
1052 the thread was not \emph{detached} in @{text s}. As we shall see |
1057 the thread was not \emph{detached} in @{text s}. As we shall see |
1053 shortly, that means there are only finitely many threads that can |
1058 shortly, that means there are only finitely many threads that can |
1054 block @{text th} in this way and then they need to run with the same |
1059 block @{text th} in this way and then they need to run with the same |
1055 precedence as @{text th}. |
1060 precedence as @{text th}. |
1056 |
1061 |
1057 Like in the argument by Sha et al.~our finite bound does not |
1062 |
1058 guarantee absence of indefinite Priority Inversion. For this we |
|
1059 further have to assume that every thread gives up its resources |
|
1060 after a finite amount of time. We found that this assumption is |
|
1061 awkward to formalise in our model. There are mainly two reasons for |
|
1062 this: First, we do not specify what ``running'' the code of a thread |
|
1063 means, for example by giving an operational semantics for machine |
|
1064 instructions. Therefore we cannot characterise what are ``good'' |
|
1065 programs that contain for every looking request also a corresponding |
|
1066 unlocking request for a resource. Second, we would need to specify a |
|
1067 kind of global clock that tracks the time how long a thread locks a |
|
1068 resource. But this seems difficult, because how do we conveniently |
|
1069 distinguish between a thread that ``just'' locks a resource for a |
|
1070 very long time and one that locks it forever. Therefore we decided |
|
1071 to leave out this property and let the programmer assume the |
|
1072 responsibility to program threads in such a benign manner (in |
|
1073 addition to causing no circularity in the RAG). In this detail, we |
|
1074 do not make any progress in comparison with the work by Sha et al. |
|
1075 However, we are able to combine their two separate bounds into a |
|
1076 single theorem improving their bound. |
|
1077 |
|
1078 %% HERE |
1063 %% HERE |
1079 |
1064 |
1080 Given our assumptions (on @{text th}), the first property we can |
1065 Given our assumptions (on @{text th}), the first property we can |
1081 show is that any running thread, say @{text "th'"}, has the same |
1066 show is that any running thread, say @{text "th'"}, has the same |
1082 precedence as @{text th}: |
1067 precedence as @{text th}: |
1117 |
1102 |
1118 Next we show that a running thread @{text "th'"} must either wait for or |
1103 Next we show that a running thread @{text "th'"} must either wait for or |
1119 hold a resource in state @{text s}. |
1104 hold a resource in state @{text s}. |
1120 |
1105 |
1121 \begin{lemma}\label{notdetached} |
1106 \begin{lemma}\label{notdetached} |
1122 If @{term "th' \<in> running (s' @ s)"} then @{term "\<not>detached s th'"}. |
1107 If @{term "th' \<in> running (s' @ s)"} and @{term "th \<noteq> th'"} then @{term "\<not>detached s th'"}. |
1123 \end{lemma} |
1108 \end{lemma} |
1124 |
1109 |
1125 \begin{proof} Let us assume @{text "th'"} is detached in state |
1110 \begin{proof} Let us assume @{text "th'"} is detached in state |
1126 @{text "s"}, then, according to the definition of detached, @{text |
1111 @{text "s"}, then, according to the definition of detached, @{text |
1127 "th’"} does not hold or wait for any resource. Hence the @{text |
1112 "th’"} does not hold or wait for any resource. Hence the @{text |
1514 %Since there are only finite many threads live and holding some resource at any moment, |
1499 %Since there are only finite many threads live and holding some resource at any moment, |
1515 %if every such thread can release all its resources in finite duration, then after finite |
1500 %if every such thread can release all its resources in finite duration, then after finite |
1516 %duration, none of them may block @{term "th"} anymore. So, no priority inversion may happen |
1501 %duration, none of them may block @{term "th"} anymore. So, no priority inversion may happen |
1517 %then. |
1502 %then. |
1518 |
1503 |
1519 NOTE: about bounds in sha et al and ours: |
1504 NOTE: about bounds in sha et al and ours: they prove a bound on the length of individual |
|
1505 blocages. We prove a bound for the overall-blockage. |
1520 |
1506 |
1521 There are low priority threads, |
1507 There are low priority threads, |
1522 which do not hold any resources, |
1508 which do not hold any resources, |
1523 such thread will not block th. |
1509 such thread will not block th. |
1524 Their Theorem 3 does not exclude such threads. |
1510 Their Theorem 3 does not exclude such threads. |
1531 |
1517 |
1532 *} |
1518 *} |
1533 (*<*) |
1519 (*<*) |
1534 end |
1520 end |
1535 (*>*) |
1521 (*>*) |
|
1522 |
|
1523 section {* Avoiding Indefinite Priority Inversion *} |
|
1524 |
|
1525 text {* |
|
1526 Like in the argument by Sha et al.~our finite bound does not |
|
1527 guarantee absence of indefinite Priority Inversion. For this we |
|
1528 further have to assume that every thread gives up its resources |
|
1529 after a finite amount of time. We found that this assumption is |
|
1530 awkward to formalise in our model. There are mainly two reasons for |
|
1531 this: First, we do not specify what ``running'' the code of a thread |
|
1532 means, for example by giving an operational semantics for machine |
|
1533 instructions. Therefore we cannot characterise what are ``good'' |
|
1534 programs that contain for every looking request also a corresponding |
|
1535 unlocking request for a resource. Second, we would need to specify a |
|
1536 kind of global clock that tracks the time how long a thread locks a |
|
1537 resource. But this seems difficult, because how do we conveniently |
|
1538 distinguish between a thread that ``just'' locks a resource for a |
|
1539 very long time and one that locks it forever. Therefore we decided |
|
1540 to leave out this property and let the programmer assume the |
|
1541 responsibility to program threads in such a benign manner (in |
|
1542 addition to causing no circularity in the RAG). In this detail, we |
|
1543 do not make any progress in comparison with the work by Sha et al. |
|
1544 However, we are able to combine their two separate bounds into a |
|
1545 single theorem improving their bound. |
|
1546 |
|
1547 *} |
|
1548 |
1536 |
1549 |
1537 section {* Properties for an Implementation\label{implement} *} |
1550 section {* Properties for an Implementation\label{implement} *} |
1538 |
1551 |
1539 text {* |
1552 text {* |
1540 While our formalised proof gives us confidence about the correctness of our model of PIP, |
1553 While our formalised proof gives us confidence about the correctness of our model of PIP, |