Subversion Repositories Kolibri OS

Rev

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