Commit 1bc8fe69 authored by Sam Lantinga's avatar Sam Lantinga

Updated the atomic API for better use cases

parent 40844381
...@@ -16,6 +16,8 @@ LOCAL_SRC_FILES := src/SDL_android.cpp \ ...@@ -16,6 +16,8 @@ LOCAL_SRC_FILES := src/SDL_android.cpp \
$(subst $(LOCAL_PATH)/,, \ $(subst $(LOCAL_PATH)/,, \
$(wildcard $(LOCAL_PATH)/src/*.c) \ $(wildcard $(LOCAL_PATH)/src/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/*.c) \ $(wildcard $(LOCAL_PATH)/src/audio/*.c) \
$(LOCAL_PATH)/src/atomic/SDL_atomic.c \
$(LOCAL_PATH)/src/atomic/SDL_spinlock.c.arm \
$(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \ $(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \
$(wildcard $(LOCAL_PATH)/src/events/*.c) \ $(wildcard $(LOCAL_PATH)/src/events/*.c) \
$(wildcard $(LOCAL_PATH)/src/file/*.c) \ $(wildcard $(LOCAL_PATH)/src/file/*.c) \
...@@ -31,7 +33,6 @@ LOCAL_SRC_FILES := src/SDL_android.cpp \ ...@@ -31,7 +33,6 @@ LOCAL_SRC_FILES := src/SDL_android.cpp \
$(wildcard $(LOCAL_PATH)/src/video/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/video/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \ $(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
$(wildcard $(LOCAL_PATH)/src/atomic/dummy/*.c) \
$(wildcard $(LOCAL_PATH)/src/thread/pthread/*.c) \ $(wildcard $(LOCAL_PATH)/src/thread/pthread/*.c) \
$(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \ $(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \
$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c)) $(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c))
......
...@@ -644,7 +644,11 @@ ...@@ -644,7 +644,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\atomic\win32\SDL_atomic.c" RelativePath="..\..\src\atomic\SDL_atomic.c"
>
</File>
<File
RelativePath="..\..\src\atomic\SDL_spinlock.c"
> >
</File> </File>
<File <File
......
...@@ -631,7 +631,11 @@ ...@@ -631,7 +631,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\atomic\win32\SDL_atomic.c" RelativePath="..\..\src\atomic\SDL_atomic.c"
>
</File>
<File
RelativePath="..\..\src\atomic\SDL_spinlock.c"
> >
</File> </File>
<File <File
......
...@@ -365,7 +365,8 @@ echo #define SDL_REVISION 0 &gt;"$(ProjectDir)\..\..\include\SDL_revision.h" ...@@ -365,7 +365,8 @@ echo #define SDL_REVISION 0 &gt;"$(ProjectDir)\..\..\include\SDL_revision.h"
<ClCompile Include="..\..\src\SDL.c" /> <ClCompile Include="..\..\src\SDL.c" />
<ClCompile Include="..\..\src\video\SDL_alphamult.c" /> <ClCompile Include="..\..\src\video\SDL_alphamult.c" />
<ClCompile Include="..\..\src\SDL_assert.c" /> <ClCompile Include="..\..\src\SDL_assert.c" />
<ClCompile Include="..\..\src\atomic\win32\SDL_atomic.c" /> <ClCompile Include="..\..\src\atomic\SDL_atomic.c" />
<ClCompile Include="..\..\src\atomic\SDL_spinlock.c" />
<ClCompile Include="..\..\src\audio\SDL_audio.c" /> <ClCompile Include="..\..\src\audio\SDL_audio.c" />
<ClCompile Include="..\..\src\audio\SDL_audiocvt.c" /> <ClCompile Include="..\..\src\audio\SDL_audiocvt.c" />
<ClCompile Include="..\..\src\audio\SDL_audiodev.c" /> <ClCompile Include="..\..\src\audio\SDL_audiodev.c" />
......
...@@ -93,7 +93,6 @@ ...@@ -93,7 +93,6 @@
04B2ECEC1025CE4800F9BC5F /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ECE61025CE4800F9BC5F /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; 04B2ECEC1025CE4800F9BC5F /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ECE61025CE4800F9BC5F /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; };
04B2ECED1025CE4800F9BC5F /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ECE71025CE4800F9BC5F /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; 04B2ECED1025CE4800F9BC5F /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ECE71025CE4800F9BC5F /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; };
04B2ECEE1025CE4800F9BC5F /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ECE81025CE4800F9BC5F /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; 04B2ECEE1025CE4800F9BC5F /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ECE81025CE4800F9BC5F /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; };
04B2ECFF1025CEB900F9BC5F /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04B2ECF11025CEB900F9BC5F /* SDL_atomic.c */; };
04B2ED081025CF9E00F9BC5F /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ED061025CF9E00F9BC5F /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; 04B2ED081025CF9E00F9BC5F /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B2ED061025CF9E00F9BC5F /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; };
04BA9D6311EF474A00B60E01 /* SDL_gesture_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BA9D5F11EF474A00B60E01 /* SDL_gesture_c.h */; }; 04BA9D6311EF474A00B60E01 /* SDL_gesture_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BA9D5F11EF474A00B60E01 /* SDL_gesture_c.h */; };
04BA9D6411EF474A00B60E01 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BA9D6011EF474A00B60E01 /* SDL_gesture.c */; }; 04BA9D6411EF474A00B60E01 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BA9D6011EF474A00B60E01 /* SDL_gesture.c */; };
...@@ -104,6 +103,11 @@ ...@@ -104,6 +103,11 @@
04EC8B521025D12900431D42 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = 04EC8B501025D12900431D42 /* SDL_config_iphoneos.h */; }; 04EC8B521025D12900431D42 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = 04EC8B501025D12900431D42 /* SDL_config_iphoneos.h */; };
04F2AF541104ABC300D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF531104ABC300D6DDF7 /* SDL_assert.h */; }; 04F2AF541104ABC300D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF531104ABC300D6DDF7 /* SDL_assert.h */; };
04F2AF561104ABD200D6DDF7 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F2AF551104ABD200D6DDF7 /* SDL_assert.c */; }; 04F2AF561104ABD200D6DDF7 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F2AF551104ABD200D6DDF7 /* SDL_assert.c */; };
04FFAB8B12E23B8D00BA343D /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */; };
04FFAB8C12E23B8D00BA343D /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */; };
04FFAB9612E23BDC00BA343D /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = 04FFAB9312E23BDC00BA343D /* SDL_blendmode.h */; };
04FFAB9712E23BDC00BA343D /* SDL_scalemode.h in Headers */ = {isa = PBXBuildFile; fileRef = 04FFAB9412E23BDC00BA343D /* SDL_scalemode.h */; };
04FFAB9812E23BDC00BA343D /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = 04FFAB9512E23BDC00BA343D /* SDL_shape.h */; };
56ED04E1118A8EE200A56AA6 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E0118A8EE200A56AA6 /* SDL_power.c */; }; 56ED04E1118A8EE200A56AA6 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E0118A8EE200A56AA6 /* SDL_power.c */; };
56ED04E3118A8EFD00A56AA6 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */; }; 56ED04E3118A8EFD00A56AA6 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */; };
FD24846D0E5655AE0021E198 /* SDL_uikitkeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = FD24846B0E5655AE0021E198 /* SDL_uikitkeyboard.h */; }; FD24846D0E5655AE0021E198 /* SDL_uikitkeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = FD24846B0E5655AE0021E198 /* SDL_uikitkeyboard.h */; };
...@@ -350,7 +354,6 @@ ...@@ -350,7 +354,6 @@
04B2ECE61025CE4800F9BC5F /* SDL_atomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_atomic.h; path = ../../include/SDL_atomic.h; sourceTree = SOURCE_ROOT; }; 04B2ECE61025CE4800F9BC5F /* SDL_atomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_atomic.h; path = ../../include/SDL_atomic.h; sourceTree = SOURCE_ROOT; };
04B2ECE71025CE4800F9BC5F /* SDL_power.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_power.h; path = ../../include/SDL_power.h; sourceTree = SOURCE_ROOT; }; 04B2ECE71025CE4800F9BC5F /* SDL_power.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_power.h; path = ../../include/SDL_power.h; sourceTree = SOURCE_ROOT; };
04B2ECE81025CE4800F9BC5F /* SDL_revision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_revision.h; path = ../../include/SDL_revision.h; sourceTree = SOURCE_ROOT; }; 04B2ECE81025CE4800F9BC5F /* SDL_revision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_revision.h; path = ../../include/SDL_revision.h; sourceTree = SOURCE_ROOT; };
04B2ECF11025CEB900F9BC5F /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = "<group>"; };
04B2ED061025CF9E00F9BC5F /* SDL_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_config.h; path = ../../include/SDL_config.h; sourceTree = SOURCE_ROOT; }; 04B2ED061025CF9E00F9BC5F /* SDL_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_config.h; path = ../../include/SDL_config.h; sourceTree = SOURCE_ROOT; };
04BA9D5F11EF474A00B60E01 /* SDL_gesture_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gesture_c.h; sourceTree = "<group>"; }; 04BA9D5F11EF474A00B60E01 /* SDL_gesture_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gesture_c.h; sourceTree = "<group>"; };
04BA9D6011EF474A00B60E01 /* SDL_gesture.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gesture.c; sourceTree = "<group>"; }; 04BA9D6011EF474A00B60E01 /* SDL_gesture.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gesture.c; sourceTree = "<group>"; };
...@@ -361,6 +364,11 @@ ...@@ -361,6 +364,11 @@
04EC8B501025D12900431D42 /* SDL_config_iphoneos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_config_iphoneos.h; path = ../../include/SDL_config_iphoneos.h; sourceTree = SOURCE_ROOT; }; 04EC8B501025D12900431D42 /* SDL_config_iphoneos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_config_iphoneos.h; path = ../../include/SDL_config_iphoneos.h; sourceTree = SOURCE_ROOT; };
04F2AF531104ABC300D6DDF7 /* SDL_assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_assert.h; path = ../../include/SDL_assert.h; sourceTree = SOURCE_ROOT; }; 04F2AF531104ABC300D6DDF7 /* SDL_assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_assert.h; path = ../../include/SDL_assert.h; sourceTree = SOURCE_ROOT; };
04F2AF551104ABD200D6DDF7 /* SDL_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_assert.c; path = ../../src/SDL_assert.c; sourceTree = SOURCE_ROOT; }; 04F2AF551104ABD200D6DDF7 /* SDL_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_assert.c; path = ../../src/SDL_assert.c; sourceTree = SOURCE_ROOT; };
04FFAB8912E23B8D00BA343D /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = "<group>"; };
04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_spinlock.c; sourceTree = "<group>"; };
04FFAB9312E23BDC00BA343D /* SDL_blendmode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_blendmode.h; path = ../../include/SDL_blendmode.h; sourceTree = SOURCE_ROOT; };
04FFAB9412E23BDC00BA343D /* SDL_scalemode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_scalemode.h; path = ../../include/SDL_scalemode.h; sourceTree = SOURCE_ROOT; };
04FFAB9512E23BDC00BA343D /* SDL_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_shape.h; path = ../../include/SDL_shape.h; sourceTree = SOURCE_ROOT; };
56ED04E0118A8EE200A56AA6 /* SDL_power.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_power.c; path = ../../src/power/SDL_power.c; sourceTree = SOURCE_ROOT; }; 56ED04E0118A8EE200A56AA6 /* SDL_power.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_power.c; path = ../../src/power/SDL_power.c; sourceTree = SOURCE_ROOT; };
56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_syspower.m; path = ../../src/power/uikit/SDL_syspower.m; sourceTree = SOURCE_ROOT; }; 56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_syspower.m; path = ../../src/power/uikit/SDL_syspower.m; sourceTree = SOURCE_ROOT; };
FD0BBFEF0E3933DD00D833B1 /* SDL_uikitview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitview.h; sourceTree = "<group>"; }; FD0BBFEF0E3933DD00D833B1 /* SDL_uikitview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitview.h; sourceTree = "<group>"; };
...@@ -690,20 +698,13 @@ ...@@ -690,20 +698,13 @@
04B2ECEF1025CEB900F9BC5F /* atomic */ = { 04B2ECEF1025CEB900F9BC5F /* atomic */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04B2ECF01025CEB900F9BC5F /* dummy */, 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */,
04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */,
); );
name = atomic; name = atomic;
path = ../../src/atomic; path = ../../src/atomic;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
04B2ECF01025CEB900F9BC5F /* dummy */ = {
isa = PBXGroup;
children = (
04B2ECF11025CEB900F9BC5F /* SDL_atomic.c */,
);
path = dummy;
sourceTree = "<group>";
};
19C28FACFE9D520D11CA2CBB /* Products */ = { 19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -848,6 +849,9 @@ ...@@ -848,6 +849,9 @@
FD99B8BC0DD52E5C00FB1D6B /* Public Headers */ = { FD99B8BC0DD52E5C00FB1D6B /* Public Headers */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04FFAB9312E23BDC00BA343D /* SDL_blendmode.h */,
04FFAB9412E23BDC00BA343D /* SDL_scalemode.h */,
04FFAB9512E23BDC00BA343D /* SDL_shape.h */,
FD99B8CC0DD52EB400FB1D6B /* begin_code.h */, FD99B8CC0DD52EB400FB1D6B /* begin_code.h */,
FD99B8CD0DD52EB400FB1D6B /* close_code.h */, FD99B8CD0DD52EB400FB1D6B /* close_code.h */,
FD99B8F50DD52EB400FB1D6B /* SDL.h */, FD99B8F50DD52EB400FB1D6B /* SDL.h */,
...@@ -1213,6 +1217,9 @@ ...@@ -1213,6 +1217,9 @@
04BA9D6511EF474A00B60E01 /* SDL_touch_c.h in Headers */, 04BA9D6511EF474A00B60E01 /* SDL_touch_c.h in Headers */,
04BA9D7D11EF497E00B60E01 /* SDL_gesture.h in Headers */, 04BA9D7D11EF497E00B60E01 /* SDL_gesture.h in Headers */,
04BA9D7E11EF497E00B60E01 /* SDL_touch.h in Headers */, 04BA9D7E11EF497E00B60E01 /* SDL_touch.h in Headers */,
04FFAB9612E23BDC00BA343D /* SDL_blendmode.h in Headers */,
04FFAB9712E23BDC00BA343D /* SDL_scalemode.h in Headers */,
04FFAB9812E23BDC00BA343D /* SDL_shape.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -1262,7 +1269,14 @@ ...@@ -1262,7 +1269,14 @@
isa = PBXProject; isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SDLiPhoneOS" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SDLiPhoneOS" */;
compatibilityVersion = "Xcode 3.1"; compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = ""; projectDirPath = "";
projectRoot = ../..; projectRoot = ../..;
...@@ -1443,7 +1457,6 @@ ...@@ -1443,7 +1457,6 @@
046387440F0B5B7D0041FD65 /* SDL_drawline.c in Sources */, 046387440F0B5B7D0041FD65 /* SDL_drawline.c in Sources */,
046387450F0B5B7D0041FD65 /* SDL_drawpoint.c in Sources */, 046387450F0B5B7D0041FD65 /* SDL_drawpoint.c in Sources */,
046387460F0B5B7D0041FD65 /* SDL_fillrect.c in Sources */, 046387460F0B5B7D0041FD65 /* SDL_fillrect.c in Sources */,
04B2ECFF1025CEB900F9BC5F /* SDL_atomic.c in Sources */,
043DD76F10FD8A0000DED673 /* SDL_alphamult.c in Sources */, 043DD76F10FD8A0000DED673 /* SDL_alphamult.c in Sources */,
043DD77110FD8A0000DED673 /* SDL_blendfillrect.c in Sources */, 043DD77110FD8A0000DED673 /* SDL_blendfillrect.c in Sources */,
043DD77210FD8A0000DED673 /* SDL_drawrect.c in Sources */, 043DD77210FD8A0000DED673 /* SDL_drawrect.c in Sources */,
...@@ -1455,6 +1468,8 @@ ...@@ -1455,6 +1468,8 @@
0420497111E6F03D007E7EC9 /* SDL_clipboardevents.c in Sources */, 0420497111E6F03D007E7EC9 /* SDL_clipboardevents.c in Sources */,
04BA9D6411EF474A00B60E01 /* SDL_gesture.c in Sources */, 04BA9D6411EF474A00B60E01 /* SDL_gesture.c in Sources */,
04BA9D6611EF474A00B60E01 /* SDL_touch.c in Sources */, 04BA9D6611EF474A00B60E01 /* SDL_touch.c in Sources */,
04FFAB8B12E23B8D00BA343D /* SDL_atomic.c in Sources */,
04FFAB8C12E23B8D00BA343D /* SDL_spinlock.c in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
......
...@@ -150,8 +150,6 @@ ...@@ -150,8 +150,6 @@
00CFA68F106B44CE00758660 /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA67F106B44CE00758660 /* SDL_rect.h */; }; 00CFA68F106B44CE00758660 /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA67F106B44CE00758660 /* SDL_rect.h */; };
00CFA690106B44CE00758660 /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA680106B44CE00758660 /* SDL_scancode.h */; }; 00CFA690106B44CE00758660 /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA680106B44CE00758660 /* SDL_scancode.h */; };
00CFA691106B44CE00758660 /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA681106B44CE00758660 /* SDL_surface.h */; }; 00CFA691106B44CE00758660 /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA681106B44CE00758660 /* SDL_surface.h */; };
00CFA6A8106B467B00758660 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 00CFA6A1106B467B00758660 /* SDL_atomic.c */; };
00CFA6AD106B467B00758660 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 00CFA6A1106B467B00758660 /* SDL_atomic.c */; };
00CFA6B6106B46E500758660 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA6B0106B46E500758660 /* SDL_audio_c.h */; }; 00CFA6B6106B46E500758660 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA6B0106B46E500758660 /* SDL_audio_c.h */; };
00CFA6B7106B46E500758660 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA6B1106B46E500758660 /* SDL_audiodev_c.h */; }; 00CFA6B7106B46E500758660 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA6B1106B46E500758660 /* SDL_audiodev_c.h */; };
00CFA6B8106B46E500758660 /* SDL_audiomem.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA6B2106B46E500758660 /* SDL_audiomem.h */; }; 00CFA6B8106B46E500758660 /* SDL_audiomem.h in Headers */ = {isa = PBXBuildFile; fileRef = 00CFA6B2106B46E500758660 /* SDL_audiomem.h */; };
...@@ -480,6 +478,10 @@ ...@@ -480,6 +478,10 @@
04F2AF671104AC0800D6DDF7 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F2AF651104AC0800D6DDF7 /* SDL_assert.c */; }; 04F2AF671104AC0800D6DDF7 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F2AF651104AC0800D6DDF7 /* SDL_assert.c */; };
04F2AF691104AC4500D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF681104AC4500D6DDF7 /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; }; 04F2AF691104AC4500D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF681104AC4500D6DDF7 /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; };
04F2AF6A1104AC4500D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF681104AC4500D6DDF7 /* SDL_assert.h */; }; 04F2AF6A1104AC4500D6DDF7 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F2AF681104AC4500D6DDF7 /* SDL_assert.h */; };
04FB7D4C12E2350700A522C6 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FB7D4A12E2350700A522C6 /* SDL_atomic.c */; };
04FB7D4D12E2350700A522C6 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FB7D4B12E2350700A522C6 /* SDL_spinlock.c */; };
04FB7D4E12E2350700A522C6 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FB7D4A12E2350700A522C6 /* SDL_atomic.c */; };
04FB7D4F12E2350700A522C6 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FB7D4B12E2350700A522C6 /* SDL_spinlock.c */; };
4537737D1207C4CE002F0F45 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4537737B1207C4CE002F0F45 /* SDL_shape_internals.h */; }; 4537737D1207C4CE002F0F45 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4537737B1207C4CE002F0F45 /* SDL_shape_internals.h */; };
4537737E1207C4CE002F0F45 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = 4537737C1207C4CE002F0F45 /* SDL_shape.c */; }; 4537737E1207C4CE002F0F45 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = 4537737C1207C4CE002F0F45 /* SDL_shape.c */; };
453773821207C518002F0F45 /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = 453773811207C518002F0F45 /* SDL_shape.h */; }; 453773821207C518002F0F45 /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = 453773811207C518002F0F45 /* SDL_shape.h */; };
...@@ -656,7 +658,6 @@ ...@@ -656,7 +658,6 @@
00CFA67F106B44CE00758660 /* SDL_rect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_rect.h; path = ../../include/SDL_rect.h; sourceTree = SOURCE_ROOT; }; 00CFA67F106B44CE00758660 /* SDL_rect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_rect.h; path = ../../include/SDL_rect.h; sourceTree = SOURCE_ROOT; };
00CFA680106B44CE00758660 /* SDL_scancode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_scancode.h; path = ../../include/SDL_scancode.h; sourceTree = SOURCE_ROOT; }; 00CFA680106B44CE00758660 /* SDL_scancode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_scancode.h; path = ../../include/SDL_scancode.h; sourceTree = SOURCE_ROOT; };
00CFA681106B44CE00758660 /* SDL_surface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_surface.h; path = ../../include/SDL_surface.h; sourceTree = SOURCE_ROOT; }; 00CFA681106B44CE00758660 /* SDL_surface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_surface.h; path = ../../include/SDL_surface.h; sourceTree = SOURCE_ROOT; };
00CFA6A1106B467B00758660 /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = "<group>"; };
00CFA6B0106B46E500758660 /* SDL_audio_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audio_c.h; sourceTree = "<group>"; }; 00CFA6B0106B46E500758660 /* SDL_audio_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audio_c.h; sourceTree = "<group>"; };
00CFA6B1106B46E500758660 /* SDL_audiodev_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiodev_c.h; sourceTree = "<group>"; }; 00CFA6B1106B46E500758660 /* SDL_audiodev_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiodev_c.h; sourceTree = "<group>"; };
00CFA6B2106B46E500758660 /* SDL_audiomem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiomem.h; sourceTree = "<group>"; }; 00CFA6B2106B46E500758660 /* SDL_audiomem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiomem.h; sourceTree = "<group>"; };
...@@ -861,6 +862,8 @@ ...@@ -861,6 +862,8 @@
04DEA57811E600A600386CAC /* SDL_cocoaclipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoaclipboard.m; sourceTree = "<group>"; }; 04DEA57811E600A600386CAC /* SDL_cocoaclipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoaclipboard.m; sourceTree = "<group>"; };
04F2AF651104AC0800D6DDF7 /* SDL_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_assert.c; path = ../../src/SDL_assert.c; sourceTree = SOURCE_ROOT; }; 04F2AF651104AC0800D6DDF7 /* SDL_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_assert.c; path = ../../src/SDL_assert.c; sourceTree = SOURCE_ROOT; };
04F2AF681104AC4500D6DDF7 /* SDL_assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_assert.h; path = ../../include/SDL_assert.h; sourceTree = SOURCE_ROOT; }; 04F2AF681104AC4500D6DDF7 /* SDL_assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_assert.h; path = ../../include/SDL_assert.h; sourceTree = SOURCE_ROOT; };
04FB7D4A12E2350700A522C6 /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = "<group>"; };
04FB7D4B12E2350700A522C6 /* SDL_spinlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_spinlock.c; sourceTree = "<group>"; };
083E489D006D88D97F000001 /* SDL_joystick.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SDL_joystick.c; sourceTree = "<group>"; }; 083E489D006D88D97F000001 /* SDL_joystick.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SDL_joystick.c; sourceTree = "<group>"; };
0C5AF5E501191D2B7F000001 /* begin_code.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = begin_code.h; path = ../../include/begin_code.h; sourceTree = SOURCE_ROOT; }; 0C5AF5E501191D2B7F000001 /* begin_code.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = begin_code.h; path = ../../include/begin_code.h; sourceTree = SOURCE_ROOT; };
0C5AF5E601191D2B7F000001 /* close_code.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = close_code.h; path = ../../include/close_code.h; sourceTree = SOURCE_ROOT; }; 0C5AF5E601191D2B7F000001 /* close_code.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = close_code.h; path = ../../include/close_code.h; sourceTree = SOURCE_ROOT; };
...@@ -1073,20 +1076,13 @@ ...@@ -1073,20 +1076,13 @@
00CFA69B106B467B00758660 /* atomic */ = { 00CFA69B106B467B00758660 /* atomic */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
00CFA6A0106B467B00758660 /* macosx */, 04FB7D4A12E2350700A522C6 /* SDL_atomic.c */,
04FB7D4B12E2350700A522C6 /* SDL_spinlock.c */,
); );
name = atomic; name = atomic;
path = ../../src/atomic; path = ../../src/atomic;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
00CFA6A0106B467B00758660 /* macosx */ = {
isa = PBXGroup;
children = (
00CFA6A1106B467B00758660 /* SDL_atomic.c */,
);
path = macosx;
sourceTree = "<group>";
};
00CFA6DF106B48D800758660 /* haptic */ = { 00CFA6DF106B48D800758660 /* haptic */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -2273,7 +2269,6 @@ ...@@ -2273,7 +2269,6 @@
002F32E509CA0BF600EBEB88 /* SDL_dummyaudio.c in Sources */, 002F32E509CA0BF600EBEB88 /* SDL_dummyaudio.c in Sources */,
046B91EC0A11B53500FB151C /* SDL_sysloadso.c in Sources */, 046B91EC0A11B53500FB151C /* SDL_sysloadso.c in Sources */,
046B92130A11B8AD00FB151C /* SDL_dlcompat.c in Sources */, 046B92130A11B8AD00FB151C /* SDL_dlcompat.c in Sources */,
00CFA6A8106B467B00758660 /* SDL_atomic.c in Sources */,
00CFA6B9106B46E500758660 /* SDL_audiotypecvt.c in Sources */, 00CFA6B9106B46E500758660 /* SDL_audiotypecvt.c in Sources */,
00CFA6CD106B480800758660 /* SDL_windowevents.c in Sources */, 00CFA6CD106B480800758660 /* SDL_windowevents.c in Sources */,
00CFA6EC106B48D800758660 /* SDL_syshaptic.c in Sources */, 00CFA6EC106B48D800758660 /* SDL_syshaptic.c in Sources */,
...@@ -2357,6 +2352,8 @@ ...@@ -2357,6 +2352,8 @@
4537738A1207C5A2002F0F45 /* SDL_cocoashape.m in Sources */, 4537738A1207C5A2002F0F45 /* SDL_cocoashape.m in Sources */,
453773921207C6E9002F0F45 /* SDL_x11shape.c in Sources */, 453773921207C6E9002F0F45 /* SDL_x11shape.c in Sources */,
046B9B6812D02EE600159CFE /* SDL_x11touch.c in Sources */, 046B9B6812D02EE600159CFE /* SDL_x11touch.c in Sources */,
04FB7D4C12E2350700A522C6 /* SDL_atomic.c in Sources */,
04FB7D4D12E2350700A522C6 /* SDL_spinlock.c in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -2399,7 +2396,6 @@ ...@@ -2399,7 +2396,6 @@
002F32E709CA0BF600EBEB88 /* SDL_dummyaudio.c in Sources */, 002F32E709CA0BF600EBEB88 /* SDL_dummyaudio.c in Sources */,
046B91ED0A11B53500FB151C /* SDL_sysloadso.c in Sources */, 046B91ED0A11B53500FB151C /* SDL_sysloadso.c in Sources */,
046B92140A11B8AD00FB151C /* SDL_dlcompat.c in Sources */, 046B92140A11B8AD00FB151C /* SDL_dlcompat.c in Sources */,
00CFA6AD106B467B00758660 /* SDL_atomic.c in Sources */,
00CFA6BF106B46E500758660 /* SDL_audiotypecvt.c in Sources */, 00CFA6BF106B46E500758660 /* SDL_audiotypecvt.c in Sources */,
00CFA6D3106B480800758660 /* SDL_windowevents.c in Sources */, 00CFA6D3106B480800758660 /* SDL_windowevents.c in Sources */,
00CFA6F3106B48D800758660 /* SDL_syshaptic.c in Sources */, 00CFA6F3106B48D800758660 /* SDL_syshaptic.c in Sources */,
...@@ -2477,6 +2473,8 @@ ...@@ -2477,6 +2473,8 @@
04DEA57C11E600A600386CAC /* SDL_cocoaclipboard.m in Sources */, 04DEA57C11E600A600386CAC /* SDL_cocoaclipboard.m in Sources */,
0420496411E6EFD3007E7EC9 /* SDL_clipboardevents.c in Sources */, 0420496411E6EFD3007E7EC9 /* SDL_clipboardevents.c in Sources */,
046B9B6A12D02EE600159CFE /* SDL_x11touch.c in Sources */, 046B9B6A12D02EE600159CFE /* SDL_x11touch.c in Sources */,
04FB7D4E12E2350700A522C6 /* SDL_atomic.c in Sources */,
04FB7D4F12E2350700A522C6 /* SDL_spinlock.c in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
......
...@@ -288,6 +288,7 @@ fi ...@@ -288,6 +288,7 @@ fi
# Standard C sources # Standard C sources
SOURCES="$SOURCES $srcdir/src/*.c" SOURCES="$SOURCES $srcdir/src/*.c"
SOURCES="$SOURCES $srcdir/src/audio/*.c" SOURCES="$SOURCES $srcdir/src/audio/*.c"
SOURCES="$SOURCES $srcdir/src/atomic/*.c"
SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c" SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c"
SOURCES="$SOURCES $srcdir/src/events/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c"
SOURCES="$SOURCES $srcdir/src/file/*.c" SOURCES="$SOURCES $srcdir/src/file/*.c"
...@@ -2303,16 +2304,6 @@ case "$host" in ...@@ -2303,16 +2304,6 @@ case "$host" in
;; ;;
esac esac
fi fi
# Set up files for the atomic operations library
if test x$enable_atomic = xyes; then
case $ARCH in
linux)
AC_DEFINE(SDL_ATOMIC_LINUX)
SOURCES="$SOURCES $srcdir/src/atomic/linux/*.c"
have_atomic=yes
;;
esac
fi
# Set up files for the joystick library # Set up files for the joystick library
if test x$enable_joystick = xyes; then if test x$enable_joystick = xyes; then
case $ARCH in case $ARCH in
...@@ -2395,12 +2386,6 @@ case "$host" in ...@@ -2395,12 +2386,6 @@ case "$host" in
SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
have_timers=yes have_timers=yes
fi fi
# Setup files for the atomic operations
if test x$enable_atomic = xyes; then
AC_DEFINE(SDL_ATOMIC_QNX)
SOURCES="$SOURCES $srcdir/src/atomic/qnx/*.c"
have_atomic=yes
fi
# Set up dummy files for the joystick for now # Set up dummy files for the joystick for now
if test x$enable_joystick = xyes; then if test x$enable_joystick = xyes; then
AC_DEFINE(SDL_JOYSTICK_DUMMY) AC_DEFINE(SDL_JOYSTICK_DUMMY)
...@@ -2460,12 +2445,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau ...@@ -2460,12 +2445,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
fi fi
have_audio=yes have_audio=yes
fi fi
# Set up files for the atomic operations library
if test x$enable_atomic = xyes; then
AC_DEFINE(SDL_ATOMIC_WIN32)
SOURCES="$SOURCES $srcdir/src/atomic/win32/*.c"
have_atomic=yes
fi
# Set up dummy files for the joystick for now # Set up dummy files for the joystick for now
if test x$enable_joystick = xyes; then if test x$enable_joystick = xyes; then
AC_DEFINE(SDL_JOYSTICK_DUMMY) AC_DEFINE(SDL_JOYSTICK_DUMMY)
...@@ -2555,12 +2534,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau ...@@ -2555,12 +2534,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
fi fi
have_audio=yes have_audio=yes
fi fi
# Set up files for the atomic operations library
if test x$enable_atomic = xyes; then
AC_DEFINE(SDL_ATOMIC_WIN32)
SOURCES="$SOURCES $srcdir/src/atomic/win32/*.c"
have_atomic=yes
fi
# Set up files for the joystick library # Set up files for the joystick library
if test x$enable_joystick = xyes; then if test x$enable_joystick = xyes; then
if test x$have_dinput = xyes; then if test x$have_dinput = xyes; then
...@@ -2715,12 +2688,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau ...@@ -2715,12 +2688,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
SOURCES="$SOURCES $srcdir/src/audio/macosx/*.c" SOURCES="$SOURCES $srcdir/src/audio/macosx/*.c"
have_audio=yes have_audio=yes
fi fi
# Set up files for the atomic operations library
if test x$enable_atomic = xyes; then
AC_DEFINE(SDL_ATOMIC_MACOSX)
SOURCES="$SOURCES $srcdir/src/atomic/macosx/*.c"
have_atomic=yes
fi
# Set up files for the joystick library # Set up files for the joystick library
if test x$enable_joystick = xyes; then if test x$enable_joystick = xyes; then
AC_DEFINE(SDL_JOYSTICK_IOKIT) AC_DEFINE(SDL_JOYSTICK_IOKIT)
...@@ -2826,12 +2793,6 @@ if test x$have_loadso != xyes; then ...@@ -2826,12 +2793,6 @@ if test x$have_loadso != xyes; then
fi fi
SOURCES="$SOURCES $srcdir/src/loadso/dummy/*.c" SOURCES="$SOURCES $srcdir/src/loadso/dummy/*.c"
fi fi
if test x$have_atomic != xyes; then
if test x$enable_atomic = xyes; then
AC_DEFINE(SDL_ATOMIC_DISABLED)
fi
SOURCES="$SOURCES $srcdir/src/atomic/dummy/*.c"
fi
if test x$SDLMAIN_SOURCES = x; then if test x$SDLMAIN_SOURCES = x; then
SDLMAIN_SOURCES="$srcdir/src/main/dummy/*.c" SDLMAIN_SOURCES="$srcdir/src/main/dummy/*.c"
fi fi
......
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
Sam Lantinga Sam Lantinga
slouken@libsdl.org slouken@libsdl.org
Contributed by Bob Pendleton, bob@pendleton.com
*/ */
/** /**
...@@ -27,15 +25,27 @@ ...@@ -27,15 +25,27 @@
* *
* Atomic operations. * Atomic operations.
* *
* IMPORTANT:
* If you are not an expert in concurrent lockless programming, you should
* only be using the atomic lock and reference counting functions in this
* file. In all other cases you should be protecting your data structures
* with full mutexes.
*
* The list of "safe" functions to use are:
* SDL_AtomicLock()
* SDL_AtomicUnlock()
* SDL_AtomicIncRef()
* SDL_AtomicDecRef()
*
* Seriously, here be dragons!
*
* These operations may, or may not, actually be implemented using * These operations may, or may not, actually be implemented using
* processor specific atomic operations. When possible they are * processor specific atomic operations. When possible they are
* implemented as true processor specific atomic operations. When that * implemented as true processor specific atomic operations. When that
* is not possible the are implemented using locks that *do* use the * is not possible the are implemented using locks that *do* use the
* available atomic operations. * available atomic operations.
* *
* At the very minimum spin locks must be implemented. Without spin * All of the atomic operations that modify memory are full memory barriers.
* locks it is not possible (AFAICT) to emulate the rest of the atomic
* operations.
*/ */
#ifndef _SDL_atomic_h_ #ifndef _SDL_atomic_h_
...@@ -53,20 +63,36 @@ extern "C" { ...@@ -53,20 +63,36 @@ extern "C" {
/* *INDENT-ON* */ /* *INDENT-ON* */
#endif #endif
/* Function prototypes */
/** /**
* \name SDL AtomicLock * \name SDL AtomicLock
* *
* The atomic locks are efficient spinlocks using CPU instructions,
* but are vulnerable to starvation and can spin forever if a thread
* holding a lock has been terminated. For this reason you should
* minimize the code executed inside an atomic lock and never do
* expensive things like API or system calls while holding them.
*
* The atomic locks are not safe to lock recursively.
*
* Porting Note:
* The spin lock functions and type are required and can not be * The spin lock functions and type are required and can not be
* emulated because they are used in the emulation code. * emulated because they are used in the atomic emulation code.
*/ */
/*@{*/ /*@{*/
typedef volatile Uint32 SDL_SpinLock; typedef int SDL_SpinLock;
/** /**
* \brief Lock a spin lock by setting it to a none zero value. * \brief Try to lock a spin lock by setting it to a non-zero value.
*
* \param lock Points to the lock.
*
* \return SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already held.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock(SDL_SpinLock *lock);
/**
* \brief Lock a spin lock by setting it to a non-zero value.
* *
* \param lock Points to the lock. * \param lock Points to the lock.
*/ */
...@@ -81,126 +107,94 @@ extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock); ...@@ -81,126 +107,94 @@ extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock);
/*@}*//*SDL AtomicLock*/ /*@}*//*SDL AtomicLock*/
/** /* Platform specific optimized versions of the atomic functions */
* \name 32 bit atomic operations /* None yet... */
*/
/*@{*/
/** /**
* \brief Check to see if \c *ptr == 0 and set it to 1. * \brief A type representing an atomic integer value. It is a struct
* * so people don't accidentally use numeric operations on it.
* \return SDL_True if the value pointed to by \c ptr was zero and
* SDL_False if it was not zero
*
* \param ptr Points to the value to be tested and set.
*/ */
extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTestThenSet32(volatile Uint32 * ptr); #ifndef SDL_atomic_t_defined
typedef struct { int value; } SDL_atomic_t;
#endif
/** /**
* \brief Set the value pointed to by \c ptr to be zero. * \brief Set an atomic variable to a value.
* *
* \param ptr Address of the value to be set to zero * \return The previous value of the atomic variable.
*/ */
extern DECLSPEC void SDLCALL SDL_AtomicClear32(volatile Uint32 * ptr); #ifndef SDL_AtomicSet
extern DECLSPEC int SDLCALL SDL_AtomicSet(SDL_atomic_t *a, int value);
#endif
/** /**
* \brief Fetch the current value of \c *ptr and then increment that * \brief Get the value of an atomic variable
* value in place.
*
* \return The value before it was incremented.
*
* \param ptr Address of the value to fetch and increment
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr); #ifndef SDL_AtomicGet
extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_atomic_t *a);
#endif
/** /**
* \brief Fetch \c *ptr and then decrement the value in place. * \brief Add to an atomic variable.
* *
* \return The value before it was decremented. * \return The previous value of the atomic variable.
*
* \param ptr Address of the value to fetch and decrement
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr); #ifndef SDL_AtomicAdd
extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int value);
#endif
/** /**
* \brief Fetch the current value at \c ptr and then add \c value to \c *ptr. * \brief Increment an atomic variable used as a reference count.
*
* \return \c *ptr before the addition took place.
*
* \param ptr The address of data we are changing.
* \param value The value to add to \c *ptr.
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value); #ifndef SDL_AtomicIncRef
extern DECLSPEC void SDLCALL SDL_AtomicIncRef(SDL_atomic_t *a);
#endif
/** /**
* \brief Fetch \c *ptr and then subtract \c value from it. * \brief Decrement an atomic variable used as a reference count.
*
* \return \c *ptr before the subtraction took place.
* *
* \param ptr The address of the data being changed. * \return SDL_TRUE if the variable has reached zero after decrementing,
* \param value The value to subtract from \c *ptr. * SDL_FALSE otherwise
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value); #ifndef SDL_AtomicDecRef
extern DECLSPEC SDL_bool SDLCALL SDL_AtomicDecRef(SDL_atomic_t *a);
#endif
/** /**
* \brief Add one to the data pointed to by \c ptr and return that value. * \brief Set an atomic variable to a new value if it is currently an old value.
* *
* \return The incremented value. * \return The previous value of the atomic variable
* *
* \param ptr The address of the data to increment. * \note If you don't know what this function is for, you shouldn't use it!
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr); #ifndef SDL_AtomicCAS
extern DECLSPEC int SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval);
#endif
/** /**
* \brief Subtract one from data pointed to by \c ptr and return the new value. * \brief Set a pointer to a value atomically.
*
* \return The decremented value.
*
* \param ptr The address of the data to decrement.
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr); #ifndef SDL_AtomicSetPtr
extern DECLSPEC void SDLCALL SDL_AtomicSetPtr(void** a, void* value);
#endif
/** /**
* \brief Add \c value to the data pointed to by \c ptr and return result. * \brief Get the value of a pointer atomically.
*
* \return The sum of \c *ptr and \c value.
*
* \param ptr The address of the data to be modified.
* \param value The value to be added.
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value); #ifndef SDL_AtomicGetPtr
extern DECLSPEC void* SDLCALL SDL_AtomicGetPtr(void** a);
#endif
/** /**
* \brief Subtract \c value from the data pointed to by \c ptr and return the result. * \brief Set a pointer to a new value if it is currently an old value.
* *
* \return The difference between \c *ptr and \c value. * \return The previous value of the pointer
* *
* \param ptr The address of the data to be modified. * \note If you don't know what this function is for, you shouldn't use it!
* \param value The value to be subtracted. */
*/ #ifndef SDL_AtomicCASPtr
extern DECLSPEC Uint32 SDLCALL SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value); extern DECLSPEC void* SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval);
#endif
/*@}*//*32 bit atomic operations*/
/**
* \name 64 bit atomic operations
*/
/*@{*/
#ifdef SDL_HAS_64BIT_TYPE
extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTestThenSet64(volatile Uint64 * ptr);
extern DECLSPEC void SDLCALL SDL_AtomicClear64(volatile Uint64 * ptr);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenIncrement64(volatile Uint64 * ptr);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenDecrement64(volatile Uint64 * ptr);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenAdd64(volatile Uint64 * ptr, Uint64 value);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenSubtract64(volatile Uint64 * ptr, Uint64 value);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicIncrementThenFetch64(volatile Uint64 * ptr);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicDecrementThenFetch64(volatile Uint64 * ptr);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicAddThenFetch64(volatile Uint64 * ptr, Uint64 value);
extern DECLSPEC Uint64 SDLCALL SDL_AtomicSubtractThenFetch64(volatile Uint64 * ptr, Uint64 value);
#endif /* SDL_HAS_64BIT_TYPE */
/*@}*//*64 bit atomic operations*/
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus
......
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 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
*/
#include "SDL_stdinc.h"
#include "SDL_atomic.h"
/*
If any of the operations are not provided then we must emulate some
of them. That means we need a nice implementation of spin locks
that avoids the "one big lock" problem. We use a vector of spin
locks and pick which one to use based on the address of the operand
of the function.
To generate the index of the lock we first shift by 3 bits to get
rid on the zero bits that result from 32 and 64 bit allignment of
data. We then mask off all but 5 bits and use those 5 bits as an
index into the table.
Picking the lock this way insures that accesses to the same data at
the same time will go to the same lock. OTOH, accesses to different
data have only a 1/32 chance of hitting the same lock. That should
pretty much eliminate the chances of several atomic operations on
different data from waiting on the same "big lock". If it isn't
then the table of locks can be expanded to a new size so long as
the new size is a power of two.
Contributed by Bob Pendleton, bob@pendleton.com
*/
static SDL_SpinLock locks[32];
static __inline__ void
enterLock(void *a)
{
uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
SDL_AtomicLock(&locks[index]);
}
static __inline__ void
leaveLock(void *a)
{
uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
SDL_AtomicUnlock(&locks[index]);
}
#ifndef SDL_AtomicSet
int
SDL_AtomicSet(SDL_atomic_t *a, int value)
{
int oldvalue;
enterLock(a);
oldvalue = a->value;
a->value = value;
leaveLock(a);
return oldvalue;
}
#endif
#ifndef SDL_AtomicGet
int
SDL_AtomicGet(SDL_atomic_t *a)
{
/* Assuming integral reads on this platform, we're safe here since the
functions that set the variable have the necessary memory barriers.
*/
return a->value;
}
#endif
#ifndef SDL_AtomicAdd
int
SDL_AtomicAdd(SDL_atomic_t *a, int value)
{
int oldvalue;
enterLock(a);
oldvalue = a->value;
a->value += value;
leaveLock(a);
return oldvalue;
}
#endif
#ifndef SDL_AtomicIncRef
void
SDL_AtomicIncRef(SDL_atomic_t *a)
{
SDL_AtomicAdd(a, 1);
}
#endif
#ifndef SDL_AtomicDecRef
SDL_bool
SDL_AtomicDecRef(SDL_atomic_t *a)
{
return SDL_AtomicAdd(a, -1) == 1;
}
#endif
#ifndef SDL_AtomicCAS
int
SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval)
{
int prevval;
enterLock(a);
prevval = a->value;
if (prevval == oldval) {
a->value = newval;
}
leaveLock(a);
return prevval;
}
#endif
#ifndef SDL_AtomicSetPtr
void
SDL_AtomicSetPtr(void** a, void* value)
{
void *prevval;
do {
prevval = *a;
} while (SDL_AtomicCASPtr(a, prevval, value) != prevval);
}
#endif
#ifndef SDL_AtomicGetPtr
void*
SDL_AtomicGetPtr(void** a)
{
/* Assuming integral reads on this platform, we're safe here since the
functions that set the pointer have the necessary memory barriers.
*/
return *a;
}
#endif
#ifndef SDL_AtomicCASPtr
void* SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
{
void *prevval;
enterLock(a);
prevval = *a;
if (*a == oldval) {
*a = newval;
}
leaveLock(a);
return prevval;
}
#endif
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 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
*/
#include "SDL_stdinc.h"
#include "SDL_atomic.h"
#include "SDL_timer.h"
#if defined(__WIN32__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#elif defined(__MACOSX__)
#include <libkern/OSAtomic.h>
#endif
/* This function is where all the magic happens... */
SDL_bool
SDL_AtomicTryLock(SDL_SpinLock *lock)
{
#if defined(__WIN32__)
return (InterlockedExchange(lock, 1) == 0);
#elif defined(__MACOSX__)
return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
#elif defined(__GNUC__)
#if defined(__arm__)
#ifdef __ARM_ARCH_5__
int result;
__asm__ __volatile__ (
"swp %0, %1, [%2]\n"
: "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory");
return (result == 0);
#else
int result;
__asm__ __volatile__ (
"ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
: "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
return (result == 0);
#endif
#else
return (__sync_lock_test_and_set(lock, 1) == 0);
#endif
#else
/* Need CPU instructions for spinlock here! */
__need_spinlock_implementation__
#endif
}
void
SDL_AtomicLock(SDL_SpinLock *lock)
{
/* FIXME: Should we have an eventual timeout? */
while (!SDL_AtomicTryLock(lock)) {
SDL_Delay(0);
}
}
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
{
#if defined(__WIN32__)
*lock = 0;
#elif defined(__MACOSX__)
*lock = 0;
#elif defined(__GNUC__) && !defined(__arm__)
__sync_lock_release(lock);
#else
/* Assuming memory barrier in lock and integral assignment operation */
*lock = 0;
#endif
}
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 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
Contributed by Bob Pendleton, bob@pendleton.com
*/
#include "SDL_stdinc.h"
#include "SDL_atomic.h"
#include "SDL_error.h"
/*
This file provides 32, and 64 bit atomic operations. If the
operations are provided by the native hardware and operating system
they are used. If they are not then the operations are emulated
using the SDL spin lock operations. If spin lock can not be
implemented then these functions must fail.
*/
/*
DUMMY VERSION.
This version of the code assumes there is no support for atomic
operations. Therefore, every function sets the SDL error
message. Oddly enough, if you only have one thread then this
version actuallys works.
*/
/*
Native spinlock routines. Because this is the dummy implementation
these will always call SDL_SetError() and do nothing.
*/
void
SDL_AtomicLock(SDL_SpinLock *lock)
{
SDL_SetError("SDL_atomic.c: is not implemented on this platform");
}
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
{
SDL_SetError("SDL_atomic.c: is not implemented on this platform");
}
/*
Note that platform specific versions can be built from this version
by changing the #undefs to #defines and adding platform specific
code.
*/
#undef nativeTestThenSet32
#undef nativeClear32
#undef nativeFetchThenIncrement32
#undef nativeFetchThenDecrement32
#undef nativeFetchThenAdd32
#undef nativeFetchThenSubtract32
#undef nativeIncrementThenFetch32
#undef nativeDecrementThenFetch32
#undef nativeAddThenFetch32
#undef nativeSubtractThenFetch32
#undef nativeTestThenSet64
#undef nativeClear64
#undef nativeFetchThenIncrement64
#undef nativeFetchThenDecrement64
#undef nativeFetchThenAdd64
#undef nativeFetchThenSubtract64
#undef nativeIncrementThenFetch64
#undef nativeDecrementThenFetch64
#undef nativeAddThenFetch64
#undef nativeSubtractThenFetch64
/*
If any of the operations are not provided then we must emulate some
of them. That means we need a nice implementation of spin locks
that avoids the "one big lock" problem. We use a vector of spin
locks and pick which one to use based on the address of the operand
of the function.
To generate the index of the lock we first shift by 3 bits to get
rid on the zero bits that result from 32 and 64 bit allignment of
data. We then mask off all but 5 bits and use those 5 bits as an
index into the table.
Picking the lock this way insures that accesses to the same data at
the same time will go to the same lock. OTOH, accesses to different
data have only a 1/32 chance of hitting the same lock. That should
pretty much eliminate the chances of several atomic operations on
different data from waiting on the same "big lock". If it isn't
then the table of locks can be expanded to a new size so long as
the new size is a power of two.
*/
static SDL_SpinLock locks[32] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static __inline__ void
privateWaitLock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif
SDL_AtomicLock(&locks[index]);
}
static __inline__ void
privateUnlock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif
SDL_AtomicUnlock(&locks[index]);
}
/* 32 bit atomic operations */
SDL_bool
SDL_AtomicTestThenSet32(volatile Uint32 * ptr)
{
#ifdef nativeTestThenSet32
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif
}
void
SDL_AtomicClear32(volatile Uint32 * ptr)
{
#ifdef nativeClear32
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif
}
Uint32
SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenIncrement32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenDecrement32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenAdd32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenSubtract32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeIncrementThenFetch32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeDecrementThenFetch32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeAddThenFetch32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeSubtractThenFetch32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
/* 64 bit atomic operations */
#ifdef SDL_HAS_64BIT_TYPE
SDL_bool
SDL_AtomicTestThenSet64(volatile Uint64 * ptr)
{
#ifdef nativeTestThenSet64
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif
}
void
SDL_AtomicClear64(volatile Uint64 * ptr)
{
#ifdef nativeClear64
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif
}
Uint64
SDL_AtomicFetchThenIncrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenIncrement64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenDecrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenDecrement64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenAdd64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenAdd64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenSubtract64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenSubtract64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicIncrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeIncrementThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicDecrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeDecrementThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicAddThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeAddThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicSubtractThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeSubtractThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
#endif
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 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
Contributed by Bob Pendleton, bob@pendleton.com
*/
#include "SDL_stdinc.h"
#include "SDL_atomic.h"
#include "SDL_error.h"
/*
This file provides 32, and 64 bit atomic operations. If the
operations are provided by the native hardware and operating system
they are used. If they are not then the operations are emulated
using the SDL spin lock operations. If spin lock can not be
implemented then these functions must fail.
*/
/*
LINUX/GCC VERSION.
This version of the code assumes support of the atomic builtins as
documented at gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html This
code should work on any modern x86 or other processor supported by
GCC.
Some processors will only support some of these operations so
#ifdefs will have to be added as incompatibilities are discovered
*/
/*
Native spinlock routines.
*/
void
SDL_AtomicLock(SDL_SpinLock *lock)
{
while (0 != __sync_lock_test_and_set(lock, 1))
{
}
}
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
{
__sync_lock_test_and_set(lock, 0);
}
/*
Note that platform specific versions can be built from this version
by changing the #undefs to #defines and adding platform specific
code.
*/
#define nativeTestThenSet32
#define nativeClear32
#define nativeFetchThenIncrement32
#define nativeFetchThenDecrement32
#define nativeFetchThenAdd32
#define nativeFetchThenSubtract32
#define nativeIncrementThenFetch32
#define nativeDecrementThenFetch32
#define nativeAddThenFetch32
#define nativeSubtractThenFetch32
#ifdef SDL_HAS_64BIT_TYPE
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
#define nativeTestThenSet64
#define nativeClear64
#define nativeFetchThenIncrement64
#define nativeFetchThenDecrement64
#define nativeFetchThenAdd64
#define nativeFetchThenSubtract64
#define nativeIncrementThenFetch64
#define nativeDecrementThenFetch64
#define nativeAddThenFetch64
#define nativeSubtractThenFetch64
#else
#undef nativeTestThenSet64
#undef nativeClear64
#undef nativeFetchThenIncrement64
#undef nativeFetchThenDecrement64
#undef nativeFetchThenAdd64
#undef nativeFetchThenSubtract64
#undef nativeIncrementThenFetch64
#undef nativeDecrementThenFetch64
#undef nativeAddThenFetch64
#undef nativeSubtractThenFetch64
#endif /* __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 */
#endif /* SDL_HAS_64BIT_TYPE */
/*
If any of the operations are not provided then we must emulate some
of them. That means we need a nice implementation of spin locks
that avoids the "one big lock" problem. We use a vector of spin
locks and pick which one to use based on the address of the operand
of the function.
To generate the index of the lock we first shift by 3 bits to get
rid on the zero bits that result from 32 and 64 bit allignment of
data. We then mask off all but 5 bits and use those 5 bits as an
index into the table.
Picking the lock this way insures that accesses to the same data at
the same time will go to the same lock. OTOH, accesses to different
data have only a 1/32 chance of hitting the same lock. That should
pretty much eliminate the chances of several atomic operations on
different data from waiting on the same "big lock". If it isn't
then the table of locks can be expanded to a new size so long as
the new size is a power of two.
*/
static SDL_SpinLock locks[32] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static __inline__ void
privateWaitLock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif
SDL_AtomicLock(&locks[index]);
}
static __inline__ void
privateUnlock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif
SDL_AtomicUnlock(&locks[index]);
}
/* 32 bit atomic operations */
SDL_bool
SDL_AtomicTestThenSet32(volatile Uint32 * ptr)
{
#ifdef nativeTestThenSet32
return 0 == __sync_lock_test_and_set(ptr, 1);
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif
}
void
SDL_AtomicClear32(volatile Uint32 * ptr)
{
#ifdef nativeClear32
__sync_lock_test_and_set(ptr, 0);
return;
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif
}
Uint32
SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenIncrement32
return __sync_fetch_and_add(ptr, 1);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenDecrement32
return __sync_fetch_and_sub(ptr, 1);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenAdd32
return __sync_fetch_and_add(ptr, value);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenSubtract32
return __sync_fetch_and_sub(ptr, value);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeIncrementThenFetch32
return __sync_add_and_fetch(ptr, 1);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeDecrementThenFetch32
return __sync_sub_and_fetch(ptr, 1);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeAddThenFetch32
return __sync_add_and_fetch(ptr, value);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeSubtractThenFetch32
return __sync_sub_and_fetch(ptr, value);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
/* 64 bit atomic operations */
#ifdef SDL_HAS_64BIT_TYPE
SDL_bool
SDL_AtomicTestThenSet64(volatile Uint64 * ptr)
{
#ifdef nativeTestThenSet64
return 0 == __sync_lock_test_and_set(ptr, 1);
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif
}
void
SDL_AtomicClear64(volatile Uint64 * ptr)
{
#ifdef nativeClear64
__sync_lock_test_and_set(ptr, 0);
return;
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif
}
Uint64
SDL_AtomicFetchThenIncrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenIncrement64
return __sync_fetch_and_add(ptr, 1);
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenDecrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenDecrement64
return __sync_fetch_and_sub(ptr, 1);
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenAdd64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenAdd64
return __sync_fetch_and_add(ptr, value);
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenSubtract64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenSubtract64
return __sync_fetch_and_sub(ptr, value);
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicIncrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeIncrementThenFetch64
return __sync_add_and_fetch(ptr, 1);
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicDecrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeDecrementThenFetch64
return __sync_sub_and_fetch(ptr, 1);
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicAddThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeAddThenFetch64
return __sync_add_and_fetch(ptr, value);
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicSubtractThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeSubtractThenFetch64
return __sync_sub_and_fetch(ptr, value);
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
#endif /* SDL_HAS_64BIT_TYPE */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 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
Contributed by Bob Pendleton, bob@pendleton.com
*/
#include "SDL_stdinc.h"
#include "SDL_atomic.h"
#include "SDL_error.h"
/*
This file provides 32, and 64 bit atomic operations. If the
operations are provided by the native hardware and operating system
they are used. If they are not then the operations are emulated
using the SDL spin lock operations. If spin lock can not be
implemented then these functions must fail.
*/
/*
DUMMY VERSION.
This version of the code assumes there is no support for atomic
operations. Therefore, every function sets the SDL error
message. Oddly enough, if you only have one thread then this
version actuallys works.
*/
/*
Native spinlock routines. Because this is the dummy implementation
these will always call SDL_SetError() and do nothing.
*/
void
SDL_AtomicLock(SDL_SpinLock *lock)
{
SDL_SetError("SDL_atomic.c: is not implemented on this platform");
}
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
{
SDL_SetError("SDL_atomic.c: is not implemented on this platform");
}
/*
Note that platform specific versions can be built from this version
by changing the #undefs to #defines and adding platform specific
code.
*/
#undef nativeTestThenSet32
#undef nativeClear32
#undef nativeFetchThenIncrement32
#undef nativeFetchThenDecrement32
#undef nativeFetchThenAdd32
#undef nativeFetchThenSubtract32
#undef nativeIncrementThenFetch32
#undef nativeDecrementThenFetch32
#undef nativeAddThenFetch32
#undef nativeSubtractThenFetch32
#undef nativeTestThenSet64
#undef nativeClear64
#undef nativeFetchThenIncrement64
#undef nativeFetchThenDecrement64
#undef nativeFetchThenAdd64
#undef nativeFetchThenSubtract64
#undef nativeIncrementThenFetch64
#undef nativeDecrementThenFetch64
#undef nativeAddThenFetch64
#undef nativeSubtractThenFetch64
/*
If any of the operations are not provided then we must emulate some
of them. That means we need a nice implementation of spin locks
that avoids the "one big lock" problem. We use a vector of spin
locks and pick which one to use based on the address of the operand
of the function.
To generate the index of the lock we first shift by 3 bits to get
rid on the zero bits that result from 32 and 64 bit allignment of
data. We then mask off all but 5 bits and use those 5 bits as an
index into the table.
Picking the lock this way insures that accesses to the same data at
the same time will go to the same lock. OTOH, accesses to different
data have only a 1/32 chance of hitting the same lock. That should
pretty much eliminate the chances of several atomic operations on
different data from waiting on the same "big lock". If it isn't
then the table of locks can be expanded to a new size so long as
the new size is a power of two.
*/
static SDL_SpinLock locks[32] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static __inline__ void
privateWaitLock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif
SDL_AtomicLock(&locks[index]);
}
static __inline__ void
privateUnlock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif
SDL_AtomicUnlock(&locks[index]);
}
/* 32 bit atomic operations */
SDL_bool
SDL_AtomicTestThenSet32(volatile Uint32 * ptr)
{
#ifdef nativeTestThenSet32
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif
}
void
SDL_AtomicClear32(volatile Uint32 * ptr)
{
#ifdef nativeClear32
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif
}
Uint32
SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenIncrement32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenDecrement32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenAdd32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenSubtract32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeIncrementThenFetch32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeDecrementThenFetch32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeAddThenFetch32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeSubtractThenFetch32
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
/* 64 bit atomic operations */
#ifdef SDL_HAS_64BIT_TYPE
SDL_bool
SDL_AtomicTestThenSet64(volatile Uint64 * ptr)
{
#ifdef nativeTestThenSet64
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif
}
void
SDL_AtomicClear64(volatile Uint64 * ptr)
{
#ifdef nativeClear64
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif
}
Uint64
SDL_AtomicFetchThenIncrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenIncrement64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenDecrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenDecrement64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenAdd64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenAdd64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenSubtract64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenSubtract64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicIncrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeIncrementThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicDecrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeDecrementThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicAddThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeAddThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicSubtractThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeSubtractThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
#endif
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 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
QNX native atomic operations
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_stdinc.h"
#include "SDL_atomic.h"
#include "SDL_error.h"
#include <atomic.h>
/* SMP Exchange for PPC platform */
#ifdef __PPC__
#include <ppc/smpxchg.h>
#endif /* __PPC__ */
/* SMP Exchange for ARM platform */
#ifdef __ARM__
#include <arm/smpxchg.h>
#endif /* __ARM__ */
/* SMP Exchange for MIPS platform */
#if defined (__MIPSEB__) || defined(__MIPSEL__)
#include <mips/smpxchg.h>
#endif /* __MIPSEB__ || __MIPSEL__ */
/* SMP Exchange for SH platform */
#ifdef __SH__
#include <sh/smpxchg.h>
#endif /* __SH__ */
/* SMP Exchange for x86 platform */
#ifdef __X86__
#include <x86/smpxchg.h>
#endif /* __X86__ */
/*
This file provides 32, and 64 bit atomic operations. If the
operations are provided by the native hardware and operating system
they are used. If they are not then the operations are emulated
using the SDL spin lock operations. If spin lock can not be
implemented then these functions must fail.
*/
void
SDL_AtomicLock(SDL_SpinLock *lock)
{
unsigned volatile* l = (unsigned volatile*)lock;
Uint32 oldval = 0;
Uint32 newval = 1;
oldval = _smp_xchg(l, newval);
while(1 == oldval)
{
oldval = _smp_xchg(l, newval);
}
}
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
{
unsigned volatile* l = (unsigned volatile*)lock;
Uint32 newval = 0;
_smp_xchg(l, newval);
}
/*
QNX 6.4.1 supports only 32 bit atomic access
*/
#undef nativeTestThenSet32
#define nativeClear32
#define nativeFetchThenIncrement32
#define nativeFetchThenDecrement32
#define nativeFetchThenAdd32
#define nativeFetchThenSubtract32
#define nativeIncrementThenFetch32
#define nativeDecrementThenFetch32
#define nativeAddThenFetch32
#define nativeSubtractThenFetch32
#undef nativeTestThenSet64
#undef nativeClear64
#undef nativeFetchThenIncrement64
#undef nativeFetchThenDecrement64
#undef nativeFetchThenAdd64
#undef nativeFetchThenSubtract64
#undef nativeIncrementThenFetch64
#undef nativeDecrementThenFetch64
#undef nativeAddThenFetch64
#undef nativeSubtractThenFetch64
/*
If any of the operations are not provided then we must emulate some
of them. That means we need a nice implementation of spin locks
that avoids the "one big lock" problem. We use a vector of spin
locks and pick which one to use based on the address of the operand
of the function.
To generate the index of the lock we first shift by 3 bits to get
rid on the zero bits that result from 32 and 64 bit allignment of
data. We then mask off all but 5 bits and use those 5 bits as an
index into the table.
Picking the lock this way insures that accesses to the same data at
the same time will go to the same lock. OTOH, accesses to different
data have only a 1/32 chance of hitting the same lock. That should
pretty much eliminate the chances of several atomic operations on
different data from waiting on the same "big lock". If it isn't
then the table of locks can be expanded to a new size so long as
the new size is a power of two.
*/
static SDL_SpinLock locks[32] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static __inline__ void
privateWaitLock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif /* SIZEOF_VOIDP */
SDL_AtomicLock(&locks[index]);
}
static __inline__ void
privateUnlock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif /* SIZEOF_VOIDP */
SDL_AtomicUnlock(&locks[index]);
}
/* 32 bit atomic operations */
SDL_bool
SDL_AtomicTestThenSet32(volatile Uint32 * ptr)
{
#ifdef nativeTestThenSet32
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif /* nativeTestThenSet32 */
}
void
SDL_AtomicClear32(volatile Uint32 * ptr)
{
#ifdef nativeClear32
atomic_clr(ptr, 0xFFFFFFFF);
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif /* nativeClear32 */
}
Uint32
SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenIncrement32
return atomic_add_value(ptr, 0x00000001);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif /* nativeFetchThenIncrement32 */
}
Uint32
SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenDecrement32
return atomic_sub_value(ptr, 0x00000001);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif /* nativeFetchThenDecrement32 */
}
Uint32
SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenAdd32
return atomic_add_value(ptr, value);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif /* nativeFetchThenAdd32 */
}
Uint32
SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenSubtract32
return atomic_sub_value(ptr, value);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif /* nativeFetchThenSubtract32 */
}
Uint32
SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeIncrementThenFetch32
atomic_add(ptr, 0x00000001);
return atomic_add_value(ptr, 0x00000000);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif /* nativeIncrementThenFetch32 */
}
Uint32
SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeDecrementThenFetch32
atomic_sub(ptr, 0x00000001);
return atomic_sub_value(ptr, 0x00000000);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif /* nativeDecrementThenFetch32 */
}
Uint32
SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeAddThenFetch32
atomic_add(ptr, value);
return atomic_add_value(ptr, 0x00000000);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif /* nativeAddThenFetch32 */
}
Uint32
SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeSubtractThenFetch32
atomic_sub(ptr, value);
return atomic_sub_value(ptr, 0x00000000);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif /* nativeSubtractThenFetch32 */
}
/* 64 bit atomic operations */
#ifdef SDL_HAS_64BIT_TYPE
SDL_bool
SDL_AtomicTestThenSet64(volatile Uint64 * ptr)
{
#ifdef nativeTestThenSet64
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif /* nativeTestThenSet64 */
}
void
SDL_AtomicClear64(volatile Uint64 * ptr)
{
#ifdef nativeClear64
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif /* nativeClear64 */
}
Uint64
SDL_AtomicFetchThenIncrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenIncrement64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif /* nativeFetchThenIncrement64 */
}
Uint64
SDL_AtomicFetchThenDecrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenDecrement64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif /* nativeFetchThenDecrement64 */
}
Uint64
SDL_AtomicFetchThenAdd64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenAdd64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif /* nativeFetchThenAdd64 */
}
Uint64
SDL_AtomicFetchThenSubtract64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenSubtract64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif /* nativeFetchThenSubtract64 */
}
Uint64
SDL_AtomicIncrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeIncrementThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif /* nativeIncrementThenFetch64 */
}
Uint64
SDL_AtomicDecrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeDecrementThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif /* nativeDecrementThenFetch64 */
}
Uint64
SDL_AtomicAddThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeAddThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif /* nativeAddThenFetch64 */
}
Uint64
SDL_AtomicSubtractThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeSubtractThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif /* nativeSubtractThenFetch64 */
}
#endif /* SDL_HAS_64BIT_TYPE */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 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
Contributed by Bob Pendleton, bob@pendleton.com
*/
#include "SDL_stdinc.h"
#include "SDL_atomic.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "SDL_error.h"
/*
This file provides 32, and 64 bit atomic operations. If the
operations are provided by the native hardware and operating system
they are used. If they are not then the operations are emulated
using the SDL spin lock operations. If spin lock can not be
implemented then these functions must fail.
*/
/*
WIN32 VERSION.
This makes use of native Windows atomic operations.
*/
/*
Native spinlock routines. Because this is the dummy implementation
these will always call SDL_SetError() and do nothing.
*/
void
SDL_AtomicLock(SDL_SpinLock *lock)
{
long volatile * l = (long volatile *)lock;
Uint32 old = 0;
Uint32 new = 1;
old = InterlockedExchange(l, new);
while(1 == old)
{
old = InterlockedExchange(l, new);
}
}
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
{
long volatile * l = (long volatile *)lock;
Uint32 new = 0;
InterlockedExchange(l, new);
}
/*
Note that platform specific versions can be built from this version
by changing the #undefs to #defines and adding platform specific
code.
*/
#define nativeTestThenSet32
#define nativeClear32
#define nativeFetchThenIncrement32
#define nativeFetchThenDecrement32
#define nativeFetchThenAdd32
#define nativeFetchThenSubtract32
#define nativeIncrementThenFetch32
#define nativeDecrementThenFetch32
#define nativeAddThenFetch32
#define nativeSubtractThenFetch32
#undef nativeTestThenSet64
#undef nativeClear64
#undef nativeFetchThenIncrement64
#undef nativeFetchThenDecrement64
#undef nativeFetchThenAdd64
#undef nativeFetchThenSubtract64
#undef nativeIncrementThenFetch64
#undef nativeDecrementThenFetch64
#undef nativeAddThenFetch64
#undef nativeSubtractThenFetch64
/*
If any of the operations are not provided then we must emulate some
of them. That means we need a nice implementation of spin locks
that avoids the "one big lock" problem. We use a vector of spin
locks and pick which one to use based on the address of the operand
of the function.
To generate the index of the lock we first shift by 3 bits to get
rid on the zero bits that result from 32 and 64 bit allignment of
data. We then mask off all but 5 bits and use those 5 bits as an
index into the table.
Picking the lock this way insures that accesses to the same data at
the same time will go to the same lock. OTOH, accesses to different
data have only a 1/32 chance of hitting the same lock. That should
pretty much eliminate the chances of several atomic operations on
different data from waiting on the same "big lock". If it isn't
then the table of locks can be expanded to a new size so long as
the new size is a power of two.
*/
static SDL_SpinLock locks[32] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static __inline__ void
privateWaitLock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif
SDL_AtomicLock(&locks[index]);
}
static __inline__ void
privateUnlock(volatile void *ptr)
{
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
#endif
SDL_AtomicUnlock(&locks[index]);
}
/* 32 bit atomic operations */
SDL_bool
SDL_AtomicTestThenSet32(volatile Uint32 * ptr)
{
#ifdef nativeTestThenSet32
long volatile * p = (long volatile *)ptr;
Uint32 new = 1;
return 0 == InterlockedExchange(p, new);
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif
}
void
SDL_AtomicClear32(volatile Uint32 * ptr)
{
#ifdef nativeClear32
long volatile * p = (long volatile *)ptr;
Uint32 new = 0;
InterlockedExchange(p, new);
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif
}
Uint32
SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenIncrement32
long volatile * p = (long volatile *)ptr;
return InterlockedExchangeAdd(p, 1);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr)
{
#ifdef nativeFetchThenDecrement32
long volatile * p = (long volatile *)ptr;
return InterlockedExchangeAdd(p, -1);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenAdd32
long volatile * p = (long volatile *)ptr;
return InterlockedExchangeAdd(p, value);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeFetchThenSubtract32
long volatile * p = (long volatile *)ptr;
return InterlockedExchangeAdd(p, (0 - value));
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeIncrementThenFetch32
long volatile * p = (LONG volatile *)ptr;
return InterlockedIncrement(p);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr)
{
#ifdef nativeDecrementThenFetch32
long volatile * p = (LONG volatile *)ptr;
return InterlockedDecrement(p);
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeAddThenFetch32
long volatile * p = (long volatile *)ptr;
return InterlockedExchangeAdd(p, value) + value;
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint32
SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value)
{
#ifdef nativeSubtractThenFetch32
long volatile * p = (long volatile *)ptr;
return InterlockedExchangeAdd(p, (0 - value)) - value;
#else
Uint32 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
/* 64 bit atomic operations */
#ifdef SDL_HAS_64BIT_TYPE
SDL_bool
SDL_AtomicTestThenSet64(volatile Uint64 * ptr)
{
#ifdef nativeTestThenSet64
#else
SDL_bool result = SDL_FALSE;
privateWaitLock(ptr);
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
privateUnlock(ptr);
return result;
#endif
}
void
SDL_AtomicClear64(volatile Uint64 * ptr)
{
#ifdef nativeClear64
#else
privateWaitLock(ptr);
*ptr = 0;
privateUnlock(ptr);
return;
#endif
}
Uint64
SDL_AtomicFetchThenIncrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenIncrement64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenDecrement64(volatile Uint64 * ptr)
{
#ifdef nativeFetchThenDecrement64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr) -= 1;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenAdd64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenAdd64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)+= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicFetchThenSubtract64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeFetchThenSubtract64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
tmp = *ptr;
(*ptr)-= value;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicIncrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeIncrementThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicDecrementThenFetch64(volatile Uint64 * ptr)
{
#ifdef nativeDecrementThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= 1;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicAddThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeAddThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)+= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
Uint64
SDL_AtomicSubtractThenFetch64(volatile Uint64 * ptr, Uint64 value)
{
#ifdef nativeSubtractThenFetch64
#else
Uint64 tmp = 0;
privateWaitLock(ptr);
(*ptr)-= value;
tmp = *ptr;
privateUnlock(ptr);
return tmp;
#endif
}
#endif
#include <stdio.h> #include <stdio.h>
#include "SDL.h" #include "SDL.h"
/* Make sure we have good macros for printing 32 and 64 bit values */
#ifndef PRIu32
#define PRIu32 "u"
#endif
#ifndef PRIu64
#ifdef __WIN32__
#define PRIu64 "I64u"
#else
#define PRIu64 "llu"
#endif
#endif
/* /*
Absolutely basic tests just to see if we get the expected value Absolutely basic tests just to see if we get the expected value
after calling each function. after calling each function.
...@@ -21,8 +9,8 @@ ...@@ -21,8 +9,8 @@
char * char *
tf(SDL_bool tf) tf(SDL_bool tf)
{ {
static char *t = "true"; static char *t = "TRUE";
static char *f = "false"; static char *f = "FALSE";
if (tf) if (tf)
{ {
...@@ -35,13 +23,7 @@ tf(SDL_bool tf) ...@@ -35,13 +23,7 @@ tf(SDL_bool tf)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int value;
volatile Uint32 val32 = 0;
Uint32 ret32 = 0;
volatile Uint64 val64 = 0;
Uint64 ret64 = 0;
SDL_SpinLock lock = 0; SDL_SpinLock lock = 0;
SDL_bool tfret = SDL_FALSE; SDL_bool tfret = SDL_FALSE;
...@@ -53,77 +35,34 @@ main(int argc, char *argv[]) ...@@ -53,77 +35,34 @@ main(int argc, char *argv[])
SDL_AtomicUnlock(&lock); SDL_AtomicUnlock(&lock);
printf("AtomicUnlock lock=%d\n", lock); printf("AtomicUnlock lock=%d\n", lock);
printf("\n32 bit -----------------------------------------\n\n"); printf("\natomic -----------------------------------------\n\n");
val32 = 0; SDL_atomic_t v;
tfret = SDL_AtomicTestThenSet32(&val32);
printf("TestThenSet32 tfret=%s val=%"PRIu32"\n", tf(tfret), val32); SDL_AtomicSet(&v, 0);
tfret = SDL_AtomicTestThenSet32(&val32); tfret = SDL_AtomicSet(&v, 10) == 0;
printf("TestThenSet32 tfret=%s val=%"PRIu32"\n", tf(tfret), val32); printf("AtomicSet(10) tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
tfret = SDL_AtomicAdd(&v, 10) == 10;
SDL_AtomicClear32(&val32); printf("AtomicAdd(10) tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
printf("Clear32 val=%"PRIu32"\n", val32);
SDL_AtomicSet(&v, 0);
ret32 = SDL_AtomicFetchThenIncrement32(&val32); SDL_AtomicIncRef(&v);
printf("FetchThenIncrement32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32); tfret = (SDL_AtomicGet(&v) == 1);
printf("AtomicIncRef() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
ret32 = SDL_AtomicFetchThenDecrement32(&val32); SDL_AtomicIncRef(&v);
printf("FetchThenDecrement32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32); tfret = (SDL_AtomicGet(&v) == 2);
printf("AtomicIncRef() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
ret32 = SDL_AtomicFetchThenAdd32(&val32, 10); tfret = (SDL_AtomicDecRef(&v) == SDL_FALSE);
printf("FetchThenAdd32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32); printf("AtomicDecRef() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
tfret = (SDL_AtomicDecRef(&v) == SDL_TRUE);
ret32 = SDL_AtomicFetchThenSubtract32(&val32, 10); printf("AtomicDecRef() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
printf("FetchThenSubtract32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
SDL_AtomicSet(&v, 10);
ret32 = SDL_AtomicIncrementThenFetch32(&val32); tfret = (SDL_AtomicCAS(&v, 0, 20) != 0);
printf("IncrementThenFetch32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32); printf("AtomicCAS() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
value = SDL_AtomicGet(&v);
ret32 = SDL_AtomicDecrementThenFetch32(&val32); tfret = (SDL_AtomicCAS(&v, value, 20) == value);
printf("DecrementThenFetch32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32); printf("AtomicCAS() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
ret32 = SDL_AtomicAddThenFetch32(&val32, 10);
printf("AddThenFetch32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
ret32 = SDL_AtomicSubtractThenFetch32(&val32, 10);
printf("SubtractThenFetch32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
#ifdef SDL_HAS_64BIT_TYPE
printf("\n64 bit -----------------------------------------\n\n");
val64 = 0;
tfret = SDL_AtomicTestThenSet64(&val64);
printf("TestThenSet64 tfret=%s val=%"PRIu64"\n", tf(tfret), val64);
tfret = SDL_AtomicTestThenSet64(&val64);
printf("TestThenSet64 tfret=%s val=%"PRIu64"\n", tf(tfret), val64);
SDL_AtomicClear64(&val64);
printf("Clear64 val=%"PRIu64"\n", val64);
ret64 = SDL_AtomicFetchThenIncrement64(&val64);
printf("FetchThenIncrement64 ret=%"PRIu64" val=%"PRIu64"\n", ret64, val64);
ret64 = SDL_AtomicFetchThenDecrement64(&val64);
printf("FetchThenDecrement64 ret=%"PRIu64" val=%"PRIu64"\n", ret64, val64);
ret64 = SDL_AtomicFetchThenAdd64(&val64, 10);
printf("FetchThenAdd64 ret=%"PRIu64" val=%"PRIu64"\n", ret64, val64);
ret64 = SDL_AtomicFetchThenSubtract64(&val64, 10);
printf("FetchThenSubtract64 ret=%"PRIu64" val=%"PRIu64"\n", ret64, val64);
ret64 = SDL_AtomicIncrementThenFetch64(&val64);
printf("IncrementThenFetch64 ret=%"PRIu64" val=%"PRIu64"\n", ret64, val64);
ret64 = SDL_AtomicDecrementThenFetch64(&val64);
printf("DecrementThenFetch64 ret=%"PRIu64" val=%"PRIu64"\n", ret64, val64);
ret64 = SDL_AtomicAddThenFetch64(&val64, 10);
printf("AddThenFetch64 ret=%"PRIu64" val=%"PRIu64"\n", ret64, val64);
ret64 = SDL_AtomicSubtractThenFetch64(&val64, 10);
printf("SubtractThenFetch64 ret=%"PRIu64" val=%"PRIu64"\n", ret64, val64);
#endif
return 0; 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