forked from dolphinsmalltalk/DolphinVM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
InterlockedOps.c
54 lines (45 loc) · 1.56 KB
/
InterlockedOps.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/******************************************************************************
File: InterlockedOps.c
Description:
These are duplicates of the NT interlocked operations, implemented because:
1) Win95 does not implement some of them at all
2) Win95 implements some of them differently (and less usefully)
3) Local copies avoid the indirection through the DLL import jump, and therefore
offer improved performance
******************************************************************************/
#pragma warning(push,3)
#include <wtypes.h>
#include "InterlockedOps.h"
// Disable warning about no return value (cos there is one)
#pragma warning (disable : 4035)
// Not implemented under Win95 (sigh).
// This is the exact NT implementation, which is really just a wrapper around an assembler instruction
__declspec(naked) PVOID __stdcall OAInterlockedCompareExchange(PVOID *Destination, PVOID Exchange, PVOID Comperand)
{
UNREFERENCED_PARAMETER(Destination);
UNREFERENCED_PARAMETER(Exchange);
UNREFERENCED_PARAMETER(Comperand);
_asm
{
mov ecx, DWORD PTR [esp+4]
mov edx, DWORD PTR [esp+8]
mov eax, DWORD PTR [esp+12]
lock cmpxchg DWORD PTR [ecx],edx
ret 12
}
}
// By using __fastcall convention we can save significantly on the instruction count since there are only two
// arguments
__declspec(naked) LONG __fastcall OAInterlockedExchange(LPLONG Target, LONG Value)
{
UNREFERENCED_PARAMETER(Target);
UNREFERENCED_PARAMETER(Value);
_asm
{
mov eax,dword ptr [ecx]
label:
lock cmpxchg dword ptr [ecx],edx
jne label // Swap it back?
ret
}
}