From 6df25e8004949862435b2a55388f146ca08f6828 Mon Sep 17 00:00:00 2001 From: Rein Klazes Date: Sat, 14 Nov 1998 18:21:32 +0000 Subject: [PATCH] Added implementations for InterlockedExchangeAdd() and InterlockedCompareExchange(). --- relay32/kernel32.spec | 4 +-- win32/thread.c | 71 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec index 279ea6368d8..3b81fd2cf5b 100644 --- a/relay32/kernel32.spec +++ b/relay32/kernel32.spec @@ -893,8 +893,8 @@ init MAIN_KernelInit 875 stdcall GetFileAttributesExW(wstr long ptr) GetFileAttributesEx32W 876 stub GetProcessPriorityBoost 877 stub GetThreadPriorityBoost -878 stub InterlockedCompareExchange -879 stub InterlockedExchangeAdd +878 stdcall InterlockedCompareExchange (ptr long long) InterlockedCompareExchange +879 stdcall InterlockedExchangeAdd (ptr long ) InterlockedExchangeAdd 880 stdcall IsProcessorFeaturePresent(long) IsProcessorFeaturePresent 881 stub OpenWaitableTimerA 882 stub OpenWaitableTimerW diff --git a/win32/thread.c b/win32/thread.c index cdf46ab7679..a235a5f2f6f 100644 --- a/win32/thread.c +++ b/win32/thread.c @@ -7,7 +7,7 @@ #include #include -#include "windows.h" +#include "winnt.h" #include "winbase.h" #include "winerror.h" #include "debug.h" @@ -131,3 +131,72 @@ LONG WINAPI InterlockedExchange( return ret; #endif } + +/************************************************************************ + * InterlockedCompareExchange [KERNEL32.879] + * + * Atomically compares Destination and Comperand, and if found equal exchanges + * the value of Destination with Exchange + * + * RETURNS + * Prior value of value pointed to by Destination + */ +PVOID WINAPI InterlockedCompareExchange( + PVOID *Destination, /* Address of 32-bit value to exchange */ + PVOID Exchange, /* change value, 32 bits */ + PVOID Comperand /* value to compare, 32 bits */ +) { +#if defined(__i386__)&&defined(__GNUC__) + PVOID ret; + __asm__ ( /* lock for SMP systems */ + "lock\n\t" + "cmpxchgl %2,(%1)" + :"=r" (ret) + :"r" (Destination),"r" (Exchange), "0" (Comperand) + :"memory" ); + return ret; +#else + PVOID ret; + /* StopAllThreadsAndProcesses() */ + + ret=*Destination; + if(*Destination==Comperand) *Destination=Exchange; + + /* ResumeAllThreadsAndProcesses() */ + return ret; +#endif +} + +/************************************************************************ + * InterlockedExchangeAdd [KERNEL32.880] + * + * Atomically adds Increment to Addend and returns the previous value of + * Addend + * + * RETURNS + * Prior value of value pointed to by cwAddendTarget + */ +LONG WINAPI InterlockedExchangeAdd( + PLONG Addend, /* Address of 32-bit value to exchange */ + LONG Increment /* Value to add */ +) { +#if defined(__i386__)&&defined(__GNUC__) + LONG ret; + __asm__ ( /* lock for SMP systems */ + "lock\n\t" + "xaddl %0,(%1)" + :"=r" (ret) + :"r" (Addend), "0" (Increment) + :"memory" ); + return ret; +#else + LONG ret; + /* StopAllThreadsAndProcesses() */ + + ret = *Addend; + *Addend += Increment; + + /* ResumeAllThreadsAndProcesses() */ + return ret; +#endif +}