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