robin12
驱动牛犊
驱动牛犊
  • 注册日期2002-02-11
  • 最后登录2014-03-27
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望63点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1570回复:2

有谁知道KiSwapThread()函数在ntos的那个原文件中??

楼主#
更多 发布于:2004-02-22 13:51
如标题
thx !!!!!!
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2004-02-23 09:02
;++
;
; VOID
; KiSwapThread (
;    VOID
;    )
;
; Routine Description:
;
;    This routine is called to select the next thread to run on the
;    current processor and to perform a context switch to the thread.
;
; Arguments:
;
;    None.
;
; Return Value:
;
;    Wait completion status (eax).
;
;--

cPublicFastCall KiSwapThread, 0
.fpo (0, 0, 0, 4, 1, 0)

;
; N.B. The following registers MUST be saved such that ebp is saved last.
;      This is done so the debugger can find the saved ebp for a thread
;      that is not currently in the running state.
;

        sub     esp, 4*4
        mov     [esp+12], ebx           ; save registers
        mov     [esp+8], esi            ;
        mov     [esp+4], edi            ;
        mov     [esp+0], ebp            ;

        mov     ebx, PCR[PcSelfPcr]     ; get address of PCR
        mov     edx, [ebx].PcPrcbData.PbNextThread ; get next thread address
        or      edx, edx                ; check if next thread selected
        jnz     Swt140                  ; if nz, next thread selected

;
; Find the highest nibble in the ready summary that contains a set bit
; and left justify so the nibble is in bits <31:28>
;

        mov     ecx, 16                 ; set base bit number
        mov     edi, _KiReadySummary    ; get ready summary
        mov     esi, edi                ; copy ready summary
        shr     esi, 16                 ; isolate bits <31:16> of summary
        jnz     short Swt10             ; if nz, bits <31:16> are nonzero
        xor     ecx, ecx                ; set base bit number
        mov     esi, edi                ; set bits <15:0> of summary
Swt10:  shr     esi, 8                  ; isolate bits <15:8> of low bits
        jz      short Swt20             ; if z, bits <15:8> are zero
        add     ecx, 8                  ; add offset to nonzero byte
Swt20:  mov     esi, edi                ; isolate highest nonzero byte
        shr     esi, cl                 ;
        add     ecx, 3                  ; adjust to high bit of nibble
        cmp     esi, 10h                ; check if high nibble nonzero
        jb      short Swt30             ; if b, then high nibble is zero
        add     ecx, 4                  ; compute ready queue priority
Swt30:  mov     esi, ecx                ; left justify ready summary nibble
        not     ecx                     ;
        shl     edi, cl                 ;
        or      edi, edi                ;

;
; If the next bit is set in the ready summary, then scan the corresponding
; dispatcher ready queue.
;

Swt40:  js      short Swt60             ; if s, queue contains an entry
Swt50:  sub     esi, 1                  ; decrement ready queue priority
        shl     edi, 1                  ; position next ready summary bit
        jnz     short Swt40             ; if nz, more queues to scan

;
; All ready queues were scanned without finding a runnable thread so
; default to the idle thread and set the appropriate bit in idle summary.
;

ifdef _COLLECT_SWITCH_DATA_

        inc     _KeThreadSwitchCounters + TwSwitchToIdle ; increment counter

endif

ifdef NT_UP

        mov     _KiIdleSummary, 1       ; set idle summary bit

else

        mov     eax, [ebx].PcPrcbData.PbSetMember ; get processor set member
        or      _KiIdleSummary, eax     ; set idle summary bit

endif

        mov     edx, [ebx].PcPrcbData.PbIdleThread ; set idle thread address
        jmp     Swt140                  ;

;
; If the thread can execute on the current processor, then remove it from
; the dispatcher ready queue.
;

        align   4
swt60:  lea     ebp, [esi*8] + _KiDispatcherReadyListHead ; get ready queue address
        mov     ecx, [ebp].LsFlink      ; get address of first queue entry
