1837 in PIP is quite ``heavy weight'' in Linux (see the Introduction). |
1837 in PIP is quite ``heavy weight'' in Linux (see the Introduction). |
1838 In our model of PIP the current precedence of a thread in a state @{text s} |
1838 In our model of PIP the current precedence of a thread in a state @{text s} |
1839 depends on the precedenes of all threads in its subtree---a ``global'' transitive notion, |
1839 depends on the precedenes of all threads in its subtree---a ``global'' transitive notion, |
1840 which is indeed heavy weight (see the equation for @{text cprec} shown in \eqref{overloaded}). |
1840 which is indeed heavy weight (see the equation for @{text cprec} shown in \eqref{overloaded}). |
1841 We can however improve upon this. For this recall the notion |
1841 We can however improve upon this. For this recall the notion |
1842 of @{term children} of a thread @{text th} (defined in \eqref{children}) |
1842 of @{term children} of a thread @{text th} defined in \eqref{children}. |
1843 where a child is a thread that is only one ``hop'' away from the thread |
1843 There a child is a thread that is only one ``hop'' away from the thread |
1844 @{text th} in the @{term TDG} (and waiting for @{text th} to release |
1844 @{text th} in the @{term TDG} (and waiting for @{text th} to release |
1845 a resource). Using children, we can prove the following lemma for more efficiently calculating |
1845 a resource). Using children, we can prove the following lemma for more efficiently calculating |
1846 @{text cprec} of a thread @{text th}. |
1846 @{text cprec} of a thread @{text th}. |
1847 |
1847 |
1848 |
1848 |
1863 However, the current precedence of a thread @{text th}, say, |
1863 However, the current precedence of a thread @{text th}, say, |
1864 only needs to be recomputed when @{text "(i)"} its static |
1864 only needs to be recomputed when @{text "(i)"} its static |
1865 precedence is re-set or when @{text "(ii)"} one of |
1865 precedence is re-set or when @{text "(ii)"} one of |
1866 its children changes its current precedence or when @{text "(iii)"} the children set changes |
1866 its children changes its current precedence or when @{text "(iii)"} the children set changes |
1867 (for example in an @{text "V"}-event). |
1867 (for example in an @{text "V"}-event). |
1868 If only the static precedence or the children-set changes, the we can |
1868 If only the static precedence or the children-set changes, then we can |
1869 avoid the recursion and compute the @{text cprec} of @{text th} locally. |
1869 avoid the recursion and compute the @{text cprec} of @{text th} locally. |
1870 In this cases |
1870 In such cases |
1871 the recursion does not need to decend into the corresponding subtree. |
1871 the recursion does not need to decend into the corresponding subtree. |
1872 Once the current |
1872 Once the current |
1873 precedence is computed in this more efficient manner, the selection |
1873 precedence is computed in this more efficient manner, the selection |
1874 of the thread with highest precedence from a set of ready threads is |
1874 of the thread with highest precedence from a set of ready threads is |
1875 a standard scheduling operation implemented in most operating |
1875 a standard scheduling operation and implemented in most operating |
1876 systems. |
1876 systems. |
1877 |
1877 |
1878 %\begin{proof}[of Lemma~\ref{childrenlem}] |
1878 %\begin{proof}[of Lemma~\ref{childrenlem}] |
1879 %Test |
1879 %Test |
1880 %\end{proof} |
1880 %\end{proof} |
1946 subtree of any other thread. So all current precedences of other |
1946 subtree of any other thread. So all current precedences of other |
1947 threads are unchanged. |
1947 threads are unchanged. |
1948 |
1948 |
1949 %The second |
1949 %The second |
1950 %however states that only threads that are \emph{not} dependants of @{text th} have their |
1950 %however states that only threads that are \emph{not} dependants of @{text th} have their |
1951 %current precedence unchanged. For the others we have to recalculate the current |
1951 %current precedence unchanged. For the ancestors of @{text th}, we |
|
1952 %have to recalculate the current |
1952 %precedence. To do this we can start from @{term "th"} |
1953 %precedence. To do this we can start from @{term "th"} |
1953 %and follow the @{term "depend"}-edges to recompute using Lemma~\ref{childrenlem} |
1954 %and follow the @{term "depend"}-edges to recompute using Lemma~\ref{childrenlem} |
1954 %the @{term "cp"} of every |
1955 %the @{term "cp"} of every |
1955 %thread encountered on the way. Since the @{term "depend"} |
1956 %thread encountered on the way. Since the @{term "depend"} |
1956 %is assumed to be loop free, this procedure will always stop. The following two lemmas show, however, |
1957 %is assumed to be loop free, this procedure will always stop. The following two lemmas show, however, |
2079 \end{tabular} |
2080 \end{tabular} |
2080 \end{isabelle} |
2081 \end{isabelle} |
2081 |
2082 |
2082 \noindent That means we have to add a waiting edge to the @{text |
2083 \noindent That means we have to add a waiting edge to the @{text |
2083 RAG}. Furthermore the current precedence for all threads that are |
2084 RAG}. Furthermore the current precedence for all threads that are |
2084 not ancestors of @{text "th"} are unchanged. For the others we need |
2085 not ancestors of @{text "th"} are unchanged. For the ancestors of |
|
2086 @{text th} we need |
2085 to follow the edges in the @{text TDG} and recompute the @{term |
2087 to follow the edges in the @{text TDG} and recompute the @{term |
2086 "cp"}. To do this we can start from @{term "th"} and follow the |
2088 "cprecs"}. Whereas in all other event we might have to make |
|
2089 modifications to the @{text "RAG"}, no recalculation of @{text |
|
2090 cprec} depends on the @{text RAG}. This is the only case where |
|
2091 the recalulation needs to take the connections in the @{text RAG} into |
|
2092 account. |
|
2093 To do this we can start from @{term "th"} and follow the |
2087 @{term "children"}-edges to recompute the @{term "cp"} of every |
2094 @{term "children"}-edges to recompute the @{term "cp"} of every |
2088 thread encountered on the way using Lemma~\ref{childrenlem}. Since |
2095 thread encountered on the way using Lemma~\ref{childrenlem}. |
|
2096 This means the recomputation can be done locally (level-by-level) |
|
2097 in a bottom-up fashion. |
|
2098 Since |
2089 the @{text RAG}, and thus @{text "TDG"}, are loop free, this |
2099 the @{text RAG}, and thus @{text "TDG"}, are loop free, this |
2090 procedure will always stop. The following lemma shows, however, that |
2100 procedure will always stop. The following lemma shows, however, that |
2091 this procedure can actually stop often earlier without having to |
2101 this procedure can actually stop often earlier without having to |
2092 consider all ancestors. |
2102 consider all ancestors. |
2093 |
2103 |
2098 & @{thm (prem 3) valid_trace_p_w.cp_up_tG}\\ |
2108 & @{thm (prem 3) valid_trace_p_w.cp_up_tG}\\ |
2099 & @{text then} @{thm (concl) valid_trace_p_w.cp_up_tG}\\ |
2109 & @{text then} @{thm (concl) valid_trace_p_w.cp_up_tG}\\ |
2100 \end{tabular} |
2110 \end{tabular} |
2101 \end{isabelle} |
2111 \end{isabelle} |
2102 |
2112 |
2103 \noindent This lemma states that if an intermediate @{term cp}-value |
2113 \noindent This property states that if an intermediate @{term cp}-value |
2104 does not change (in this case the @{text cprec}-value of @{text "th'"}), then the procedure can |
2114 does not change (in this case the @{text cprec}-value of @{text "th'"}), then the procedure can |
2105 also stop, because none of @{text "th'"} ancestor-threads will have their |
2115 also stop, because none of @{text "th'"} ancestor-threads will have their |
2106 current precedence changed. |
2116 current precedence changed. |
2107 |
2117 |
2108 *} |
2118 *} |
2345 size. Moreover, our result is a good |
2355 size. Moreover, our result is a good |
2346 witness for one of the major reasons to be interested in machine checked |
2356 witness for one of the major reasons to be interested in machine checked |
2347 reasoning: gaining deeper understanding of the subject matter. |
2357 reasoning: gaining deeper understanding of the subject matter. |
2348 |
2358 |
2349 Our formalisation |
2359 Our formalisation |
2350 consists of around 210 lemmas and overall 6950 lines of readable Isabelle/Isar |
2360 consists of around 600 lemmas and overall 10800 lines |
|
2361 of readable and commented Isabelle/Isar |
2351 code with a few apply-scripts interspersed. The formal model of PIP |
2362 code with a few apply-scripts interspersed. The formal model of PIP |
2352 is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary |
2363 is 620 lines long; our graph theory implementation using relations is |
2353 definitions and proofs span over 770 lines of code. The properties relevant |
2364 1860 lines; the basic properties of PIP take around 5500 lines of code; |
2354 for an implementation require 2000 lines. |
2365 and the formal correctness proof 1700 lines. |
|
2366 %Some auxiliary |
|
2367 %definitions and proofs span over 770 lines of code. |
|
2368 The properties relevant |
|
2369 for an implementation require 1000 lines. |
2355 The code of our formalisation |
2370 The code of our formalisation |
2356 can be downloaded from the Mercurial repository at |
2371 can be downloaded from the Mercurial repository at |
2357 \url{http://www.dcs.kcl.ac.uk/staff/urbanc/cgi-bin/repos.cgi/pip}. |
2372 \url{http://www.dcs.kcl.ac.uk/staff/urbanc/cgi-bin/repos.cgi/pip}. |
2358 |
2373 |
2359 %\medskip |
2374 %\medskip |