| 1 | ; $Id: interlock.asm,v 1.7 1999-12-16 00:59:21 sandervl Exp $ | 
|---|
| 2 |  | 
|---|
| 3 | ;/* | 
|---|
| 4 | ; * Interlocked apis | 
|---|
| 5 | ; * | 
|---|
| 6 | ; * Copyright 1999 Sander van Leeuwen | 
|---|
| 7 | ; * Copyright 1999 Patrick Haller | 
|---|
| 8 | ; * | 
|---|
| 9 | ; * Based on WINE code: win32\thread.c (990815) | 
|---|
| 10 | ; * | 
|---|
| 11 | ; * Copyright 1995 Martin von Loewis | 
|---|
| 12 | ; * Copyright 1997 Onno Hovers | 
|---|
| 13 | ; * | 
|---|
| 14 | ; * Project Odin Software License can be found in LICENSE.TXT | 
|---|
| 15 | ; * | 
|---|
| 16 | ; */ | 
|---|
| 17 | .586P | 
|---|
| 18 | NAME    interlocked | 
|---|
| 19 |  | 
|---|
| 20 | CODE32         SEGMENT DWORD PUBLIC USE32 'CODE' | 
|---|
| 21 |  | 
|---|
| 22 | public  _InterlockedIncrement@4 | 
|---|
| 23 |  | 
|---|
| 24 | ;*           InterlockedIncrement                       [KERNEL32]      * | 
|---|
| 25 | ;*                                                                      * | 
|---|
| 26 | ;* InterlockedIncrement adds 1 to a long variable and returns           * | 
|---|
| 27 | ;*  -  a negative number if the result < 0                              * | 
|---|
| 28 | ;*  -  zero if the result == 0                                          * | 
|---|
| 29 | ;*  -  a positive number if the result > 0                              * | 
|---|
| 30 | ;*                                                                      * | 
|---|
| 31 | ;* The returned number need not be equal to the result!!!!              * | 
|---|
| 32 |  | 
|---|
| 33 | _InterlockedIncrement@4 proc near | 
|---|
| 34 | mov     eax, dword ptr [esp+4] ; LPLONG lpAddend | 
|---|
| 35 | lock    inc dword ptr [eax] | 
|---|
| 36 | mov     eax, 0 | 
|---|
| 37 | je      @end                  ; not incremented? | 
|---|
| 38 | jl      @decr | 
|---|
| 39 | inc     eax                    ; ? | 
|---|
| 40 | jmp     @end | 
|---|
| 41 | @decr:  dec     eax                    ; ? | 
|---|
| 42 | @end:   ret     4 | 
|---|
| 43 | _InterlockedIncrement@4 endp | 
|---|
| 44 |  | 
|---|
| 45 | public  _InterlockedDecrement@4 | 
|---|
| 46 |  | 
|---|
| 47 | ;*           InterlockedDecrement                       [KERNEL32]      * | 
|---|
| 48 | ;*                                                                      * | 
|---|
| 49 | ;* InterlockedIncrement adds 1 to a long variable and returns           * | 
|---|
| 50 | ;*  -  a negative number if the result < 0                              * | 
|---|
| 51 | ;*  -  zero if the result == 0                                          * | 
|---|
| 52 | ;*  -  a positive number if the result > 0                              * | 
|---|
| 53 | ;*                                                                      * | 
|---|
| 54 | ;* The returned number need not be equal to the result!!!!              * | 
|---|
| 55 |  | 
|---|
| 56 | _InterlockedDecrement@4 proc near | 
|---|
| 57 | mov     eax, dword ptr [esp+4] ; LPLONG lpAddend | 
|---|
| 58 | lock    dec dword ptr [eax] | 
|---|
| 59 | mov     eax, 0 | 
|---|
| 60 | je      @end                   ; not decremented? | 
|---|
| 61 | jl      @decr | 
|---|
| 62 | inc     eax                    ; ? | 
|---|
| 63 | jmp     @end | 
|---|
| 64 | @decr:  dec     eax                    ; ? | 
|---|
| 65 | @end:   ret     4 | 
|---|
| 66 | _InterlockedDecrement@4 endp | 
|---|
| 67 |  | 
|---|
| 68 |  | 
|---|
| 69 | public  _InterlockedExchange@8 | 
|---|
| 70 | ; *           InterlockedExchange                               [KERNEL32.???] | 
|---|
| 71 | ; * | 
|---|
| 72 | ; * Atomically exchanges a pair of values. | 
|---|
| 73 | ; * | 
|---|
| 74 | ; * RETURNS | 
|---|
| 75 | ; *     Prior value of value pointed to by Target | 
|---|
| 76 |  | 
|---|
| 77 | _InterlockedExchange@8 proc near | 
|---|
| 78 | push    edx | 
|---|
| 79 | mov     eax, [esp+12]           ; LONG value | 
|---|
| 80 | mov     edx,[esp+8]             ; LPLONG target | 
|---|
| 81 | lock    xchg eax, dword ptr [edx] | 
|---|
| 82 | pop     edx | 
|---|
| 83 | ret     8 | 
|---|
| 84 | _InterlockedExchange@8 endp | 
|---|
| 85 |  | 
|---|
| 86 |  | 
|---|
| 87 |  | 
|---|
| 88 | public _InterlockedCompareExchange@12 | 
|---|
| 89 | ;/************************************************************************ | 
|---|
| 90 | ; *           InterlockedCompareExchange                [KERNEL32.879] | 
|---|
| 91 | ; * | 
|---|
| 92 | ; * Atomically compares Destination and Comperand, and if found equal exchanges | 
|---|
| 93 | ; * the value of Destination with Exchange | 
|---|
| 94 | ; * | 
|---|
| 95 | ; * RETURNS | 
|---|
| 96 | ; *     Prior value of value pointed to by Destination | 
|---|
| 97 | ; */ | 
|---|
| 98 | _InterlockedCompareExchange@12 proc near | 
|---|
| 99 | push    ebp | 
|---|
| 100 | mov     ebp, esp | 
|---|
| 101 | push    edx | 
|---|
| 102 | push    ebx | 
|---|
| 103 |  | 
|---|
| 104 | mov     ebx, dword ptr [ebp+8]  ;PVOID *Destination, /* Address of 32-bit value to exchange */ | 
|---|
| 105 | push    dword ptr [ebx]         ;save old *Destination | 
|---|
| 106 | mov     eax, [ebp+16]           ;PVOID Comperand      /* value to compare, 32 bits */ | 
|---|
| 107 | mov     edx, [ebp+12]           ;PVOID Exchange,      /* change value, 32 bits */ | 
|---|
| 108 | lock    cmpxchg dword ptr [ebx],edx | 
|---|
| 109 | pop     eax | 
|---|
| 110 |  | 
|---|
| 111 | pop     ebx | 
|---|
| 112 | pop     edx | 
|---|
| 113 | pop     ebp | 
|---|
| 114 | ret     12 | 
|---|
| 115 | _InterlockedCompareExchange@12 endp | 
|---|
| 116 |  | 
|---|
| 117 | public _InterlockedExchangeAdd@8 | 
|---|
| 118 | ; *           InterlockedExchangeAdd                    [KERNEL32.880] | 
|---|
| 119 | ; * | 
|---|
| 120 | ; * Atomically adds Increment to Addend and returns the previous value of | 
|---|
| 121 | ; * Addend | 
|---|
| 122 | ; * | 
|---|
| 123 | ; * RETURNS | 
|---|
| 124 | ; *     Prior value of value pointed to by cwAddendTarget | 
|---|
| 125 | ; */ | 
|---|
| 126 | _InterlockedExchangeAdd@8 proc near | 
|---|
| 127 | push    edx | 
|---|
| 128 | mov     eax, dword ptr [esp+12] ;LONG Increment /* Value to add */ | 
|---|
| 129 | mov     edx, dword ptr [esp+8]  ;PLONG Addend, /* Address of 32-bit value to exchange */ | 
|---|
| 130 | lock    xadd dword ptr [edx], eax | 
|---|
| 131 | pop     edx | 
|---|
| 132 | ret     8 | 
|---|
| 133 | _InterlockedExchangeAdd@8 endp | 
|---|
| 134 |  | 
|---|
| 135 | CODE32          ENDS | 
|---|
| 136 |  | 
|---|
| 137 | END | 
|---|