1c2c66affSColin Finck/* 2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory 3c2c66affSColin Finck * PROJECT: ReactOS kernel 4c2c66affSColin Finck * FILE: ntoskrnl/ex/i386/fastinterlck_asm.S 5c2c66affSColin Finck * PURPOSE: FASTCALL Interlocked Functions 6c2c66affSColin Finck * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) 7c2c66affSColin Finck */ 8c2c66affSColin Finck 9c2c66affSColin Finck/* INCLUDES ******************************************************************/ 10c2c66affSColin Finck 11c2c66affSColin Finck#include <asm.inc> 12c2c66affSColin Finck#include <ks386.inc> 13c2c66affSColin Finck#include <internal/i386/asmmacro.S> 14c2c66affSColin Finck 15c2c66affSColin Finck/* FUNCTIONS ****************************************************************/ 16c2c66affSColin Finck 17c2c66affSColin Finck.code32 18c2c66affSColin Finck 19c2c66affSColin Finck/* 20c2c66affSColin Finck * NOTE: These functions must obey the following rules: 21c2c66affSColin Finck * - Acquire locks only on MP systems. 22c2c66affSColin Finck * - Be safe at HIGH_LEVEL (no paged access). 23c2c66affSColin Finck * - Preserve flags. 24*0f3da974SHermès Bélusca-Maïto * - Disable interrupts. 25c2c66affSColin Finck */ 26c2c66affSColin Finck 27c2c66affSColin Finck/*VOID 28c2c66affSColin Finck *FASTCALL 29c2c66affSColin Finck *ExInterlockedAddLargeStatistic(IN PLARGE_INTEGER Addend, 30c2c66affSColin Finck * IN ULONG Increment) 31c2c66affSColin Finck */ 32c2c66affSColin FinckPUBLIC @ExInterlockedAddLargeStatistic@8 33c2c66affSColin Finck@ExInterlockedAddLargeStatistic@8: 34c2c66affSColin Finck 35c2c66affSColin Finck#ifdef CONFIG_SMP 36c2c66affSColin Finck /* Do the addition */ 37c2c66affSColin Finck lock add [ecx], edx 38c2c66affSColin Finck 39c2c66affSColin Finck /* Check for carry bit and return */ 40c2c66affSColin Finck jc .l1 41c2c66affSColin Finck ret 42c2c66affSColin Finck 43c2c66affSColin Finck.l1: 44c2c66affSColin Finck /* Add carry */ 45c2c66affSColin Finck lock adc dword ptr [ecx+4], 0 46c2c66affSColin Finck#else 47c2c66affSColin Finck /* Do the addition and add the carry */ 48c2c66affSColin Finck add dword ptr [ecx], edx 49c2c66affSColin Finck adc dword ptr [ecx+4], 0 50c2c66affSColin Finck#endif 51c2c66affSColin Finck /* Return */ 52c2c66affSColin Finck ret 53c2c66affSColin Finck 54c2c66affSColin Finck 55c2c66affSColin Finck 56c2c66affSColin Finck/*PSINGLE_LIST_ENTRY 57c2c66affSColin Finck *FASTCALL 58c2c66affSColin Finck *ExInterlockedPopEntrySList(IN PSINGLE_LIST_ENTRY ListHead, 59c2c66affSColin Finck * IN PKSPIN_LOCK Lock) 60c2c66affSColin Finck */ 61c2c66affSColin FinckPUBLIC @ExInterlockedPopEntrySList@8 62c2c66affSColin FinckPUBLIC @InterlockedPopEntrySList@4 63c2c66affSColin FinckPUBLIC _ExpInterlockedPopEntrySListResume@0 64c2c66affSColin FinckPUBLIC _ExpInterlockedPopEntrySListFault@0 65c2c66affSColin FinckPUBLIC _ExpInterlockedPopEntrySListEnd@0 66c2c66affSColin Finck@ExInterlockedPopEntrySList@8: 67c2c66affSColin Finck@InterlockedPopEntrySList@4: 68c2c66affSColin Finck 69c2c66affSColin Finck /* Save registers */ 70c2c66affSColin Finck push ebx 71c2c66affSColin Finck push ebp 72c2c66affSColin Finck 73c2c66affSColin Finck /* Pointer to list */ 74c2c66affSColin Finck mov ebp, ecx 75c2c66affSColin Finck 76c2c66affSColin Finck /* Get sequence number and link pointer */ 77c2c66affSColin Finck_ExpInterlockedPopEntrySListResume@0: 78c2c66affSColin Finck mov edx, [ebp+4] 79c2c66affSColin Finck mov eax, [ebp] 80c2c66affSColin Finck 81c2c66affSColin Finck /* Check if the list is empty */ 82c2c66affSColin Finck or eax, eax 83c2c66affSColin Finck jz .l7 84c2c66affSColin Finck 85c2c66affSColin Finck /* Copy depth and adjust it */ 86c2c66affSColin Finck lea ecx, [edx-1] 87c2c66affSColin Finck 88c2c66affSColin Finck /* Get next pointer and do the exchange */ 89c2c66affSColin Finck_ExpInterlockedPopEntrySListFault@0: 90c2c66affSColin Finck mov ebx, [eax] 91c2c66affSColin Finck_ExpInterlockedPopEntrySListEnd@0: 92c2c66affSColin Finck LOCK cmpxchg8b qword ptr [ebp] 93c2c66affSColin Finck jnz _ExpInterlockedPopEntrySListResume@0 94c2c66affSColin Finck 95c2c66affSColin Finck /* Restore registers and return */ 96c2c66affSColin Finck.l7: 97c2c66affSColin Finck pop ebp 98c2c66affSColin Finck pop ebx 99c2c66affSColin Finck ret 100c2c66affSColin Finck 101c2c66affSColin Finck/*PSINGLE_LIST_ENTRY 102c2c66affSColin Finck *FASTCALL 103c2c66affSColin Finck *ExInterlockedPushEntrySList(IN PSINGLE_LIST_ENTRY ListHead, 104c2c66affSColin Finck * IN PSINGLE_LIST_ENTRY ListEntry, 105c2c66affSColin Finck * IN PKSPIN_LOCK Lock) 106c2c66affSColin Finck */ 107c2c66affSColin FinckPUBLIC @ExInterlockedPushEntrySList@12 108c2c66affSColin Finck@ExInterlockedPushEntrySList@12: 109c2c66affSColin Finck 110c2c66affSColin Finck /* So we can fall through below */ 111c2c66affSColin Finck pop [esp] 112c2c66affSColin Finck 113c2c66affSColin FinckPUBLIC @InterlockedPushEntrySList@8 114c2c66affSColin Finck@InterlockedPushEntrySList@8: 115c2c66affSColin Finck 116c2c66affSColin Finck /* Save registers */ 117c2c66affSColin Finck push ebx 118c2c66affSColin Finck push ebp 119c2c66affSColin Finck 120c2c66affSColin Finck /* Pointer to list */ 121c2c66affSColin Finck mov ebp, ecx 122c2c66affSColin Finck mov ebx, edx 123c2c66affSColin Finck 124c2c66affSColin Finck /* Get sequence number and link pointer */ 125c2c66affSColin Finck mov edx, [ebp+4] 126c2c66affSColin Finck mov eax, [ebp] 127c2c66affSColin Finck 128c2c66affSColin Finck.l8: 129c2c66affSColin Finck /* Set link pointer */ 130c2c66affSColin Finck mov [ebx], eax 131c2c66affSColin Finck 132c2c66affSColin Finck /* Copy sequence number and adjust it */ 133c2c66affSColin Finck lea ecx, [edx + HEX(10001)] 134c2c66affSColin Finck 135c2c66affSColin Finck /* Do the exchange */ 136c2c66affSColin Finck LOCK cmpxchg8b qword ptr [ebp] 137c2c66affSColin Finck jnz .l8 138c2c66affSColin Finck 139c2c66affSColin Finck /* Restore registers and return */ 140c2c66affSColin Finck pop ebp 141c2c66affSColin Finck pop ebx 142c2c66affSColin Finck ret 143c2c66affSColin Finck 144c2c66affSColin Finck/*PSINGLE_LIST_ENTRY 145c2c66affSColin Finck *FASTCALL 146c2c66affSColin Finck *ExInterlockedFlushSList(IN PSINGLE_LIST_ENTRY ListHead) 147c2c66affSColin Finck */ 148c2c66affSColin FinckPUBLIC @ExInterlockedFlushSList@4 149c2c66affSColin Finck@ExInterlockedFlushSList@4: 150c2c66affSColin Finck 151c2c66affSColin Finck /* Save registers */ 152c2c66affSColin Finck push ebx 153c2c66affSColin Finck push ebp 154c2c66affSColin Finck 155c2c66affSColin Finck /* Clear ebx */ 156c2c66affSColin Finck xor ebx, ebx 157c2c66affSColin Finck 158c2c66affSColin Finck /* Pointer to list */ 159c2c66affSColin Finck mov ebp, ecx 160c2c66affSColin Finck 161c2c66affSColin Finck /* Get sequence number and link pointer */ 162c2c66affSColin Finck mov edx, [ebp+4] 163c2c66affSColin Finck mov eax, [ebp] 164c2c66affSColin Finck 165c2c66affSColin Finck.l9: 166c2c66affSColin Finck /* Check if the list is empty */ 167c2c66affSColin Finck or eax, eax 168c2c66affSColin Finck jz .l10 169c2c66affSColin Finck 170c2c66affSColin Finck /* Clear depth and pointer */ 171c2c66affSColin Finck mov ecx, edx 172c2c66affSColin Finck mov cx, bx 173c2c66affSColin Finck 174c2c66affSColin Finck /* Do the exchange */ 175c2c66affSColin Finck LOCK cmpxchg8b qword ptr [ebp] 176c2c66affSColin Finck jnz .l9 177c2c66affSColin Finck 178c2c66affSColin Finck /* Restore registers and return */ 179c2c66affSColin Finck.l10: 180c2c66affSColin Finck pop ebp 181c2c66affSColin Finck pop ebx 182c2c66affSColin Finck ret 183c2c66affSColin Finck 184c2c66affSColin FinckEND 185c2c66affSColin Finck/* EOF */ 186