472 vat_s.le_cp) |
471 vat_s.le_cp) |
473 |
472 |
474 section {* The `blocking thread` *} |
473 section {* The `blocking thread` *} |
475 |
474 |
476 text {* |
475 text {* |
477 |
476 The purpose of PIP is to ensure that the most |
478 The purpose of PIP is to ensure that the most urgent thread @{term |
477 urgent thread @{term th} is not blocked unreasonably. |
479 th} is not blocked unreasonably. Therefore, below, we will derive |
478 Therefore, a clear picture of the blocking thread is essential |
480 properties of the blocking thread. By blocking thread, we mean a |
479 to assure people that the purpose is fulfilled. |
481 thread in running state t @ s, but is different from thread @{term |
480 |
482 th}. |
481 In this section, we are going to derive a series of lemmas |
483 |
482 with finally give rise to a picture of the blocking thread. |
484 The first lemmas shows that the @{term cp}-value of the blocking |
483 |
485 thread @{text th'} equals to the highest precedence in the whole |
484 By `blocking thread`, we mean a thread in running state but |
486 system. |
485 different from thread @{term th}. |
487 |
486 *} |
488 *} |
487 |
489 |
488 text {* |
|
489 The following lemmas shows that the @{term cp}-value |
|
490 of the blocking thread @{text th'} equals to the highest |
|
491 precedence in the whole system. |
|
492 *} |
490 lemma runing_preced_inversion: |
493 lemma runing_preced_inversion: |
491 assumes runing': "th' \<in> runing (t @ s)" |
494 assumes runing': "th' \<in> runing (t@s)" |
492 shows "cp (t @ s) th' = preced th s" |
495 shows "cp (t@s) th' = preced th s" (is "?L = ?R") |
493 proof - |
496 proof - |
494 have "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" |
497 have "?L = Max (cp (t @ s) ` readys (t @ s))" using assms |
495 using assms by (unfold runing_def, auto) |
498 by (unfold runing_def, auto) |
496 also have "\<dots> = preced th s" |
499 also have "\<dots> = ?R" |
497 by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) |
500 by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) |
498 finally show ?thesis . |
501 finally show ?thesis . |
499 qed |
502 qed |
500 |
503 |
501 text {* |
504 text {* |
502 |
505 |
503 The next lemma shows how the counters for @{term "P"} and @{term |
506 The following lemma shows how the counters for @{term "P"} and |
504 "V"} operations relate to the running threads in the states @{term |
507 @{term "V"} operations relate to the running threads in the states |
505 s} and @{term "t @ s"}: if a thread's @{term "P"}-count equals its |
508 @{term s} and @{term "t @ s"}. The lemma shows that if a thread's |
506 @{term "V"}-count (which means it no longer has any resource in its |
509 @{term "P"}-count equals its @{term "V"}-count (which means it no |
507 possession), it cannot be a running thread. |
510 longer has any resource in its possession), it cannot be a running |
|
511 thread. |
508 |
512 |
509 The proof is by contraction with the assumption @{text "th' \<noteq> th"}. |
513 The proof is by contraction with the assumption @{text "th' \<noteq> th"}. |
510 The key is the use of @{thm count_eq_dependants} to derive the |
514 The key is the use of @{thm eq_pv_dependants} to derive the |
511 emptiness of @{text th'}s @{term dependants}-set from the balance of |
515 emptiness of @{text th'}s @{term dependants}-set from the balance of |
512 its @{term P} and @{term V} counts. From this, it can be shown |
516 its @{term P} and @{term V} counts. From this, it can be shown |
513 @{text th'}s @{term cp}-value equals to its own precedence. |
517 @{text th'}s @{term cp}-value equals to its own precedence. |
514 |
518 |
515 On the other hand, since @{text th'} is running, by @{thm |
519 On the other hand, since @{text th'} is running, by @{thm |
516 runing_preced_inversion}, its @{term cp}-value equals to the |
520 runing_preced_inversion}, its @{term cp}-value equals to the |
517 precedence of @{term th}. |
521 precedence of @{term th}. |
518 |
522 |
519 Combining the above two results we have that @{text th'} and @{term |
523 Combining the above two resukts we have that @{text th'} and @{term |
520 th} have the same precedence. By uniqueness of precedences, we have |
524 th} have the same precedence. By uniqueness of precedences, we have |
521 @{text "th' = th"}, which is in contradiction with the assumption |
525 @{text "th' = th"}, which is in contradiction with the assumption |
522 @{text "th' \<noteq> th"}. |
526 @{text "th' \<noteq> th"}. |
523 |
527 |
524 *} |
528 *} |
525 |
529 |
526 lemma eq_pv_blocked: (* ddd *) |
530 lemma eq_pv_blocked: (* ddd *) |
527 assumes neq_th': "th' \<noteq> th" |
531 assumes neq_th': "th' \<noteq> th" |
528 and eq_pv: "cntP (t @ s) th' = cntV (t @ s) th'" |
532 and eq_pv: "cntP (t@s) th' = cntV (t@s) th'" |
529 shows "th' \<notin> runing (t @ s)" |
533 shows "th' \<notin> runing (t@s)" |
530 proof |
534 proof |
531 assume otherwise: "th' \<in> runing (t @ s)" |
535 assume otherwise: "th' \<in> runing (t@s)" |
532 show False |
536 show False |
533 proof - |
537 proof - |
534 have th'_in: "th' \<in> threads (t @ s)" |
538 have th'_in: "th' \<in> threads (t@s)" |
535 using otherwise readys_threads runing_def by auto |
539 using otherwise readys_threads runing_def by auto |
536 have "th' = th" |
540 have "th' = th" |
537 proof(rule preced_unique) |
541 proof(rule preced_unique) |
538 -- {* The proof goes like this: |
542 -- {* The proof goes like this: |
539 it is first shown that the @{term preced}-value of @{term th'} |
543 it is first shown that the @{term preced}-value of @{term th'} |
543 show "preced th' (t @ s) = preced th (t @ s)" (is "?L = ?R") |
547 show "preced th' (t @ s) = preced th (t @ s)" (is "?L = ?R") |
544 proof - |
548 proof - |
545 -- {* Since the counts of @{term th'} are balanced, the subtree |
549 -- {* Since the counts of @{term th'} are balanced, the subtree |
546 of it contains only itself, so, its @{term cp}-value |
550 of it contains only itself, so, its @{term cp}-value |
547 equals its @{term preced}-value: *} |
551 equals its @{term preced}-value: *} |
548 have "?L = cp (t @ s) th'" |
552 have "?L = cp (t@s) th'" |
549 by (unfold cp_eq_cpreced cpreced_def count_eq_dependants[OF eq_pv], simp) |
553 by (unfold cp_eq_cpreced cpreced_def eq_dependants vat_t.eq_pv_dependants[OF eq_pv], simp) |
550 -- {* Since @{term "th'"} is running, by @{thm runing_preced_inversion}, |
554 -- {* Since @{term "th'"} is running, by @{thm runing_preced_inversion}, |
551 its @{term cp}-value equals @{term "preced th s"}, |
555 its @{term cp}-value equals @{term "preced th s"}, |
552 which equals to @{term "?R"} by simplification: *} |
556 which equals to @{term "?R"} by simplification: *} |
553 also have "... = ?R" |
557 also have "... = ?R" |
|
558 thm runing_preced_inversion |
554 using runing_preced_inversion[OF otherwise] by simp |
559 using runing_preced_inversion[OF otherwise] by simp |
555 finally show ?thesis . |
560 finally show ?thesis . |
556 qed |
561 qed |
557 qed (auto simp: th'_in th_kept) |
562 qed (auto simp: th'_in th_kept) |
558 with `th' \<noteq> th` show ?thesis by simp |
563 with `th' \<noteq> th` show ?thesis by simp |
566 it will keep hand-emptied in the future @{term "t@s"}. |
571 it will keep hand-emptied in the future @{term "t@s"}. |
567 *} |
572 *} |
568 lemma eq_pv_persist: (* ddd *) |
573 lemma eq_pv_persist: (* ddd *) |
569 assumes neq_th': "th' \<noteq> th" |
574 assumes neq_th': "th' \<noteq> th" |
570 and eq_pv: "cntP s th' = cntV s th'" |
575 and eq_pv: "cntP s th' = cntV s th'" |
571 shows "cntP (t @ s) th' = cntV (t @ s) th'" |
576 shows "cntP (t@s) th' = cntV (t@s) th'" |
572 proof(induction rule: ind) |
577 proof(induction rule:ind) -- {* The proof goes by induction. *} |
573 -- {* The nontrivial case is for the @{term Cons}: *} |
578 -- {* The nontrivial case is for the @{term Cons}: *} |
574 case (Cons e t) |
579 case (Cons e t) |
575 -- {* All results derived so far hold for both @{term s} and @{term "t@s"}: *} |
580 -- {* All results derived so far hold for both @{term s} and @{term "t@s"}: *} |
576 interpret vat_t: extend_highest_gen s th prio tm t using Cons by simp |
581 interpret vat_t: extend_highest_gen s th prio tm t using Cons by simp |
577 interpret vat_e: extend_highest_gen s th prio tm "(e # t)" using Cons by simp |
582 interpret vat_e: extend_highest_gen s th prio tm "(e # t)" using Cons by simp |
616 ultimately show ?thesis using Cons(5) by metis |
621 ultimately show ?thesis using Cons(5) by metis |
617 qed |
622 qed |
618 qed (auto simp:eq_pv) |
623 qed (auto simp:eq_pv) |
619 |
624 |
620 text {* |
625 text {* |
621 |
626 By combining @{thm eq_pv_blocked} and @{thm eq_pv_persist}, |
622 By combining @{thm eq_pv_blocked} and @{thm eq_pv_persist}, it can |
627 it can be derived easily that @{term th'} can not be running in the future: |
623 be derived easily that @{term th'} can not be running in the future: |
628 *} |
624 |
|
625 *} |
|
626 |
|
627 lemma eq_pv_blocked_persist: |
629 lemma eq_pv_blocked_persist: |
628 assumes neq_th': "th' \<noteq> th" |
630 assumes neq_th': "th' \<noteq> th" |
629 and eq_pv: "cntP s th' = cntV s th'" |
631 and eq_pv: "cntP s th' = cntV s th'" |
630 shows "th' \<notin> runing (t @ s)" |
632 shows "th' \<notin> runing (t@s)" |
631 using assms |
633 using assms |
632 by (simp add: eq_pv_blocked eq_pv_persist) |
634 by (simp add: eq_pv_blocked eq_pv_persist) |
633 |
635 |
634 text {* |
636 text {* |
635 |
637 The following lemma shows the blocking thread @{term th'} |
636 The following lemma shows the blocking thread @{term th'} must hold |
638 must hold some resource in the very beginning. |
637 some resource in the very beginning. |
639 *} |
638 |
|
639 *} |
|
640 |
|
641 lemma runing_cntP_cntV_inv: (* ddd *) |
640 lemma runing_cntP_cntV_inv: (* ddd *) |
642 assumes is_runing: "th' \<in> runing (t @ s)" |
641 assumes is_runing: "th' \<in> runing (t@s)" |
643 and neq_th': "th' \<noteq> th" |
642 and neq_th': "th' \<noteq> th" |
644 shows "cntP s th' > cntV s th'" |
643 shows "cntP s th' > cntV s th'" |
645 using assms |
644 using assms |
646 proof - |
645 proof - |
647 -- {* First, it can be shown that the number of @{term P} and |
646 -- {* First, it can be shown that the number of @{term P} and |
710 next |
704 next |
711 from runing_preced_inversion[OF runing'] |
705 from runing_preced_inversion[OF runing'] |
712 show "cp (t@s) th' = preced th s" . |
706 show "cp (t@s) th' = preced th s" . |
713 qed |
707 qed |
714 |
708 |
715 |
|
716 section {* The existence of `blocking thread` *} |
709 section {* The existence of `blocking thread` *} |
717 |
710 |
718 text {* |
711 text {* |
719 |
712 Suppose @{term th} is not running, it is first shown that |
720 Suppose @{term th} is not running, it is first shown that there is a |
713 there is a path in RAG leading from node @{term th} to another thread @{text "th'"} |
721 path in RAG leading from node @{term th} to another thread @{text |
714 in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}). |
722 "th'"} in the @{term readys}-set (So @{text "th'"} is an ancestor of |
715 |
723 @{term th}}). |
716 Now, since @{term readys}-set is non-empty, there must be |
724 |
717 one in it which holds the highest @{term cp}-value, which, by definition, |
725 Now, since @{term readys}-set is non-empty, there must be one in it |
718 is the @{term runing}-thread. However, we are going to show more: this running thread |
726 which holds the highest @{term cp}-value, which, by definition, is |
719 is exactly @{term "th'"}. |
727 the @{term runing}-thread. However, we are going to show more: this |
720 *} |
728 running thread is exactly @{term "th'"}. |
|
729 |
|
730 *} |
|
731 |
|
732 lemma th_blockedE: (* ddd, the other main lemma to be presented: *) |
721 lemma th_blockedE: (* ddd, the other main lemma to be presented: *) |
733 assumes "th \<notin> runing (t@s)" |
722 assumes "th \<notin> runing (t@s)" |
734 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
723 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
735 "th' \<in> runing (t@s)" |
724 "th' \<in> runing (t@s)" |
736 proof - |
725 proof - |
788 using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def) |
777 using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def) |
789 ultimately show ?thesis using that by metis |
778 ultimately show ?thesis using that by metis |
790 qed |
779 qed |
791 |
780 |
792 text {* |
781 text {* |
793 |
782 Now it is easy to see there is always a thread to run by case analysis |
794 Now it is easy to see there is always a thread to run by case |
783 on whether thread @{term th} is running: if the answer is Yes, the |
795 analysis on whether thread @{term th} is running: if the answer is |
784 the running thread is obviously @{term th} itself; otherwise, the running |
796 yes, the the running thread is obviously @{term th} itself; |
785 thread is the @{text th'} given by lemma @{thm th_blockedE}. |
797 otherwise, the running thread is the @{text th'} given by lemma |
786 *} |
798 @{thm th_blockedE}. |
|
799 |
|
800 *} |
|
801 |
|
802 lemma live: "runing (t@s) \<noteq> {}" |
787 lemma live: "runing (t@s) \<noteq> {}" |
803 proof(cases "th \<in> runing (t@s)") |
788 proof(cases "th \<in> runing (t@s)") |
804 case True thus ?thesis by auto |
789 case True thus ?thesis by auto |
805 next |
790 next |
806 case False |
791 case False |
807 thus ?thesis using th_blockedE by auto |
792 thus ?thesis using th_blockedE by auto |
808 qed |
793 qed |
809 |
794 |
810 |
|
811 end |
795 end |
812 end |
796 end |