xref: /reactos/sdk/lib/rtl/i386/interlck.S (revision c2c66aff)
1/*
2 * COPYRIGHT:       See COPYING in the top level directory
3 * PROJECT:         ReactOS system libraries
4 * FILE:            lib/rtl/i386/interlck.S
5 * PURPOSE:         Rtl Interlocked Functions for x86
6 * PROGRAMMERS:     Timo Kreuzer
7 */
8
9#include <asm.inc>
10
11/* FUNCTIONS ****************************************************************/
12.code
13
14/* PSLIST_ENTRY
15 * NTAPI
16 * RtlInterlockedPopEntrySList(
17 *     IN PSLIST_HEADER ListHead);
18 */
19PUBLIC _ExpInterlockedPopEntrySListResume@0
20PUBLIC _ExpInterlockedPopEntrySListEnd@0
21PUBLIC _ExpInterlockedPopEntrySListFault@0
22PUBLIC _RtlInterlockedPopEntrySList@4
23_RtlInterlockedPopEntrySList@4:
24
25    /* Save registers */
26    push ebx
27    push ebp
28
29    /* Load ListHead into ebp */
30    mov ebp, [esp + 12]
31_ExpInterlockedPopEntrySListResume@0:
32    /* Load ListHead->Next into eax */
33    mov eax, [ebp]
34
35    /* Load ListHead->Depth and ListHead->Sequence into edx */
36    mov edx, [ebp + 4]
37
38    /* Check if ListHead->Next is NULL */
39    or eax, eax
40    jz _ExpInterlockedPopEntrySList2
41
42    /* Copy Depth and Sequence number and adjust Depth */
43    lea ecx, [edx - 1]
44
45_ExpInterlockedPopEntrySListFault@0:
46    /* Get next pointer */
47    mov ebx, [eax]
48_ExpInterlockedPopEntrySListEnd@0:
49    /* If [ebp] equals edx:eax, exchange it with ecx:ebx */
50    LOCK cmpxchg8b qword ptr [ebp]
51
52    /* If not equal, retry with edx:eax, being the content of [ebp] now */
53    jnz _ExpInterlockedPopEntrySListResume@0
54
55    /* Restore registers and return */
56_ExpInterlockedPopEntrySList2:
57    pop ebp
58    pop ebx
59    ret 4
60
61
62/* PSLIST_ENTRY
63 * NTAPI
64 * RtlInterlockedPushEntrySList(
65 *     IN PSLIST_HEADER ListHead,
66 *     IN PSLIST_ENTRY ListEntry);
67 */
68PUBLIC _RtlInterlockedPushEntrySList@8
69_RtlInterlockedPushEntrySList@8:
70
71    /* Save registers */
72    push ebx
73    push ebp
74
75    /* Load ListHead into ebp */
76    mov ebp, [esp + 12]
77
78    /* Load ListEntry into ebx */
79    mov ebx, [esp + 16]
80
81    /* Load ListHead->Next into eax */
82    mov eax, [ebp]
83
84    /* Load ListHead->Depth and ListHead->Sequence into edx */
85    mov edx, [ebp + 4]
86
87_RtlpInterlockedPushEntrySListResume:
88    /* Set ListEntry->Next to ListHead->Next */
89    mov [ebx], eax
90
91    /* Copy ListHead->Depth and ListHead->Sequence and adjust them */
92    lea ecx, [edx + HEX(10001)]
93
94    /* If [ebp] equals edx:eax, exchange it with ecx:ebx */
95    LOCK cmpxchg8b qword ptr [ebp]
96
97    /* If not equal, retry with edx:eax, being the content of [ebp] now */
98    jnz _RtlpInterlockedPushEntrySListResume
99
100    /* Restore registers and return */
101    pop ebp
102    pop ebx
103    ret 8
104
105
106/* PSLIST_ENTRY
107 * NTAPI
108 * RtlInterlockedFlushSList(
109 *     IN PSINGLE_LIST_ENTRY ListHead);
110 */
111PUBLIC _RtlInterlockedFlushSList@4
112_RtlInterlockedFlushSList@4:
113
114    /* Save registers */
115    push ebx
116    push ebp
117
118    /* Clear ebx */
119    xor ebx, ebx
120
121    /* Load ListHead into ebp */
122    mov ebp, [esp + 12]
123
124    /* Load ListHead->Next into eax */
125    mov eax, [ebp]
126
127    /* Load ListHead->Depth and ListHead->Sequence into edx */
128    mov edx, [ebp + 4]
129
130_RtlpInterlockedFlushSListResume:
131    /* Check if ListHead->Next is NULL */
132    or eax, eax
133    jz _RtlpInterlockedFlushSListEnd
134
135    /* Copy Depth and Sequence number to ecx */
136    mov ecx, edx
137
138    /* Clear Depth in cx */
139    xor cx, cx
140
141    /* If [ebp] equals edx:eax, exchange it with ecx:ebx */
142    LOCK cmpxchg8b qword ptr [ebp]
143
144    /* If not equal, retry with edx:eax, being the content of [ebp] now */
145    jnz _RtlpInterlockedFlushSListResume
146
147    /* Restore registers and return */
148_RtlpInterlockedFlushSListEnd:
149    pop ebp
150    pop ebx
151    ret 4
152
153END
154