Swt70:  mov     edx, ecx                ; compute address of thread object
        sub     edx, ThWaitListEntry    ;

ifndef NT_UP

        mov     eax, [edx].ThAffinity   ; get thread affinity
        test    eax, [ebx].PcPrcbData.PbSetMember ; test if compatible affinity
        jnz     short Swt80             ; if nz, thread affinity compatible
        mov     ecx, [ecx].LsFlink      ; get address of next entry
        cmp     ebp, ecx                ; check if end of list
        jnz     short Swt70             ; if nz, not end of list
        jmp     short Swt50             ;

;
; If the thread last ran on the current processor, has been waiting for
; longer than a quantum, or its priority is greater than low realtime
; plus 9, then select the thread. Otherwise, an attempt is made to find
; a more appropriate candidate.
;

        align   4
Swt80:  cmp     _KiThreadSelectNotifyRoutine, 0 ; check for callout routine
        je      short Swt85             ; if eq, no callout routine registered
        push    edx                     ; save volatile registers
        push    ecx                     ;
        mov     ecx, [edx].EtCid.CidUniqueThread ; set trial thread unique id
        call    [_KiThreadSelectNotifyRoutine] ; notify callout routine
        pop     ecx                     ; restore volatile registers
        pop     edx                     ;
        or      eax, eax                ; check if trial thread selectable
        jnz     Swt120                  ; if nz, trial thread selectable
        jmp     Swt87                   ;

        align   4
Swt85:  mov     al, [edx].ThNextProcessor ; get last processor number
        cmp     al, [ebx].PcPrcbData.PbNumber ; check if current processor
        jz      Swt120                  ; if z, same as current processor
        mov     al, [edx].ThIdealProcessor ; get ideal processor number
        cmp     al, [ebx].PcPrcbData.PbNumber ; check if current processor
        jz      short Swt120            ; if z, same as current processor
Swt87:  cmp     esi, LOW_REALTIME_PRIORITY + 9 ; check if priority in range
        jae     short Swt120            ; if ae, priority not in range
        mov     edi, _KeTickCount + 0   ; get low part of tick count
        sub     edi, [edx].ThWaitTime   ; compute length of wait
        cmp     edi, READY_SKIP_QUANTUM + 1 ; check if wait time exceeded
        jae     short Swt120            ; if ae, wait time exceeded
        mov     edi, edx                ; set address of thread

;
; Search forward in the ready queue until the end of the list is reached
; or a more appropriate thread is found.
;

Swt90:  mov     edi, [edi].ThWaitListEntry ; get address of next entry
        cmp     ebp, edi                ; check if end of list
        jz      short Swt120            ; if z, end of list
        sub     edi, ThWaitListEntry    ; compute address of thread
        mov     eax, [edi].ThAffinity   ; get thread affinity
        test    eax, [ebx].PcPrcbData.PbSetMember ; test if compatible infinity
        jz      short Swt100            ; if z, thread affinity not compatible
        cmp     _KiThreadSelectNotifyRoutine, 0 ; check for callout routine
        je      short Swt95             ; if eq, no callout routine registered
        push    edx                     ; save volatile registers
        push    ecx                     ;
        mov     ecx, [edi].EtCid.CidUniqueThread ; set trial thread unique id
        call    [_KiThreadSelectNotifyRoutine] ; notify callout routine
        pop     ecx                     ; restore volatile registers
        pop     edx                     ;
        or      eax, eax                ; check if trial thread selectable
        jnz     short Swt110            ; if nz, trial thread selectable
        jmp     short Swt100            ;

        align   4
Swt95:  mov     al, [edi].ThNextProcessor ; get last processor number
        cmp     al, [ebx].PcPrcbData.PbNumber ; check if current processor
        jz      short Swt110            ; if z, same as current processor
        mov     al, [edi].ThIdealProcessor ; get ideal processor number
        cmp     al, [ebx].PcPrcbData.PbNumber ; check if current processor
        jz      short Swt110            ; if z, same as current processor
Swt100: mov     eax, _KeTickCount + 0   ; get low part of tick count
        sub     eax, [edi].ThWaitTime   ; compute length of wait
        cmp     eax, READY_SKIP_QUANTUM + 1 ; check if wait time exceeded
        jb      short Swt90             ; if b, wait time not exceeded
        jmp     short Swt120            ;

        align   4
Swt110: mov     edx, edi                ; set address of thread
        mov     ecx, edi                ; compute address of list entry
        add     ecx, ThWaitListEntry    ;
Swt120: mov     al, [ebx].PcPrcbData.PbNumber ; get current processor number

ifdef _COLLECT_SWITCH_DATA_

        lea     ebp, _KeThreadSwitchCounters + TwFindIdeal ; get counter address
        cmp     al, [edx].ThIdealProcessor ; check if same as ideal processor
        jz      short Swt130            ; if z, same as ideal processor
        add     ebp, TwFindLast - TwFindIdeal ; compute address of last counter
        cmp     al, [edx].ThNextProcessor ; check if same as last processor
        jz      short Swt130            ; if z, same as last processor
        add     ebp,TwFindAny - TwFindLast ; compute address of correct counter
Swt130: inc     dword ptr [ebp]         ; increment appropriate switch counter

endif

        mov     [edx].ThNextProcessor, al ; set next processor number

endif

;
; Remove the selected thread from the ready queue.
;

        mov     eax, [ecx].LsFlink      ; get list entry forward link
        mov     ebp, [ecx].LsBlink      ; get list entry backward link
        mov     [ebp].LsFlink, eax      ; set forward link in previous entry
        mov     [eax].LsBlink, ebp      ; set backward link in next entry
        cmp     eax, ebp                ; check if list is empty
        jnz     short Swt140            ; if nz, list is not empty
        mov     ebp, 1                  ; clear ready summary bit
        mov     ecx, esi                ;
        shl     ebp, cl                 ;
        xor     _KiReadySummary, ebp    ;

;
; Swap context to the next thread.
;

Swt140: mov     esi, edx                ; set address of next thread
        mov     edi, [ebx].PcPrcbData.PbCurrentThread ; set current thread address
        mov     dword ptr [ebx].PcPrcbData.PbNextThread, 0 ; clear next thread address
        mov     [ebx].PcPrcbData.PbCurrentThread, esi ; set current thread address
        mov     cl, [edi].ThWaitIrql    ; set APC interrupt bypass disable
        call    SwapContext             ; swap context
        or      al, al                  ; check if kernel APC pending
        mov     edi, [esi].ThWaitStatus ; save wait completion status
        mov     cl, [esi].ThWaitIrql    ; get wait IRQL
        jnz     short Swt160            ; if nz, kernel APC pending

Swt150: fstCall KfLowerIrql             ; lower IRQL to previous value

        mov     eax, edi                ; set wait completion status
        mov     ebp, [esp+0]            ; restore registers
        mov     edi, [esp+4]            ;
        mov     esi, [esp+8]            ;
        mov     ebx, [esp+12]           ;
        add     esp, 4*4                ;
        fstRET  KiSwapThread            ;

Swt160: mov     cl, APC_LEVEL           ; lower IRQL to APC level
        fstCall KfLowerIrql             ;
        xor     eax, eax                ; set previous mode to kernel
        stdCall _KiDeliverApc, <eax, eax, eax> ; deliver kernel mode APC
        inc     dword ptr [ebx].PcPrcbData.PbApcBypassCount ; increment count
        xor     ecx, ecx                ; set original wait IRQL
        jmp     short Swt150

fstENDP KiSwapThread
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
robin12
驱动牛犊
驱动牛犊
  • 注册日期2002-02-11
  • 最后登录2014-03-27
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望63点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-02-28 17:01
非常感谢!!!,其实用source insight 收一下就可以了
该函数在windows_2000_source_code\\win2k\\private\\ntos\\ke\\i386\\ctxswap.asm文件中。

[编辑 -  2/28/04 by  robin12]
游客

返回顶部