Moved interlocked functions to libwine_port.
This commit is contained in:
parent
f94c8b85b9
commit
108a69bd2f
|
@ -164,15 +164,11 @@ struct statfs;
|
|||
|
||||
|
||||
/****************************************************************
|
||||
* Function definitions (only when using libwine)
|
||||
* Function definitions (only when using libwine_port)
|
||||
*/
|
||||
|
||||
#ifndef NO_LIBWINE_PORT
|
||||
|
||||
#if !defined(HAVE_CLONE) && defined(linux)
|
||||
int clone(int (*fn)(void *arg), void *stack, int flags, void *arg);
|
||||
#endif /* !defined(HAVE_CLONE) && defined(linux) */
|
||||
|
||||
#ifndef HAVE_GETOPT_LONG
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
@ -255,7 +251,7 @@ extern int mkstemps(char *template, int suffix_len);
|
|||
|
||||
#if defined(__i386__) && defined(__GNUC__)
|
||||
|
||||
inline static long interlocked_cmpxchg( long *dest, long xchg, long compare )
|
||||
extern inline long interlocked_cmpxchg( long *dest, long xchg, long compare )
|
||||
{
|
||||
long ret;
|
||||
__asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
|
||||
|
@ -263,7 +259,7 @@ inline static long interlocked_cmpxchg( long *dest, long xchg, long compare )
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline static void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
|
||||
extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
|
||||
{
|
||||
void *ret;
|
||||
__asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
|
||||
|
@ -271,7 +267,7 @@ inline static void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *comp
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline static long interlocked_xchg( long *dest, long val )
|
||||
extern inline long interlocked_xchg( long *dest, long val )
|
||||
{
|
||||
long ret;
|
||||
__asm__ __volatile__( "lock; xchgl %0,(%1)"
|
||||
|
@ -279,7 +275,7 @@ inline static long interlocked_xchg( long *dest, long val )
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline static void *interlocked_xchg_ptr( void **dest, void *val )
|
||||
extern inline void *interlocked_xchg_ptr( void **dest, void *val )
|
||||
{
|
||||
void *ret;
|
||||
__asm__ __volatile__( "lock; xchgl %0,(%1)"
|
||||
|
@ -287,7 +283,7 @@ inline static void *interlocked_xchg_ptr( void **dest, void *val )
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline static long interlocked_xchg_add( long *dest, long incr )
|
||||
extern inline long interlocked_xchg_add( long *dest, long incr )
|
||||
{
|
||||
long ret;
|
||||
__asm__ __volatile__( "lock; xaddl %0,(%1)"
|
||||
|
@ -309,17 +305,23 @@ extern long interlocked_xchg_add( long *dest, long incr );
|
|||
|
||||
#define __WINE_NOT_PORTABLE(func) func##_is_not_portable func##_is_not_portable
|
||||
|
||||
#define clone __WINE_NOT_PORTABLE(clone)
|
||||
#define getpagesize __WINE_NOT_PORTABLE(getpagesize)
|
||||
#define lstat __WINE_NOT_PORTABLE(lstat)
|
||||
#define memmove __WINE_NOT_PORTABLE(memmove)
|
||||
#define pread __WINE_NOT_PORTABLE(pread)
|
||||
#define pwrite __WINE_NOT_PORTABLE(pwrite)
|
||||
#define statfs __WINE_NOT_PORTABLE(statfs)
|
||||
#define strcasecmp __WINE_NOT_PORTABLE(strcasecmp)
|
||||
#define strerror __WINE_NOT_PORTABLE(strerror)
|
||||
#define strncasecmp __WINE_NOT_PORTABLE(strncasecmp)
|
||||
#define usleep __WINE_NOT_PORTABLE(usleep)
|
||||
#define getopt_long __WINE_NOT_PORTABLE(getopt_long)
|
||||
#define getopt_long_only __WINE_NOT_PORTABLE(getopt_long_only)
|
||||
#define getpagesize __WINE_NOT_PORTABLE(getpagesize)
|
||||
#define interlocked_cmpxchg __WINE_NOT_PORTABLE(interlocked_cmpxchg)
|
||||
#define interlocked_cmpxchg_ptr __WINE_NOT_PORTABLE(interlocked_cmpxchg_ptr)
|
||||
#define interlocked_xchg __WINE_NOT_PORTABLE(interlocked_xchg)
|
||||
#define interlocked_xchg_ptr __WINE_NOT_PORTABLE(interlocked_xchg_ptr)
|
||||
#define interlocked_xchg_add __WINE_NOT_PORTABLE(interlocked_xchg_add)
|
||||
#define lstat __WINE_NOT_PORTABLE(lstat)
|
||||
#define memmove __WINE_NOT_PORTABLE(memmove)
|
||||
#define pread __WINE_NOT_PORTABLE(pread)
|
||||
#define pwrite __WINE_NOT_PORTABLE(pwrite)
|
||||
#define statfs __WINE_NOT_PORTABLE(statfs)
|
||||
#define strcasecmp __WINE_NOT_PORTABLE(strcasecmp)
|
||||
#define strerror __WINE_NOT_PORTABLE(strerror)
|
||||
#define strncasecmp __WINE_NOT_PORTABLE(strncasecmp)
|
||||
#define usleep __WINE_NOT_PORTABLE(usleep)
|
||||
|
||||
#endif /* NO_LIBWINE_PORT */
|
||||
|
||||
|
|
225
library/port.c
225
library/port.c
|
@ -271,228 +271,3 @@ void pthread_mutex_unlock() { assert(0); }
|
|||
#ifndef HAVE_PTHREAD_SETSPECIFIC
|
||||
void pthread_setspecific() { assert(0); }
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* interlocked functions
|
||||
*/
|
||||
#ifdef __i386__
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
__ASM_GLOBAL_FUNC(interlocked_cmpxchg,
|
||||
"movl 12(%esp),%eax\n\t"
|
||||
"movl 8(%esp),%ecx\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; cmpxchgl %ecx,(%edx)\n\t"
|
||||
"ret");
|
||||
__ASM_GLOBAL_FUNC(interlocked_cmpxchg_ptr,
|
||||
"movl 12(%esp),%eax\n\t"
|
||||
"movl 8(%esp),%ecx\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; cmpxchgl %ecx,(%edx)\n\t"
|
||||
"ret");
|
||||
__ASM_GLOBAL_FUNC(interlocked_xchg,
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; xchgl %eax,(%edx)\n\t"
|
||||
"ret");
|
||||
__ASM_GLOBAL_FUNC(interlocked_xchg_ptr,
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; xchgl %eax,(%edx)\n\t"
|
||||
"ret");
|
||||
__ASM_GLOBAL_FUNC(interlocked_xchg_add,
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; xaddl %eax,(%edx)\n\t"
|
||||
"ret");
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
__declspec(naked) long interlocked_cmpxchg( long *dest, long xchg, long compare )
|
||||
{
|
||||
__asm mov eax, 12[esp];
|
||||
__asm mov ecx, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock cmpxchg [edx], ecx;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
__declspec(naked) void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
|
||||
{
|
||||
__asm mov eax, 12[esp];
|
||||
__asm mov ecx, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock cmpxchg [edx], ecx;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
__declspec(naked) long interlocked_xchg( long *dest, long val )
|
||||
{
|
||||
__asm mov eax, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock xchg [edx], eax;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
__declspec(naked) void *interlocked_xchg_ptr( void **dest, void *val )
|
||||
{
|
||||
__asm mov eax, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock xchg [edx], eax;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
__declspec(naked) long interlocked_xchg_add( long *dest, long incr )
|
||||
{
|
||||
__asm mov eax, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock xadd [edx], eax;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
#else
|
||||
# error You must implement the interlocked* functions for your compiler
|
||||
#endif
|
||||
|
||||
#elif defined(__powerpc__)
|
||||
void* interlocked_cmpxchg_ptr( void **dest, void* xchg, void* compare)
|
||||
{
|
||||
long ret = 0;
|
||||
long scratch;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0,0,%2 ;"
|
||||
" xor. %1,%4,%0;"
|
||||
" bne 1f;"
|
||||
" stwcx. %3,0,%2;"
|
||||
" bne- 0b;"
|
||||
"1: "
|
||||
: "=&r"(ret), "=&r"(scratch)
|
||||
: "r"(dest), "r"(xchg), "r"(compare)
|
||||
: "cr0","memory");
|
||||
return (void*)ret;
|
||||
}
|
||||
|
||||
long interlocked_cmpxchg( long *dest, long xchg, long compare)
|
||||
{
|
||||
long ret = 0;
|
||||
long scratch;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0,0,%2 ;"
|
||||
" xor. %1,%4,%0;"
|
||||
" bne 1f;"
|
||||
" stwcx. %3,0,%2;"
|
||||
" bne- 0b;"
|
||||
"1: "
|
||||
: "=&r"(ret), "=&r"(scratch)
|
||||
: "r"(dest), "r"(xchg), "r"(compare)
|
||||
: "cr0","memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
long interlocked_xchg_add( long *dest, long incr )
|
||||
{
|
||||
long ret = 0;
|
||||
long zero = 0;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0, %3, %1;"
|
||||
" add %0, %2, %0;"
|
||||
" stwcx. %0, %3, %1;"
|
||||
" bne- 0b;"
|
||||
: "=&r" (ret)
|
||||
: "r"(dest), "r"(incr), "r"(zero)
|
||||
: "cr0", "memory"
|
||||
);
|
||||
return ret-incr;
|
||||
}
|
||||
|
||||
long interlocked_xchg( long* dest, long val )
|
||||
{
|
||||
long ret = 0;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0,0,%1 ;"
|
||||
" stwcx. %2,0,%1;"
|
||||
" bne- 0b;"
|
||||
: "=&r"(ret)
|
||||
: "r"(dest), "r"(val)
|
||||
: "cr0","memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* interlocked_xchg_ptr( void** dest, void* val )
|
||||
{
|
||||
void *ret = NULL;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0,0,%1 ;"
|
||||
" stwcx. %2,0,%1;"
|
||||
" bne- 0b;"
|
||||
: "=&r"(ret)
|
||||
: "r"(dest), "r"(val)
|
||||
: "cr0","memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(__sparc__) && defined(__sun__)
|
||||
|
||||
/*
|
||||
* As the earlier Sparc processors lack necessary atomic instructions,
|
||||
* I'm simply falling back to the library-provided _lwp_mutex routines
|
||||
* to ensure mutual exclusion in a way appropriate for the current
|
||||
* architecture.
|
||||
*
|
||||
* FIXME: If we have the compare-and-swap instruction (Sparc v9 and above)
|
||||
* we could use this to speed up the Interlocked operations ...
|
||||
*/
|
||||
#include <synch.h>
|
||||
static lwp_mutex_t interlocked_mutex = DEFAULTMUTEX;
|
||||
|
||||
long interlocked_cmpxchg( long *dest, long xchg, long compare )
|
||||
{
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
if (*dest == compare) *dest = xchg;
|
||||
else compare = *dest;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return compare;
|
||||
}
|
||||
|
||||
void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
|
||||
{
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
if (*dest == compare) *dest = xchg;
|
||||
else compare = *dest;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return compare;
|
||||
}
|
||||
|
||||
long interlocked_xchg( long *dest, long val )
|
||||
{
|
||||
long retv;
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
retv = *dest;
|
||||
*dest = val;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return retv;
|
||||
}
|
||||
|
||||
void *interlocked_xchg_ptr( void **dest, void *val )
|
||||
{
|
||||
long retv;
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
retv = *dest;
|
||||
*dest = val;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return retv;
|
||||
}
|
||||
|
||||
long interlocked_xchg_add( long *dest, long incr )
|
||||
{
|
||||
long retv;
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
retv = *dest;
|
||||
*dest += incr;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return retv;
|
||||
}
|
||||
#else
|
||||
# error You must implement the interlocked* functions for your CPU
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@ C_SRCS = \
|
|||
getopt.c \
|
||||
getopt1.c \
|
||||
getpagesize.c \
|
||||
interlocked.c \
|
||||
lstat.c \
|
||||
memmove.c \
|
||||
mkstemps.c \
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* interlocked functions
|
||||
*
|
||||
* Copyright 1996 Alexandre Julliard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
__ASM_GLOBAL_FUNC(interlocked_cmpxchg,
|
||||
"movl 12(%esp),%eax\n\t"
|
||||
"movl 8(%esp),%ecx\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; cmpxchgl %ecx,(%edx)\n\t"
|
||||
"ret");
|
||||
__ASM_GLOBAL_FUNC(interlocked_cmpxchg_ptr,
|
||||
"movl 12(%esp),%eax\n\t"
|
||||
"movl 8(%esp),%ecx\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; cmpxchgl %ecx,(%edx)\n\t"
|
||||
"ret");
|
||||
__ASM_GLOBAL_FUNC(interlocked_xchg,
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; xchgl %eax,(%edx)\n\t"
|
||||
"ret");
|
||||
__ASM_GLOBAL_FUNC(interlocked_xchg_ptr,
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; xchgl %eax,(%edx)\n\t"
|
||||
"ret");
|
||||
__ASM_GLOBAL_FUNC(interlocked_xchg_add,
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"lock; xaddl %eax,(%edx)\n\t"
|
||||
"ret");
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
__declspec(naked) long interlocked_cmpxchg( long *dest, long xchg, long compare )
|
||||
{
|
||||
__asm mov eax, 12[esp];
|
||||
__asm mov ecx, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock cmpxchg [edx], ecx;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
__declspec(naked) void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
|
||||
{
|
||||
__asm mov eax, 12[esp];
|
||||
__asm mov ecx, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock cmpxchg [edx], ecx;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
__declspec(naked) long interlocked_xchg( long *dest, long val )
|
||||
{
|
||||
__asm mov eax, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock xchg [edx], eax;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
__declspec(naked) void *interlocked_xchg_ptr( void **dest, void *val )
|
||||
{
|
||||
__asm mov eax, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock xchg [edx], eax;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
__declspec(naked) long interlocked_xchg_add( long *dest, long incr )
|
||||
{
|
||||
__asm mov eax, 8[esp];
|
||||
__asm mov edx, 4[esp];
|
||||
__asm lock xadd [edx], eax;
|
||||
__asm ret;
|
||||
}
|
||||
|
||||
#else
|
||||
# error You must implement the interlocked* functions for your compiler
|
||||
#endif
|
||||
|
||||
#elif defined(__powerpc__)
|
||||
void* interlocked_cmpxchg_ptr( void **dest, void* xchg, void* compare)
|
||||
{
|
||||
long ret = 0;
|
||||
long scratch;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0,0,%2 ;"
|
||||
" xor. %1,%4,%0;"
|
||||
" bne 1f;"
|
||||
" stwcx. %3,0,%2;"
|
||||
" bne- 0b;"
|
||||
"1: "
|
||||
: "=&r"(ret), "=&r"(scratch)
|
||||
: "r"(dest), "r"(xchg), "r"(compare)
|
||||
: "cr0","memory");
|
||||
return (void*)ret;
|
||||
}
|
||||
|
||||
long interlocked_cmpxchg( long *dest, long xchg, long compare)
|
||||
{
|
||||
long ret = 0;
|
||||
long scratch;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0,0,%2 ;"
|
||||
" xor. %1,%4,%0;"
|
||||
" bne 1f;"
|
||||
" stwcx. %3,0,%2;"
|
||||
" bne- 0b;"
|
||||
"1: "
|
||||
: "=&r"(ret), "=&r"(scratch)
|
||||
: "r"(dest), "r"(xchg), "r"(compare)
|
||||
: "cr0","memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
long interlocked_xchg_add( long *dest, long incr )
|
||||
{
|
||||
long ret = 0;
|
||||
long zero = 0;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0, %3, %1;"
|
||||
" add %0, %2, %0;"
|
||||
" stwcx. %0, %3, %1;"
|
||||
" bne- 0b;"
|
||||
: "=&r" (ret)
|
||||
: "r"(dest), "r"(incr), "r"(zero)
|
||||
: "cr0", "memory"
|
||||
);
|
||||
return ret-incr;
|
||||
}
|
||||
|
||||
long interlocked_xchg( long* dest, long val )
|
||||
{
|
||||
long ret = 0;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0,0,%1 ;"
|
||||
" stwcx. %2,0,%1;"
|
||||
" bne- 0b;"
|
||||
: "=&r"(ret)
|
||||
: "r"(dest), "r"(val)
|
||||
: "cr0","memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* interlocked_xchg_ptr( void** dest, void* val )
|
||||
{
|
||||
void *ret = NULL;
|
||||
__asm__ __volatile__(
|
||||
"0: lwarx %0,0,%1 ;"
|
||||
" stwcx. %2,0,%1;"
|
||||
" bne- 0b;"
|
||||
: "=&r"(ret)
|
||||
: "r"(dest), "r"(val)
|
||||
: "cr0","memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(__sparc__) && defined(__sun__)
|
||||
|
||||
/*
|
||||
* As the earlier Sparc processors lack necessary atomic instructions,
|
||||
* I'm simply falling back to the library-provided _lwp_mutex routines
|
||||
* to ensure mutual exclusion in a way appropriate for the current
|
||||
* architecture.
|
||||
*
|
||||
* FIXME: If we have the compare-and-swap instruction (Sparc v9 and above)
|
||||
* we could use this to speed up the Interlocked operations ...
|
||||
*/
|
||||
#include <synch.h>
|
||||
static lwp_mutex_t interlocked_mutex = DEFAULTMUTEX;
|
||||
|
||||
long interlocked_cmpxchg( long *dest, long xchg, long compare )
|
||||
{
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
if (*dest == compare) *dest = xchg;
|
||||
else compare = *dest;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return compare;
|
||||
}
|
||||
|
||||
void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
|
||||
{
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
if (*dest == compare) *dest = xchg;
|
||||
else compare = *dest;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return compare;
|
||||
}
|
||||
|
||||
long interlocked_xchg( long *dest, long val )
|
||||
{
|
||||
long retv;
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
retv = *dest;
|
||||
*dest = val;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return retv;
|
||||
}
|
||||
|
||||
void *interlocked_xchg_ptr( void **dest, void *val )
|
||||
{
|
||||
long retv;
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
retv = *dest;
|
||||
*dest = val;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return retv;
|
||||
}
|
||||
|
||||
long interlocked_xchg_add( long *dest, long incr )
|
||||
{
|
||||
long retv;
|
||||
_lwp_mutex_lock( &interlocked_mutex );
|
||||
retv = *dest;
|
||||
*dest += incr;
|
||||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return retv;
|
||||
}
|
||||
#else
|
||||
# error You must implement the interlocked* functions for your CPU
|
||||
#endif
|
Loading…
Reference in New Issue