Commit dad8f050 authored by Bob Pendleton's avatar Bob Pendleton

I've made so many changes I don't dare continue until I check the current stuff in.

/test/testatomic.c performs absolutely basic tests to show that the function work as expected. Need a second test to do more detailed tests.

/include/SDL_atomic.h provides declarations for all included functions.

/src/atomic/linux/SDL_atomic.c provided all the functions. On a generic built the 64 bit functions work, but they are emulated. On a build for -march=pentium and above the 64 bit functions use native instructions
/src/atomic/dummy/SDL_atomic.c emulates all the operations using SDL_mutex.h.
/src/atomic/win32/SDL_atomic.c is a copy of dummy
/src/atomic/macosx/SDL_atomic.s is a copy of dummy

These versions of SDL_atomic.c provide a frame work for building the library with a mixture of native and emulated functions. This allows the whole library to be provided on all platforms. (I hope.)
I hope this fits with the SDL philosophy of either providing a common subset or emulating when the platform is missing a feature.

I have not added dummy, macosx, or win32 to the build. They are there as place holders for future work.

I have modified congifure.in to compile sources in /src/atomic/linux. (The SDL configure.in file is an amazing piece of work and I hope I didn't mess it up. :-)

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403671
parent 9b4d5550
......@@ -29,7 +29,6 @@
#ifndef _SDL_atomic_h_
#define _SDL_atomic_h_
#include "SDL_stdinc.h"
#include "SDL_platform.h"
......@@ -42,71 +41,50 @@ extern "C" {
/* *INDENT-ON* */
#endif
/* *INDENT-OFF* */
/**
* \def SDL_AtomicBusyWait32 (ptr)
*
* \brief Implements a simple busy wait for use with
* SDL_AtomicTestThenSet and SDL_AtomicClear.
*
* Note: This can be an infinite loop.
*
* These operations may, or may not, actually be implemented using
* processor specific atomic operations. When possible they are
* implemented as true processor specific atomic operations. When that
* is not possible the are implemented using locks that *do* use the
* available atomic operations. In rare cases they may be implemented
* using SDL's mutex fuctions.
*/
#define SDL_AtomicBusyWait32(ptr) \
{ \
while (!SDL_AtomicTestThenSet32(ptr) \
{ \
}; \
};
/**
* \def SDL_AtomicWait32(ptr)
*
* \brief A safer way to wait for a test-then-set lock to be cleared.
*
* This assumes that the SDL_Sleep(0) call acts as a thread_yeild
* operation.
*
*/
#define SDL_AtomicWait32(ptr) \
{ \
while (!SDL_AtomicTestThenSet32(ptr) \
{ \
SDL_Sleep(0); \
}; \
};
/* Function prototypes */
/**
* \def SDL_AtomicBusyWait64(ptr)
*
* \brief 64 bit version of busy wait
*
* \sa SDL_AtomicBusyWait32
*/
#define SDL_AtomicBusyWait64(ptr) \
{ \
while (!SDL_AtomicTestThenSet64(ptr) \
{ \
}; \
};
/* 8 bit atomic operations */
/**
* \def SDL_AtomicWait64(ptr)
*
* \brief 64 bit version of SDL_AtomicWait32
*
* \sa SDL_AtomicWait32
*/
#define SDL_AtomicWait64(ptr) \
{ \
while (!SDL_AtomicTestThenSet64(ptr) \
{ \
SDL_Sleep(0); \
}; \
};
/* *INDENT-ON* */
extern DECLSPEC Uint8 SDLCALL SDL_AtomicExchange8(Uint8 * ptr, Uint8 value);
extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCompareThenSet8(Uint8 * ptr,
Uint8 oldvalue, Uint8 newvalue);
extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTestThenSet8(Uint8 * ptr);
extern DECLSPEC void SDLCALL SDL_AtomicClear8(Uint8 * ptr);
extern DECLSPEC Uint8 SDLCALL SDL_AtomicFetchThenIncrement8(Uint8 * ptr);
extern DECLSPEC Uint8 SDLCALL SDL_AtomicFetchThenDecrement8(Uint8 * ptr);
extern DECLSPEC Uint8 SDLCALL SDL_AtomicFetchThenAdd8(Uint8 * ptr, Uint8 value);
extern DECLSPEC Uint8 SDLCALL SDL_AtomicFetchThenSubtract8(Uint8 * ptr, Uint8 value);
extern DECLSPEC Uint8 SDLCALL SDL_AtomicIncrementThenFetch8(Uint8 * ptr);
extern DECLSPEC Uint8 SDLCALL SDL_AtomicDecrementThenFetch8(Uint8 * ptr);
extern DECLSPEC Uint8 SDLCALL SDL_AtomicAddThenFetch8(Uint8 * ptr, Uint8 value);
extern DECLSPEC Uint8 SDLCALL SDL_AtomicSubtractThenFetch8(Uint8 * ptr, Uint8 value);
/* Function prototypes */
/* 16 bit atomic operations */
extern DECLSPEC Uint16 SDLCALL SDL_AtomicExchange16(Uint16 * ptr, Uint16 value);
extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCompareThenSet16(Uint16 * ptr,
Uint16 oldvalue, Uint16 newvalue);
extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTestThenSet16(Uint16 * ptr);
extern DECLSPEC void SDLCALL SDL_AtomicClear16(Uint16 * ptr);
extern DECLSPEC Uint16 SDLCALL SDL_AtomicFetchThenIncrement16(Uint16 * ptr);
extern DECLSPEC Uint16 SDLCALL SDL_AtomicFetchThenDecrement16(Uint16 * ptr);
extern DECLSPEC Uint16 SDLCALL SDL_AtomicFetchThenAdd16(Uint16 * ptr, Uint16 value);
extern DECLSPEC Uint16 SDLCALL SDL_AtomicFetchThenSubtract16(Uint16 * ptr, Uint16 value);
extern DECLSPEC Uint16 SDLCALL SDL_AtomicIncrementThenFetch16(Uint16 * ptr);
extern DECLSPEC Uint16 SDLCALL SDL_AtomicDecrementThenFetch16(Uint16 * ptr);
extern DECLSPEC Uint16 SDLCALL SDL_AtomicAddThenFetch16(Uint16 * ptr, Uint16 value);
extern DECLSPEC Uint16 SDLCALL SDL_AtomicSubtractThenFetch16(Uint16 * ptr, Uint16 value);
/* 32 bit atomic operations */
/**
* \fn int SDL_AtomicExchange32(Uint32 * ptr, Uint32 value)
......@@ -252,6 +230,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_AtomicAddThenFetch32(Uint32 * ptr, Uint32 val
*/
extern DECLSPEC Uint32 SDLCALL SDL_AtomicSubtractThenFetch32(Uint32 * ptr, Uint32 value);
/* 64 bit atomic operations */
#ifdef SDL_HAS_64BIT_TYPE
extern DECLSPEC Uint64 SDLCALL SDL_AtomicExchange64(Uint64 * ptr, Uint64 value);
......@@ -267,7 +246,7 @@ extern DECLSPEC Uint64 SDLCALL SDL_AtomicIncrementThenFetch64(Uint64 * ptr);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicDecrementThenFetch64(Uint64 * ptr);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicAddThenFetch64(Uint64 * ptr, Uint64 value);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicSubtractThenFetch64(Uint64 * ptr, Uint64 value);
#endif
#endif /* SDL_HAS_64BIT_TYPE */
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include "SDL.h"
/*
Absolutely basic test just to see if we get the expected value after
calling each function.
Absolutely basic tests just to see if we get the expected value
after calling each function.
*/
char *
tf(SDL_bool tf)
{
static char *t = "true";
static char *f = "false";
if (tf)
{
return t;
}
return f;
}
int
main(int argc, char **argv)
{
Uint8 val8 = 0;
Uint8 ret8 = 0;
Uint16 val16 = 0;
Uint16 ret16 = 0;
Uint32 val32 = 0;
Uint32 ret32 = 0;
Uint64 val64 = 0;
Uint64 ret64 = 0;
SDL_bool tfval = SDL_FALSE;
SDL_bool tfret = SDL_FALSE;
printf("8 bit -----------------------------------------\n\n");
ret8 = SDL_AtomicExchange8(&val8, 10);
printf("Exchange8 ret=%d val=%d\n", ret8, val8);
ret8 = SDL_AtomicExchange8(&val8, 0);
printf("Exchange8 ret=%d val=%d\n", ret8, val8);
val8 = 10;
tfret = SDL_AtomicCompareThenSet8(&val8, 10, 20);
printf("CompareThenSet8 tfret=%s val=%d\n", tf(tfret), val8);
val8 = 10;
tfret = SDL_AtomicCompareThenSet8(&val8, 0, 20);
printf("CompareThenSet8 tfret=%s val=%d\n", tf(tfret), val8);
val8 = 0;
tfret = SDL_AtomicTestThenSet8(&val8);
printf("TestThenSet8 tfret=%s val=%d\n", tf(tfret), val8);
tfret = SDL_AtomicTestThenSet8(&val8);
printf("TestThenSet8 tfret=%s val=%d\n", tf(tfret), val8);
SDL_AtomicClear8(&val8);
printf("Clear8 val=%d\n", val8);
ret8 = SDL_AtomicFetchThenIncrement8(&val8);
printf("FetchThenIncrement8 ret=%d val=%d\n", ret8, val8);
ret8 = SDL_AtomicFetchThenDecrement8(&val8);
printf("FetchThenDecrement8 ret=%d val=%d\n", ret8, val8);
ret8 = SDL_AtomicFetchThenAdd8(&val8, 10);
printf("FetchThenAdd8 ret=%d val=%d\n", ret8, val8);
ret8 = SDL_AtomicFetchThenSubtract8(&val8, 10);
printf("FetchThenSubtract8 ret=%d val=%d\n", ret8, val8);
ret8 = SDL_AtomicIncrementThenFetch8(&val8);
printf("IncrementThenFetch8 ret=%d val=%d\n", ret8, val8);
ret8 = SDL_AtomicDecrementThenFetch8(&val8);
printf("DecrementThenFetch8 ret=%d val=%d\n", ret8, val8);
ret8 = SDL_AtomicAddThenFetch8(&val8, 10);
printf("AddThenFetch8 ret=%d val=%d\n", ret8, val8);
ret8 = SDL_AtomicSubtractThenFetch8(&val8, 10);
printf("SubtractThenFetch8 ret=%d val=%d\n", ret8, val8);
printf("16 bit -----------------------------------------\n\n");
ret16 = SDL_AtomicExchange16(&val16, 10);
printf("Exchange16 ret=%d val=%d\n", ret16, val16);
ret16 = SDL_AtomicExchange16(&val16, 0);
printf("Exchange16 ret=%d val=%d\n", ret16, val16);
val16 = 10;
tfret = SDL_AtomicCompareThenSet16(&val16, 10, 20);
printf("CompareThenSet16 tfret=%s val=%d\n", tf(tfret), val16);
val16 = 10;
tfret = SDL_AtomicCompareThenSet16(&val16, 0, 20);
printf("CompareThenSet16 tfret=%s val=%d\n", tf(tfret), val16);
val16 = 0;
tfret = SDL_AtomicTestThenSet16(&val16);
printf("TestThenSet16 tfret=%s val=%d\n", tf(tfret), val16);
tfret = SDL_AtomicTestThenSet16(&val16);
printf("TestThenSet16 tfret=%s val=%d\n", tf(tfret), val16);
SDL_AtomicClear16(&val16);
printf("Clear16 val=%d\n", val16);
ret16 = SDL_AtomicFetchThenIncrement16(&val16);
printf("FetchThenIncrement16 ret=%d val=%d\n", ret16, val16);
ret16 = SDL_AtomicFetchThenDecrement16(&val16);
printf("FetchThenDecrement16 ret=%d val=%d\n", ret16, val16);
ret16 = SDL_AtomicFetchThenAdd16(&val16, 10);
printf("FetchThenAdd16 ret=%d val=%d\n", ret16, val16);
ret16 = SDL_AtomicFetchThenSubtract16(&val16, 10);
printf("FetchThenSubtract16 ret=%d val=%d\n", ret16, val16);
ret16 = SDL_AtomicIncrementThenFetch16(&val16);
printf("IncrementThenFetch16 ret=%d val=%d\n", ret16, val16);
ret16 = SDL_AtomicDecrementThenFetch16(&val16);
printf("DecrementThenFetch16 ret=%d val=%d\n", ret16, val16);
ret16 = SDL_AtomicAddThenFetch16(&val16, 10);
printf("AddThenFetch16 ret=%d val=%d\n", ret16, val16);
ret16 = SDL_AtomicSubtractThenFetch16(&val16, 10);
printf("SubtractThenFetch16 ret=%d val=%d\n", ret16, val16);
printf("32 bit -----------------------------------------\n\n");
ret32 = SDL_AtomicExchange32(&val32, 10);
tfval = SDL_AtomicCompareThenSet32(&val32, 10, 20);
tfval = SDL_AtomicTestThenSet32(&val32);
printf("Exchange32 ret=%d val=%d\n", ret32, val32);
ret32 = SDL_AtomicExchange32(&val32, 0);
printf("Exchange32 ret=%d val=%d\n", ret32, val32);
val32 = 10;
tfret = SDL_AtomicCompareThenSet32(&val32, 10, 20);
printf("CompareThenSet32 tfret=%s val=%d\n", tf(tfret), val32);
val32 = 10;
tfret = SDL_AtomicCompareThenSet32(&val32, 0, 20);
printf("CompareThenSet32 tfret=%s val=%d\n", tf(tfret), val32);
val32 = 0;
tfret = SDL_AtomicTestThenSet32(&val32);
printf("TestThenSet32 tfret=%s val=%d\n", tf(tfret), val32);
tfret = SDL_AtomicTestThenSet32(&val32);
printf("TestThenSet32 tfret=%s val=%d\n", tf(tfret), val32);
SDL_AtomicClear32(&val32);
printf("Clear32 val=%d\n", val32);
ret32 = SDL_AtomicFetchThenIncrement32(&val32);
printf("FetchThenIncrement32 ret=%d val=%d\n", ret32, val32);
ret32 = SDL_AtomicFetchThenDecrement32(&val32);
printf("FetchThenDecrement32 ret=%d val=%d\n", ret32, val32);
ret32 = SDL_AtomicFetchThenAdd32(&val32, 10);
printf("FetchThenAdd32 ret=%d val=%d\n", ret32, val32);
ret32 = SDL_AtomicFetchThenSubtract32(&val32, 10);
printf("FetchThenSubtract32 ret=%d val=%d\n", ret32, val32);
ret32 = SDL_AtomicIncrementThenFetch32(&val32);
printf("IncrementThenFetch32 ret=%d val=%d\n", ret32, val32);
ret32 = SDL_AtomicDecrementThenFetch32(&val32);
printf("DecrementThenFetch32 ret=%d val=%d\n", ret32, val32);
ret32 = SDL_AtomicAddThenFetch32(&val32, 10);
printf("AddThenFetch32 ret=%d val=%d\n", ret32, val32);
ret32 = SDL_AtomicSubtractThenFetch32(&val32, 10);
printf("SubtractThenFetch32 ret=%d val=%d\n", ret32, val32);
/* #ifdef SDL_HAS_64BIT_TYPE */
#if 0
#ifdef SDL_HAS_64BIT_TYPE
printf("64 bit -----------------------------------------\n\n");
ret64 = SDL_AtomicExchange64(&val64, 10);
tfval = SDL_AtomicCompareThenSet64(&val64, 10, 20);
tfval = SDL_AtomicTestThenSet64(&val64);
printf("Exchange64 ret=%lld val=%lld\n", ret64, val64);
ret64 = SDL_AtomicExchange64(&val64, 0);
printf("Exchange64 ret=%lld val=%lld\n", ret64, val64);
val64 = 10;
tfret = SDL_AtomicCompareThenSet64(&val64, 10, 20);
printf("CompareThenSet64 tfret=%s val=%lld\n", tf(tfret), val64);
val64 = 10;
tfret = SDL_AtomicCompareThenSet64(&val64, 0, 20);
printf("CompareThenSet64 tfret=%s val=%lld\n", tf(tfret), val64);
val64 = 0;
tfret = SDL_AtomicTestThenSet64(&val64);
printf("TestThenSet64 tfret=%s val=%lld\n", tf(tfret), val64);
tfret = SDL_AtomicTestThenSet64(&val64);
printf("TestThenSet64 tfret=%s val=%lld\n", tf(tfret), val64);
SDL_AtomicClear64(&val64);
printf("Clear64 val=%lld\n", val64);
ret64 = SDL_AtomicFetchThenIncrement64(&val64);
printf("FetchThenIncrement64 ret=%lld val=%lld\n", ret64, val64);
ret64 = SDL_AtomicFetchThenDecrement64(&val64);
printf("FetchThenDecrement64 ret=%lld val=%lld\n", ret64, val64);
ret64 = SDL_AtomicFetchThenAdd64(&val64, 10);
printf("FetchThenAdd64 ret=%lld val=%lld\n", ret64, val64);
ret64 = SDL_AtomicFetchThenSubtract64(&val64, 10);
printf("FetchThenSubtract64 ret=%lld val=%lld\n", ret64, val64);
ret64 = SDL_AtomicIncrementThenFetch64(&val64);
printf("IncrementThenFetch64 ret=%lld val=%lld\n", ret64, val64);
ret64 = SDL_AtomicDecrementThenFetch64(&val64);
printf("DecrementThenFetch64 ret=%lld val=%lld\n", ret64, val64);
ret64 = SDL_AtomicAddThenFetch64(&val64, 10);
printf("AddThenFetch64 ret=%lld val=%lld\n", ret64, val64);
ret64 = SDL_AtomicSubtractThenFetch64(&val64, 10);
printf("SubtractThenFetch64 ret=%lld val=%lld\n", ret64, val64);
#endif
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment