⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fastinterlck_asm.s

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 S
📖 第 1 页 / 共 2 页
字号:
/*
 * COPYRIGHT:       See COPYING in the top level directory
 * PROJECT:         ReactOS kernel
 * FILE:            ntoskrnl/ex/i386/fastinterlck_asm.S
 * PURPOSE:         FASTCALL Interlocked Functions
 * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
 */
 
/* INCLUDES ******************************************************************/
#include <ndk/asm.h>
#include <internal/i386/asmmacro.S>
.intel_syntax noprefix

/* FUNCTIONS ****************************************************************/

/*
 * NOTE: These functions must obey the following rules:
 *  - Acquire locks only on MP systems.
 *  - Be safe at HIGH_LEVEL (no paged access).
 *  - Preserve flags.
 *  - Disable interrups.
 */

/*VOID
 *FASTCALL
 *ExInterlockedAddLargeStatistic(IN PLARGE_INTEGER Addend,
 *                               IN ULONG Increment)
 */
.global @ExInterlockedAddLargeStatistic@8
@ExInterlockedAddLargeStatistic@8:

#ifdef CONFIG_SMP
    /* Do the addition */
    lock add [ecx], edx

    /* Check for carry bit and return */
    jb 1f
    ret

1:
    /* Add carry */
    lock adc dword ptr [ecx+4], 0
#else
    /* Do the addition and add the carry */
    add dword ptr [ecx], edx
    adc dword ptr [ecx+4], 0
#endif
    /* Return */
    ret

/*ULONG
 *FASTCALL
 *ExfInterlockedAddUlong(IN PULONG Addend,
 *                       IN ULONG Increment,
 *                       IN PKSPIN_LOCK Lock)
 */
.global @ExfInterlockedAddUlong@12
@ExfInterlockedAddUlong@12:

    /* Save flags */
    pushfd

#ifdef CONFIG_SMP
    /* Get lock address */
    mov eax, [esp+8]
.start1:
#endif
    /* Disable interrupts */
    cli

    /* Acquire lock */
    ACQUIRE_SPINLOCK(eax, .spin1)

    /* Do the add */
    mov eax, [ecx]
    add [ecx], edx

#ifdef CONFIG_SMP
    /* Get spinlock address and release it */
    mov edx, [esp+8]
    RELEASE_SPINLOCK(edx)
#endif

    /* Restore flags and return */
    popfd
    ret 4

#ifdef CONFIG_SMP
.spin1:
    /* Restore flags and spin */
    popfd
    pushfd
    SPIN_ON_LOCK(eax, .start1)
#endif

/*PLIST_ENTRY
 *FASTCALL
 *ExfInterlockedInsertHeadList(IN PLIST_ENTRY ListHead,
 *                             IN PLIST_ENTRY ListEntry,
 *                             IN PKSPIN_LOCK Lock)
 */
.global @ExfInterlockedInsertHeadList@12
@ExfInterlockedInsertHeadList@12:

#ifdef CONFIG_SMP
    /* Save lock address */
    push esi
    mov esi, [esp+8]
#endif

    /* Save flags and disable interrupts */
    pushfd
.start2:
    cli

    /* Acquire lock */
    ACQUIRE_SPINLOCK(esi, .spin2)

    /* Get list pointer */
    mov eax, [ecx]

    /* Do the insert */
    mov [edx], eax
    mov [edx+4], ecx
    mov [ecx], edx
    mov [eax+4], edx

    /* Release lock and restore flags */
    RELEASE_SPINLOCK(esi)
    popfd

#ifdef CONFIG_SMP
    pop esi
#endif

    /* Check if list was empty */
    xor eax, ecx
    jz 2f

    /* Return list pointer */
    xor eax, ecx
2:
    ret 4

#ifdef CONFIG_SMP
.spin2:
    popfd
    pushfd
    SPIN_ON_LOCK(esi, .start2)
#endif

/*PLIST_ENTRY
 *FASTCALL
 *ExfInterlockedInsertTailList(IN PLIST_ENTRY ListHead,
 *                            IN PLIST_ENTRY ListEntry,
 *                            IN PKSPIN_LOCK Lock)
 */
.global @ExfInterlockedInsertTailList@12
@ExfInterlockedInsertTailList@12:

#ifdef CONFIG_SMP
    /* Save lock address */
    push esi
    mov esi, [esp+8]
#endif

    /* Save flags and disable interrupts */
    pushfd
.start3:
    cli

    /* Acquire lock */
    ACQUIRE_SPINLOCK(esi, .spin3)

    /* Get list pointer */
    mov eax, [ecx+4]

    /* Do the insert */
    mov [edx], ecx
    mov [edx+4], eax
    mov [ecx+4], edx
    mov [eax], edx

    /* Release lock and restore flags */
    RELEASE_SPINLOCK(esi)
    popfd

#ifdef CONFIG_SMP
    pop esi
#endif

    /* Check if list was empty */
    xor eax, ecx
    jz 2f

    /* Return list pointer */
    xor eax, ecx
2:
    ret 4

#ifdef CONFIG_SMP
.spin3:
    popfd
    pushfd
    SPIN_ON_LOCK(esi, .start3)
#endif

/*PLIST_ENTRY
 *FASTCALL
 *ExfInterlockedRemoveHeadList(IN PLIST_ENTRY ListHead,
 *                             IN PKSPIN_LOCK Lock)
 */
.global @ExfInterlockedRemoveHeadList@8
@ExfInterlockedRemoveHeadList@8:

    /* Save flags and disable interrupts */
.start4:
    pushfd
    cli
    ACQUIRE_SPINLOCK(edx, .spin4)

    /* Get list pointer */
    mov eax, [ecx]

    /* Check if it's empty */
    cmp eax, ecx
    je 2f

    /* Get the next entry and do the deletion*/
#ifdef CONFIG_SMP
    push ebx
    mov ebx, [eax]
    mov [ecx], ebx
    mov [ebx+4], ecx
#else
    mov edx, [eax]
    mov [ecx], edx
    mov [edx+4], ecx
#endif

    /* Release lock */
#ifdef CONFIG_SMP
    RELEASE_SPINLOCK(edx)
    pop ebx
#endif

    /* Restore flags */
    popfd

    /* Return */
    ret

2:
    /* Release lock */
    RELEASE_SPINLOCK(edx)

    /* Restore flags */
    popfd

    /* Return empty list */
    xor eax, eax
    ret

#ifdef CONFIG_SMP
.spin4:
    popfd
    SPIN_ON_LOCK(edx, .start4)
#endif

/*PSINGLE_LIST_ENTRY
 *FASTCALL
 *ExfInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead,
 *                           IN PKSPIN_LOCK Lock)
 */
.global @ExfInterlockedPopEntryList@8
@ExfInterlockedPopEntryList@8:

    /* Save flags and disable interrupts */
.start5:
    pushfd
    cli
    ACQUIRE_SPINLOCK(edx, .spin5)

    /* Get list pointer */
    mov eax, [ecx]

    /* Check if it's empty */
    or eax, eax
    je 3f

    /* Get next entry and do deletion */
#ifdef CONFIG_SMP
    push edx
#endif
    mov edx, [eax]
    mov [ecx], edx
#ifdef CONFIG_SMP
    pop edx
#endif

2:
    /* Release lock */
    RELEASE_SPINLOCK(edx)

    /* Restore flags */
    popfd

    /* Return */
    ret

3:
    /* Return empty list */
    xor eax, eax
    jmp 2b

#ifdef CONFIG_SMP
.spin5:
    popfd
    SPIN_ON_LOCK(edx, .start5)
#endif

/*PSINGLE_LIST_ENTRY
 *FASTCALL
 *ExfInterlockedPushEntryList(IN PSINGLE_LIST_ENTRY ListHead,
 *                            IN PSINGLE_LIST_ENTRY ListEntry,
 *                            IN PKSPIN_LOCK Lock)
 */
.global @ExfInterlockedPushEntryList@12
@ExfInterlockedPushEntryList@12:

    /* Save flags */
    pushfd

    /* Save lock pointer */
#ifdef CONFIG_SMP
    push edx
    mov edx, [esp+12]
#endif

    /* Disable interrupts */
.start6:
    cli
#ifdef CONFIG_SMP
    ACQUIRE_SPINLOCK(edx, .spin6)
    pop edx
#endif

    /* Get list pointer */
    mov eax, [ecx]

    /* Do push */
    mov [edx], eax
    mov [ecx], edx

    /* Release lock */
#ifdef CONFIG_SMP
    mov edx, [esp+8]
    RELEASE_SPINLOCK(edx)
#endif

    /* Restore flags */
    popfd

    /* Return */
    ret 4

#ifdef CONFIG_SMP
.spin6:
    pop edx
    popfd
    pushfd
    push edx
    mov edx, [esp+12]
    SPIN_ON_LOCK(edx, .start6)
#endif

/*PSINGLE_LIST_ENTRY
 *FASTCALL
 *ExInterlockedPopEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
 *                           IN PKSPIN_LOCK Lock)
 */
.global @ExInterlockedPopEntrySList@8
.global @InterlockedPopEntrySList@4
.global _ExpInterlockedPopEntrySListResume@0
.global _ExpInterlockedPopEntrySListFault@0
.global _ExpInterlockedPopEntrySListEnd@0
@ExInterlockedPopEntrySList@8:
@InterlockedPopEntrySList@4:

    /* Save registers */
    push ebx
    push ebp

    /* Pointer to list */
    mov ebp, ecx

    /* Get sequence number and link pointer */
_ExpInterlockedPopEntrySListResume@0:
    mov edx, [ebp+4]
    mov eax, [ebp]

    /* Check if the list is empty */
    or eax, eax
    jz 2f

    /* Copy sequence number and adjust it */
    lea ecx, [edx-1]

    /* Get next pointer and do the exchange */
_ExpInterlockedPopEntrySListFault@0:
    mov ebx, [eax]
_ExpInterlockedPopEntrySListEnd@0:
    LOCK cmpxchg8b [ebp]
    jnz _ExpInterlockedPopEntrySListResume@0

    /* Restore registers and return */
2:
    pop ebp
    pop ebx
    ret

/*PSINGLE_LIST_ENTRY
 *FASTCALL
 *ExInterlockedPushEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
 *                            IN PSINGLE_LIST_ENTRY ListEntry,
 *                            IN PKSPIN_LOCK Lock)
 */
.global @ExInterlockedPushEntrySList@12
@ExInterlockedPushEntrySList@12:

    /* So we can fall through below */
    pop [esp]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -