First commit for SDL atomic operations.
On my linux box it compiles and installs correctly and testatomic runs without errors. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403638
This commit is contained in:
parent
d083f30b19
commit
d813a7eac5
11 changed files with 755 additions and 2 deletions
|
@ -42,7 +42,7 @@ SDLMAIN_OBJECTS = @SDLMAIN_OBJECTS@
|
||||||
|
|
||||||
DIST = acinclude.m4 autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS docs docs.html include INSTALL Makefile.dc Makefile.minimal Makefile.in README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualC.html VisualC VisualCE Watcom-OS2.zip Watcom-Win32.zip WhatsNew Xcode
|
DIST = acinclude.m4 autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS docs docs.html include INSTALL Makefile.dc Makefile.minimal Makefile.in README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualC.html VisualC VisualCE Watcom-OS2.zip Watcom-Win32.zip WhatsNew Xcode
|
||||||
|
|
||||||
HDRS = SDL.h SDL_audio.h SDL_cdrom.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_haptic.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
|
HDRS = SDL.h SDL_atomic.h SDL_audio.h SDL_cdrom.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_haptic.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
|
||||||
|
|
||||||
LT_AGE = @LT_AGE@
|
LT_AGE = @LT_AGE@
|
||||||
LT_CURRENT = @LT_CURRENT@
|
LT_CURRENT = @LT_CURRENT@
|
||||||
|
|
|
@ -159,6 +159,7 @@ if test x$enable_libc = xyes; then
|
||||||
AC_CHECK_FUNCS(iconv)
|
AC_CHECK_FUNCS(iconv)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF(void*)
|
||||||
if test x$have_inttypes != xyes; then
|
if test x$have_inttypes != xyes; then
|
||||||
AC_CHECK_SIZEOF(char, 1)
|
AC_CHECK_SIZEOF(char, 1)
|
||||||
AC_CHECK_SIZEOF(short, 2)
|
AC_CHECK_SIZEOF(short, 2)
|
||||||
|
|
|
@ -76,6 +76,7 @@ Enjoy!
|
||||||
|
|
||||||
#include "SDL_main.h"
|
#include "SDL_main.h"
|
||||||
#include "SDL_stdinc.h"
|
#include "SDL_stdinc.h"
|
||||||
|
#include "SDL_atomic.h"
|
||||||
#include "SDL_audio.h"
|
#include "SDL_audio.h"
|
||||||
#include "SDL_cdrom.h"
|
#include "SDL_cdrom.h"
|
||||||
#include "SDL_cpuinfo.h"
|
#include "SDL_cpuinfo.h"
|
||||||
|
|
674
include/SDL_atomic.h
Normal file
674
include/SDL_atomic.h
Normal file
|
@ -0,0 +1,674 @@
|
||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2006 Sam Lantinga
|
||||||
|
|
||||||
|
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file SDL_atomic.h
|
||||||
|
*
|
||||||
|
* Atomic int and pointer magic
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SDL_atomic_h_
|
||||||
|
#define _SDL_atomic_h_
|
||||||
|
|
||||||
|
|
||||||
|
#include "SDL_stdinc.h"
|
||||||
|
#include "SDL_platform.h"
|
||||||
|
|
||||||
|
#include "begin_code.h"
|
||||||
|
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && (defined(i386) || defined(__i386__) || defined(__x86_64__))
|
||||||
|
static __inline__ void
|
||||||
|
SDL_atomic_int_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__("lock;"
|
||||||
|
"addl %1, %0"
|
||||||
|
: "=m" (*atomic)
|
||||||
|
: "ir" (value),
|
||||||
|
"m" (*atomic));
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ int
|
||||||
|
SDL_atomic_int_xchg_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
__asm__ __volatile__("lock;"
|
||||||
|
"xaddl %0, %1"
|
||||||
|
: "=r" (rv),
|
||||||
|
"=m" (*atomic)
|
||||||
|
: "0" (value),
|
||||||
|
"m" (*atomic));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
__asm__ __volatile__("lock;"
|
||||||
|
"cmpxchgl %2, %1"
|
||||||
|
: "=a" (rv),
|
||||||
|
"=m" (*atomic)
|
||||||
|
: "r" (newvalue),
|
||||||
|
"m" (*atomic),
|
||||||
|
"0" (oldvalue));
|
||||||
|
return (rv == oldvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
void* rv;
|
||||||
|
__asm__ __volatile__("lock;"
|
||||||
|
# if defined(__x86_64__)
|
||||||
|
"cmpxchgq %q2, %1"
|
||||||
|
# else
|
||||||
|
"cmpxchgl %2, %1"
|
||||||
|
# endif
|
||||||
|
: "=a" (rv),
|
||||||
|
"=m" (*atomic)
|
||||||
|
: "r" (newvalue),
|
||||||
|
"m" (*atomic),
|
||||||
|
"0" (oldvalue));
|
||||||
|
return (rv == oldvalue);
|
||||||
|
}
|
||||||
|
#elif defined(__GNUC__) && defined(__alpha__)
|
||||||
|
# define ATOMIC_MEMORY_BARRIER (__asm__ __volatile__ ("mb" : : : "memory"))
|
||||||
|
# define ATOMIC_INT_CMP_XCHG(atomic,value) \
|
||||||
|
({ \
|
||||||
|
int rv,prev; \
|
||||||
|
__asm__ __volatile__(" mb\n" \
|
||||||
|
"1: ldl_l %0,%2\n" \
|
||||||
|
" cmpeq %0,%3,%1\n" \
|
||||||
|
" beq %1,2f\n" \
|
||||||
|
" mov %4,%1\n" \
|
||||||
|
" stl_c %1,%2\n" \
|
||||||
|
" beq %1,1b\n" \
|
||||||
|
" mb\n" \
|
||||||
|
"2:" \
|
||||||
|
: "=&r" (prev), \
|
||||||
|
"=&r" (rv) \
|
||||||
|
: "m" (*(atomic)), \
|
||||||
|
"Ir" (oldvalue), \
|
||||||
|
"Ir" (newvalue) \
|
||||||
|
: "memory"); \
|
||||||
|
(rv != 0); \
|
||||||
|
})
|
||||||
|
|
||||||
|
# if (SIZEOF_VOIDP == 4)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
void* prev;
|
||||||
|
__asm__ __volatile__(" mb\n"
|
||||||
|
"1: ldl_l %0,%2\n"
|
||||||
|
" cmpeq %0,%3,%1\n"
|
||||||
|
" beq $1,2f\n"
|
||||||
|
" mov %4,%1\n"
|
||||||
|
" stl_c %1,%2\n"
|
||||||
|
" beq %1,1b\n"
|
||||||
|
" mb\n"
|
||||||
|
"2:"
|
||||||
|
: "=&r" (prev),
|
||||||
|
"=&r" (rv)
|
||||||
|
: "m" (*atomic),
|
||||||
|
"Ir" (oldvalue),
|
||||||
|
"Ir" (newvalue)
|
||||||
|
: "memory");
|
||||||
|
return (rv != 0);
|
||||||
|
}
|
||||||
|
# elif (SIZEOF_VOIDP == 8)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
void* prev;
|
||||||
|
__asm__ __volatile__(" mb\n"
|
||||||
|
"1: ldq_l %0,%2\n"
|
||||||
|
" cmpeq %0,%3,%1\n"
|
||||||
|
" beq %1,2f\n"
|
||||||
|
" mov %4,%1\n"
|
||||||
|
" stq_c %1,%2\n"
|
||||||
|
" beq %1,1b\n"
|
||||||
|
" mb\n"
|
||||||
|
"2:"
|
||||||
|
: "=&r" (prev),
|
||||||
|
"=&r" (rv)
|
||||||
|
: "m" (*atomic),
|
||||||
|
"Ir" (oldvalue),
|
||||||
|
"Ir" (newvalue)
|
||||||
|
: "memory");
|
||||||
|
return (rv != 0);
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# error "Your system has an unsupported pointer size"
|
||||||
|
# endif /* SIZEOF_VOIDP */
|
||||||
|
#elif defined(__GNUC__) && defined(__sparc__)
|
||||||
|
# define ATOMIC_MEMORY_BARRIER \
|
||||||
|
(__asm__ __volatile__("membar #LoadLoad | #LoadStore" \
|
||||||
|
" | #StoreLoad | #StoreStore" : : : "memory"))
|
||||||
|
# define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue) \
|
||||||
|
({ \
|
||||||
|
int rv; \
|
||||||
|
__asm__ __volatile__("cas [%4], %2, %0" \
|
||||||
|
: "=r" (rv), "=m" (*(atomic)) \
|
||||||
|
: "r" (oldvalue), "m" (*(atomic)), \
|
||||||
|
"r" (atomic), "0" (newvalue)); \
|
||||||
|
rv == oldvalue; \
|
||||||
|
})
|
||||||
|
|
||||||
|
# if (SIZEOF_VOIDP == 4)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
void* rv;
|
||||||
|
__asm__ __volatile__("cas [%4], %2, %0"
|
||||||
|
: "=r" (rv),
|
||||||
|
"=m" (*atomic)
|
||||||
|
: "r" (oldvalue),
|
||||||
|
"m" (*atomic),
|
||||||
|
"r" (atomic),
|
||||||
|
"0" (newvalue));
|
||||||
|
return (rv == oldvalue);
|
||||||
|
}
|
||||||
|
# elif (SIZEOF_VOIDP == 8)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
void* rv;
|
||||||
|
void** a = atomic;
|
||||||
|
__asm__ __volatile__("casx [%4], %2, %0"
|
||||||
|
: "=r" (rv),
|
||||||
|
"=m" (*a)
|
||||||
|
: "r" (oldvalue),
|
||||||
|
"m" (*a),
|
||||||
|
"r" (a),
|
||||||
|
"0" (newvalue));
|
||||||
|
return (rv == oldvalue);
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# error "Your system has an unsupported pointer size"
|
||||||
|
# endif /* SIZEOF_VOIDP */
|
||||||
|
#elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC))
|
||||||
|
# define ATOMIC_MEMORY_BARRIER \
|
||||||
|
(__asm__ __volatile__ ("sync" : : : "memory"))
|
||||||
|
static __inline__ void
|
||||||
|
SDL_atomic_int_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv,tmp;
|
||||||
|
__asm__ __volatile__("1: lwarx %0, 0, %3\n"
|
||||||
|
" add %1, %0, %4\n"
|
||||||
|
" stwcx. %1, 0, %3\n"
|
||||||
|
" bne- 1b"
|
||||||
|
: "=&b" (rv),
|
||||||
|
"=&r" (tmp),
|
||||||
|
"=m" (*atomic)
|
||||||
|
: "b" (atomic),
|
||||||
|
"r" (value),
|
||||||
|
"m" (*atomic)
|
||||||
|
: "cr0",
|
||||||
|
"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ int
|
||||||
|
SDL_atomic_int_xchg_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv,tmp;
|
||||||
|
__asm__ __volatile__("1: lwarx %0, 0, %3\n"
|
||||||
|
" add %1, %0, %4\n"
|
||||||
|
" stwcx. %1, 0, %3\n"
|
||||||
|
" bne- 1b"
|
||||||
|
: "=&b" (rv),
|
||||||
|
"=&r" (tmp),
|
||||||
|
"=m" (*atomic)
|
||||||
|
: "b" (atomic),
|
||||||
|
"r" (value),
|
||||||
|
"m" (*atomic)
|
||||||
|
: "cr0",
|
||||||
|
"memory");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
# if (SIZEOF_VOIDP == 4)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
__asm__ __volatile__(" sync\n"
|
||||||
|
"1: lwarx %0, 0, %1\n"
|
||||||
|
" subf. %0, %2, %0\n"
|
||||||
|
" bne 2f\n"
|
||||||
|
" stwcx. %3, 0, %1\n"
|
||||||
|
" bne- 1b\n"
|
||||||
|
"2: isync"
|
||||||
|
: "=&r" (rv)
|
||||||
|
: "b" (atomic),
|
||||||
|
"r" (oldvalue),
|
||||||
|
"r"
|
||||||
|
: "cr0",
|
||||||
|
"memory");
|
||||||
|
return (rv == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
void* rv;
|
||||||
|
__asm__ __volatile__("sync\n"
|
||||||
|
"1: lwarx %0, 0, %1\n"
|
||||||
|
" subf. %0, %2, %0\n"
|
||||||
|
" bne 2f\n"
|
||||||
|
" stwcx. %3, 0, %1\n"
|
||||||
|
" bne- 1b\n"
|
||||||
|
"2: isync"
|
||||||
|
: "=&r" (rv)
|
||||||
|
: "b" (atomic),
|
||||||
|
"r" (oldvalue),
|
||||||
|
"r" (newvalue)
|
||||||
|
: "cr0",
|
||||||
|
"memory");
|
||||||
|
return (rv == 0);
|
||||||
|
}
|
||||||
|
# elif (SIZEOF_VOIDP == 8)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
__asm__ __volatile__(" sync\n"
|
||||||
|
"1: lwarx %0, 0, %1\n"
|
||||||
|
" extsw %0, %0\n"
|
||||||
|
" subf. %0, %2, %0\n"
|
||||||
|
" bne 2f\n"
|
||||||
|
" stwcx. %3, 0, %1\n"
|
||||||
|
" bne- 1b\n"
|
||||||
|
"2: isync"
|
||||||
|
: "=&r" (rv)
|
||||||
|
: "b" (atomic),
|
||||||
|
"r" (oldvalue),
|
||||||
|
"r"
|
||||||
|
: "cr0",
|
||||||
|
"memory");
|
||||||
|
return (rv == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
void* rv;
|
||||||
|
__asm__ __volatile__("sync\n"
|
||||||
|
"1: ldarx %0, 0, %1\n"
|
||||||
|
" subf. %0, %2, %0\n"
|
||||||
|
" bne 2f\n"
|
||||||
|
" stdcx. %3, 0, %1\n"
|
||||||
|
" bne- 1b\n"
|
||||||
|
"2: isync"
|
||||||
|
: "=&r" (rv)
|
||||||
|
: "b" (atomic),
|
||||||
|
"r" (oldvalue),
|
||||||
|
"r" (newvalue)
|
||||||
|
: "cr0",
|
||||||
|
"memory");
|
||||||
|
return (rv == 0);
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# error "Your system has an unsupported pointer size"
|
||||||
|
# endif /* SIZEOF_VOIDP */
|
||||||
|
#elif defined(__GNUC__) && (defined(__IA64__) || defined(__ia64__))
|
||||||
|
# define ATOMIC_MEMORY_BARRIER (__sync_synchronize())
|
||||||
|
# define SDL_atomic_int_xchg_add(atomic, value) \
|
||||||
|
(__sync_fetch_and_add((atomic),(value)))
|
||||||
|
# define SDL_atomic_int_add(atomic, value) \
|
||||||
|
((void)__sync_fetch_and_add((atomic),(value)))
|
||||||
|
# define SDL_atomic_int_cmp_xchg(atomic,oldvalue,newvalue) \
|
||||||
|
(__sync_bool_compare_and_swap((atomic),(oldvalue),(newvalue)))
|
||||||
|
# define SDL_atomic_ptr_cmp_xchg(atomic,oldvalue,newvalue) \
|
||||||
|
(__sync_bool_compare_and_swap((long*)(atomic),(long)(oldvalue),(long)(newvalue)))
|
||||||
|
#elif defined(__GNUC__) && defined(__LINUX__) && (defined(__mips__) || defined(__MIPS__))
|
||||||
|
static __inline__ int
|
||||||
|
SDL_atomic_int_xchg_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv,tmp;
|
||||||
|
__asm__ __volatile__("1: \n"
|
||||||
|
".set push \n"
|
||||||
|
".set mips2 \n"
|
||||||
|
"ll %0,%3 \n"
|
||||||
|
"addu %1,%4,%0 \n"
|
||||||
|
"sc %1,%2 \n"
|
||||||
|
".set pop \n"
|
||||||
|
"beqz %1,1b \n"
|
||||||
|
: "=&r" (rv),
|
||||||
|
"=&r" (tmp),
|
||||||
|
"=m" (*atomic)
|
||||||
|
: "m" (*atomic),
|
||||||
|
"r" (value)
|
||||||
|
: "memory");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void
|
||||||
|
SDL_atomic_int_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
__asm__ __volatile__("1: \n"
|
||||||
|
".set push \n"
|
||||||
|
".set mips2 \n"
|
||||||
|
"ll %0,%2 \n"
|
||||||
|
"addu %0,%3,%0 \n"
|
||||||
|
"sc %0,%1 \n"
|
||||||
|
".set pop \n"
|
||||||
|
"beqz %0,1b \n"
|
||||||
|
: "=&r" (rv),
|
||||||
|
"=m" (*atomic)
|
||||||
|
: "m" (*atomic),
|
||||||
|
"r" (value)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
__asm__ __volatile__(" .set push \n"
|
||||||
|
" .set noat \n"
|
||||||
|
" .set mips3 \n"
|
||||||
|
"1: ll %0, %2 \n"
|
||||||
|
" bne %0, %z3, 2f \n"
|
||||||
|
" .set mips0 \n"
|
||||||
|
" move $1, %z4 \n"
|
||||||
|
" .set mips3 \n"
|
||||||
|
" sc $1, %1 \n"
|
||||||
|
" beqz $1, 1b \n"
|
||||||
|
" sync \n"
|
||||||
|
"2: \n"
|
||||||
|
" .set pop \n"
|
||||||
|
: "=&r" (rv),
|
||||||
|
"=R" (*atomic)
|
||||||
|
: "R" (*atomic),
|
||||||
|
"Jr" (oldvalue),
|
||||||
|
"Jr" (newvalue)
|
||||||
|
: "memory");
|
||||||
|
return (SDL_bool)rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
__asm__ __volatile__(" .set push \n"
|
||||||
|
" .set noat \n"
|
||||||
|
" .set mips3 \n"
|
||||||
|
# if defined(__mips64)
|
||||||
|
"1: lld %0, %2 \n"
|
||||||
|
# else
|
||||||
|
"1: ll %0, %2 \n"
|
||||||
|
# endif
|
||||||
|
" bne %0, %z3, 2f \n"
|
||||||
|
" move $1, %z4 \n"
|
||||||
|
# if defined(__mips64)
|
||||||
|
" sc $1, %1 \n"
|
||||||
|
# else
|
||||||
|
" scd $1, %1 \n"
|
||||||
|
# endif
|
||||||
|
" beqz $1, 1b \n"
|
||||||
|
" sync \n"
|
||||||
|
"2: \n"
|
||||||
|
" .set pop \n"
|
||||||
|
: "=&r" (rv),
|
||||||
|
"=R" (*atomic)
|
||||||
|
: "R" (*atomic),
|
||||||
|
"Jr" (oldvalue),
|
||||||
|
"Jr" (newvalue)
|
||||||
|
: "memory");
|
||||||
|
return (SDL_bool)rv;
|
||||||
|
}
|
||||||
|
#elif defined(__GNUC__) && defined(__m68k__)
|
||||||
|
static __inline__ int
|
||||||
|
SDL_atomic_int_xchg_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv = *atomic;
|
||||||
|
int tmp;
|
||||||
|
__asm__ __volatile__("1: move%.l %0,%1 \n"
|
||||||
|
" add%.l %2,%1 \n"
|
||||||
|
" cas%.l %0,%1,%3 \n"
|
||||||
|
" jbne 1b \n"
|
||||||
|
: "=d" (rv),
|
||||||
|
"=&d" (tmp)
|
||||||
|
: "d" (value),
|
||||||
|
"m" (*atomic),
|
||||||
|
"0" (rv)
|
||||||
|
: "memory");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void
|
||||||
|
SDL_atomic_int_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__("add%.l %0,%1"
|
||||||
|
:
|
||||||
|
: "id" (value),
|
||||||
|
"m" (*atomic)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
char rv;
|
||||||
|
int readvalue;
|
||||||
|
__asm__ __volatile__("cas%.l %2,%3,%1\n"
|
||||||
|
"seq %0"
|
||||||
|
: "=dm" (rv),
|
||||||
|
"=m" (*atomic),
|
||||||
|
"=d" (readvalue)
|
||||||
|
: "d" (newvalue),
|
||||||
|
"m" (*atomic),
|
||||||
|
"2" (oldvalue));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
char rv;
|
||||||
|
int readvalue;
|
||||||
|
__asm__ __volatile__("cas%.l %2,%3,%1\n"
|
||||||
|
"seq %0"
|
||||||
|
: "=dm" (rv),
|
||||||
|
"=m" (*atomic),
|
||||||
|
"=d" (readvalue)
|
||||||
|
: "d" (newvalue),
|
||||||
|
"m" (*atomic),
|
||||||
|
"2" (oldvalue));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#elif defined(__GNUC__) && defined(__s390__)
|
||||||
|
# define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue) \
|
||||||
|
({ \
|
||||||
|
int rv = oldvalue; \
|
||||||
|
__asm__ __volatile__("cs %0, %2, %1" \
|
||||||
|
: "+d" (rv), \
|
||||||
|
"=Q" (*(atomic)) \
|
||||||
|
: "d" (newvalue), \
|
||||||
|
"m" (*(atomic)) \
|
||||||
|
: "cc"); \
|
||||||
|
rv == oldvalue; \
|
||||||
|
})
|
||||||
|
# if (SIZEOF_VOIDP == 4)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
void* rv = oldvalue;
|
||||||
|
__asm__ __volatile__("cs %0, %2, %1"
|
||||||
|
: "+d" (rv),
|
||||||
|
"=Q" (*atomic)
|
||||||
|
: "d" (newvalue),
|
||||||
|
"m" (*atomic)
|
||||||
|
: "cc");
|
||||||
|
return (rv == oldvalue);
|
||||||
|
}
|
||||||
|
# elif (SIZEOF_VOIDP == 8)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
void* rv = oldvalue;
|
||||||
|
void** a = atomic;
|
||||||
|
__asm__ __volatile__("csg %0, %2, %1"
|
||||||
|
: "+d" (rv),
|
||||||
|
"=Q" (*a)
|
||||||
|
: "d" ((long)(newvalue)),
|
||||||
|
"m" (*a)
|
||||||
|
: "cc");
|
||||||
|
return (rv == oldvalue);
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# error "Your system has an unsupported pointer size"
|
||||||
|
# endif /* SIZEOF_VOIDP */
|
||||||
|
#elif defined(__WIN32__)
|
||||||
|
# include <windows.h>
|
||||||
|
static __inline__ int
|
||||||
|
SDL_atomic_int_xchg_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
return InterlockedExchangeAdd(atomic, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void
|
||||||
|
SDL_atomic_int_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
InterlockedExchangeAdd(atomic, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
# if (WINVER > 0X0400)
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atmoic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
return ((SDL_bool)InterlockedCompareExchangePointer((PVOID*)atomic,
|
||||||
|
(PVOID)newvalue,
|
||||||
|
(PVOID)oldvalue) == oldvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
return (InterlockedCompareExchangePointer(atomic, newvalue, oldvalue) == oldvalue);
|
||||||
|
}
|
||||||
|
# else /* WINVER <= 0x0400 */
|
||||||
|
# if (SIZEOF_VOIDP != 4)
|
||||||
|
# error "InterlockedCompareExchangePointer needed"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == oldvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
|
||||||
|
{
|
||||||
|
return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == oldvalue);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#else /* when all else fails */
|
||||||
|
# define SDL_ATOMIC_OPS_NOT_SUPPORTED
|
||||||
|
# warning "Atomic Ops for this platform not supported!"
|
||||||
|
static __inline__ int
|
||||||
|
SDL_atomic_int_xchg_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv = *atomic;
|
||||||
|
*(atomic) += value;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
return (*atomic == oldvalue) ?
|
||||||
|
((*atomic = newvalue), SDL_TRUE) : SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void
|
||||||
|
SDL_atomic_int_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
*atomic += value;
|
||||||
|
}
|
||||||
|
#endif /* arch & platforms */
|
||||||
|
|
||||||
|
#ifdef ATOMIC_INT_CMP_XCHG
|
||||||
|
static __inline__ SDL_bool
|
||||||
|
SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
|
||||||
|
{
|
||||||
|
return ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ int
|
||||||
|
SDL_atomic_int_xchg_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
do
|
||||||
|
rv = *atomic;
|
||||||
|
while(!ATOMIC_INT_CMP_XCHG(atomic,rv,rv+value));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void
|
||||||
|
SDL_atomic_int_add(volatile int* atomic, int value)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
do
|
||||||
|
rv = *atomic;
|
||||||
|
while(!ATOMIC_INT_CMP_XCHG(atomic,rv,rv+value));
|
||||||
|
}
|
||||||
|
#endif /* ATOMIC_CMP_XCHG */
|
||||||
|
|
||||||
|
#ifdef ATOMIC_MEMORY_BARRIER
|
||||||
|
# define SDL_atomic_int_get(atomic) \
|
||||||
|
(ATOMIC_MEMORY_BARRIER,*(atomic))
|
||||||
|
# define SDL_atomic_int_set(atomic,value) \
|
||||||
|
(*(atomic)=value,ATOMIC_MEMORY_BARRIER)
|
||||||
|
#else
|
||||||
|
# define SDL_atomic_int_get(atomic) (*(atomic))
|
||||||
|
# define SDL_atomic_int_set(atomic, newvalue) ((void)(*(atomic) = (newvalue)))
|
||||||
|
#endif /* MEMORY_BARRIER_NEEDED */
|
||||||
|
|
||||||
|
#define SDL_atomic_int_inc(atomic) (SDL_atomic_int_add((atomic),1))
|
||||||
|
#define SDL_atomic_int_dec_test(atomic) (SDL_atomic_int_xchg_add((atomic),-1) == 1)
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "close_code.h"
|
||||||
|
|
||||||
|
#endif /* _SDL_atomic_h_ */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -49,6 +49,7 @@
|
||||||
#undef int64_t
|
#undef int64_t
|
||||||
#undef uint64_t
|
#undef uint64_t
|
||||||
#undef uintptr_t
|
#undef uintptr_t
|
||||||
|
#undef SIZEOF_VOIDP
|
||||||
#undef SDL_HAS_64BIT_TYPE
|
#undef SDL_HAS_64BIT_TYPE
|
||||||
|
|
||||||
/* Endianness */
|
/* Endianness */
|
||||||
|
|
|
@ -36,6 +36,7 @@ typedef unsigned int uint32_t;
|
||||||
typedef signed long long int64_t;
|
typedef signed long long int64_t;
|
||||||
typedef unsigned long long uint64_t;
|
typedef unsigned long long uint64_t;
|
||||||
typedef unsigned long uintptr_t;
|
typedef unsigned long uintptr_t;
|
||||||
|
#define SIZEOF_VOIDP 4
|
||||||
#define SDL_HAS_64BIT_TYPE 1
|
#define SDL_HAS_64BIT_TYPE 1
|
||||||
|
|
||||||
/* Useful headers */
|
/* Useful headers */
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
/* This is a set of defines to configure the SDL features */
|
/* This is a set of defines to configure the SDL features */
|
||||||
|
|
||||||
|
#define SIZEOF_VOIDP 4
|
||||||
#define SDL_HAS_64BIT_TYPE 1
|
#define SDL_HAS_64BIT_TYPE 1
|
||||||
|
|
||||||
/* Useful headers */
|
/* Useful headers */
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef unsigned long uintptr_t;
|
||||||
typedef signed long long int64_t;
|
typedef signed long long int64_t;
|
||||||
typedef unsigned long long uint64_t;
|
typedef unsigned long long uint64_t;
|
||||||
|
|
||||||
|
#define SIZEOF_VOIDP 4
|
||||||
#define SDL_HAS_64BIT_TYPE 1
|
#define SDL_HAS_64BIT_TYPE 1
|
||||||
|
|
||||||
/* Use Watcom's LIBC */
|
/* Use Watcom's LIBC */
|
||||||
|
|
|
@ -68,6 +68,12 @@ typedef unsigned int size_t;
|
||||||
#endif
|
#endif
|
||||||
typedef unsigned int uintptr_t;
|
typedef unsigned int uintptr_t;
|
||||||
#endif /* __GNUC__ || _MSC_VER */
|
#endif /* __GNUC__ || _MSC_VER */
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
# define SIZEOF_VOIDP 8
|
||||||
|
#else
|
||||||
|
# define SIZEOF_VOIDP 4
|
||||||
|
#endif
|
||||||
#define SDL_HAS_64BIT_TYPE 1
|
#define SDL_HAS_64BIT_TYPE 1
|
||||||
|
|
||||||
/* Enabled for SDL 1.2 (binary compatibility) */
|
/* Enabled for SDL 1.2 (binary compatibility) */
|
||||||
|
|
|
@ -7,7 +7,7 @@ EXE = @EXE@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
LIBS = @LIBS@
|
LIBS = @LIBS@
|
||||||
|
|
||||||
TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE)
|
TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE) testatomic$(EXE)
|
||||||
|
|
||||||
all: Makefile $(TARGETS)
|
all: Makefile $(TARGETS)
|
||||||
|
|
||||||
|
@ -149,6 +149,9 @@ testhaptic$(EXE): $(srcdir)/testhaptic.c
|
||||||
testmmousetablet$(EXE): $(srcdir)/testmmousetablet.c
|
testmmousetablet$(EXE): $(srcdir)/testmmousetablet.c
|
||||||
$(CC) -o $@ $? $(CFLAGS) $(LIBS)
|
$(CC) -o $@ $? $(CFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
testatomic$(EXE): $(srcdir)/testatomic.c
|
||||||
|
$(CC) -o $@ $? $(CFLAGS) $(LIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGETS)
|
rm -f $(TARGETS)
|
||||||
|
|
||||||
|
|
64
test/testatomic.c
Normal file
64
test/testatomic.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rv = 10;
|
||||||
|
volatile int atomic;
|
||||||
|
|
||||||
|
SDL_atomic_int_set(&atomic, 10);
|
||||||
|
if(SDL_atomic_int_get(&atomic) != 10)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_set(atomic, 10): atomic-> %d\n",
|
||||||
|
SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
SDL_atomic_int_add(&atomic, 10);
|
||||||
|
if(SDL_atomic_int_get(&atomic) != 20)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_add(atomic, 10): atomic-> %d\n",
|
||||||
|
SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
rv = SDL_atomic_int_cmp_xchg(&atomic, 20, 30);
|
||||||
|
if(rv != SDL_TRUE || SDL_atomic_int_get(&atomic) != 30)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_cmp_xchg(atomic, 20, 30): rv-> %d, atomic-> %d\n",
|
||||||
|
rv, SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
rv = SDL_atomic_int_cmp_xchg(&atomic, 20, 30);
|
||||||
|
if(rv != SDL_FALSE || SDL_atomic_int_get(&atomic) != 30)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_cmp_xchg(atomic, 20, 40): rv-> %d, atomic-> %d\n",
|
||||||
|
rv, SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
rv = SDL_atomic_int_xchg_add(&atomic, 10);
|
||||||
|
if(rv != 30 || SDL_atomic_int_get(&atomic) != 40)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_xchg_add(atomic, 10): rv-> %d, atomic-> %d\n",
|
||||||
|
rv, SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
SDL_atomic_int_inc(&atomic);
|
||||||
|
if(SDL_atomic_int_get(&atomic) != 41)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_inc(atomic): atomic-> %d\n",
|
||||||
|
SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
rv = SDL_atomic_int_dec_test(&atomic);
|
||||||
|
if(rv != SDL_FALSE || SDL_atomic_int_get(&atomic) != 40)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_dec_test(atomic): rv-> %d, atomic-> %d\n",
|
||||||
|
rv, SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
SDL_atomic_int_set(&atomic, 1);
|
||||||
|
if(SDL_atomic_int_get(&atomic) != 1)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_set(atomic, 1): atomic-> %d\n",
|
||||||
|
SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
rv = SDL_atomic_int_dec_test(&atomic);
|
||||||
|
if(rv != SDL_TRUE || SDL_atomic_int_get(&atomic) != 0)
|
||||||
|
printf("Error: ");
|
||||||
|
printf("SDL_atomic_int_dec_test(atomic): rv-> %d, atomic-> %d\n",
|
||||||
|
rv, SDL_atomic_int_get(&atomic));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue