Rev 3294 | Rev 3309 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3294 | Rev 3296 | ||
---|---|---|---|
Line 9... | Line 9... | ||
9 | ;; Distributed under GPL. See file COPYING for details. ;; |
9 | ;; Distributed under GPL. See file COPYING for details. ;; |
10 | ;; Copyright 2003 Ville Turjanmaa ;; |
10 | ;; Copyright 2003 Ville Turjanmaa ;; |
11 | ;; ;; |
11 | ;; ;; |
12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 13... | Line 13... | ||
13 | 13 | ||
Line 14... | Line 14... | ||
14 | $Revision: 3294 $ |
14 | $Revision: 3296 $ |
15 | 15 | ||
16 | 16 | ||
Line 705... | Line 705... | ||
705 | ; call build_process_gdt_tss_pointer |
705 | ; call build_process_gdt_tss_pointer |
Line 706... | Line 706... | ||
706 | 706 | ||
707 | ; mov esi,boot_sched_2 |
707 | ; mov esi,boot_sched_2 |
708 | ; call boot_log |
708 | ; call boot_log |
- | 709 | ; ret |
|
- | 710 | ||
- | 711 | ; Three following procedures are used to guarantee that |
|
- | 712 | ; some part of kernel code will not be terminated from outside |
|
- | 713 | ; while it is running. |
|
- | 714 | ; Note: they do not protect a thread from terminating due to errors inside |
|
- | 715 | ; the thread; accessing a nonexisting memory would still terminate it. |
|
- | 716 | ||
- | 717 | ; First two procedures must be used in pair by thread-to-be-protected |
|
- | 718 | ; to signal the beginning and the end of an important part. |
|
- | 719 | ; It is OK to have nested areas. |
|
- | 720 | ||
- | 721 | ; The last procedure must be used by outside wanna-be-terminators; |
|
- | 722 | ; if it is safe to terminate the given thread immediately, it returns eax=1; |
|
- | 723 | ; otherwise, it returns eax=0 and notifies the target thread that it should |
|
- | 724 | ; terminate itself when leaving a critical area (the last critical area if |
|
- | 725 | ; they are nested). |
|
- | 726 | ||
- | 727 | ; Implementation. Those procedures use one dword in APPDATA for the thread, |
|
- | 728 | ; APPDATA.terminate_protection. |
|
- | 729 | ; * The upper bit is 1 during normal operations and 0 when terminate is requested. |
|
- | 730 | ; * Other bits form a number = depth of critical regions, |
|
- | 731 | ; plus 1 if the upper bit is 1. |
|
- | 732 | ; * When this dword goes to zero, the thread should be destructed, |
|
- | 733 | ; and the procedure in which it happened becomes responsible for destruction. |
|
- | 734 | ||
- | 735 | ; Enter critical area. Called by thread which wants to be protected. |
|
- | 736 | proc protect_from_terminate |
|
- | 737 | mov edx, [current_slot] |
|
- | 738 | ; Atomically increment depth of critical areas and get the old value. |
|
- | 739 | mov eax, 1 |
|
- | 740 | lock xadd [edx+APPDATA.terminate_protection], eax |
|
- | 741 | ; If the old value was zero, somebody has started to terminate us, |
|
- | 742 | ; so we are destructing and cannot do anything protected. |
|
- | 743 | ; Otherwise, return to the caller. |
|
- | 744 | test eax, eax |
|
- | 745 | jz @f |
|
- | 746 | ret |
|
- | 747 | @@: |
|
- | 748 | ; Wait for somebody to finish us. |
|
- | 749 | call change_task |
|
- | 750 | jmp @b |
|
- | 751 | endp |
|
- | 752 | ||
- | 753 | ; Leave critical area. Called by thread which wants to be protected. |
|
- | 754 | proc unprotect_from_terminate |
|
- | 755 | mov edx, [current_slot] |
|
- | 756 | ; Atomically decrement depth of critical areas. |
|
- | 757 | lock dec [edx+APPDATA.terminate_protection] |
|
- | 758 | ; If the result of decrement is zero, somebody has requested termination, |
|
- | 759 | ; but at that moment we were inside a critical area; terminate now. |
|
- | 760 | jz sys_end |
|
- | 761 | ; Otherwise, return to the caller. |
|
- | 762 | ret |
|
- | 763 | endp |
|
- | 764 | ||
- | 765 | ; Request termination of thread identified by edx = SLOT_BASE + slot*256. |
|
- | 766 | ; Called by anyone. |
|
- | 767 | proc request_terminate |
|
- | 768 | xor eax, eax ; set return value |
|
- | 769 | ; Atomically clear the upper bit. If it was already zero, then |
|
- | 770 | ; somebody has requested termination before us, so just exit. |
|
- | 771 | lock btr [edx+APPDATA.terminate_protection], 31 |
|
- | 772 | jnc .unsafe |
|
- | 773 | ; Atomically decrement depth of critical areas. |
|
- | 774 | lock dec [edx+APPDATA.terminate_protection] |
|
- | 775 | ; If the result of decrement is nonzero, the target thread is inside a |
|
- | 776 | ; critical area; leave termination to leaving that area. |
|
- | 777 | jnz .unsafe |
|
- | 778 | ; Otherwise, it is safe to kill the target now and the caller is responsible |
|
- | 779 | ; for this. Return eax=1. |
|
- | 780 | inc eax |
|
- | 781 | .unsafe: |
|
- | 782 | ret |
|
- | 783 | endp |