Updated the atomic API for better use cases
This commit is contained in:
parent
4084438113
commit
1bc8fe69ce
16 changed files with 488 additions and 2758 deletions
|
@ -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 \
|
||||||
$(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 @@
|
||||||
>
|
>
|
||||||
</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 @@
|
||||||
>
|
>
|
||||||
</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 >"$(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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
41
configure.in
41
configure.in
|
@ -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
|
||||||
;;
|
;;
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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,24 +18,34 @@
|
||||||
|
|
||||||
Sam Lantinga
|
Sam Lantinga
|
||||||
slouken@libsdl.org
|
slouken@libsdl.org
|
||||||
|
|
||||||
Contributed by Bob Pendleton, bob@pendleton.com
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file SDL_atomic.h
|
* \file SDL_atomic.h
|
||||||
*
|
*
|
||||||
* Atomic operations.
|
* Atomic operations.
|
||||||
*
|
*
|
||||||
* These operations may, or may not, actually be implemented using
|
* IMPORTANT:
|
||||||
* processor specific atomic operations. When possible they are
|
* If you are not an expert in concurrent lockless programming, you should
|
||||||
* implemented as true processor specific atomic operations. When that
|
* only be using the atomic lock and reference counting functions in this
|
||||||
* is not possible the are implemented using locks that *do* use the
|
* file. In all other cases you should be protecting your data structures
|
||||||
* available atomic operations.
|
* with full mutexes.
|
||||||
*
|
*
|
||||||
* At the very minimum spin locks must be implemented. Without spin
|
* The list of "safe" functions to use are:
|
||||||
* locks it is not possible (AFAICT) to emulate the rest of the atomic
|
* SDL_AtomicLock()
|
||||||
* operations.
|
* SDL_AtomicUnlock()
|
||||||
|
* SDL_AtomicIncRef()
|
||||||
|
* SDL_AtomicDecRef()
|
||||||
|
*
|
||||||
|
* Seriously, here be dragons!
|
||||||
|
*
|
||||||
|
* These operations may, or may not, actually be implemented using
|
||||||
|
* processor specific atomic operations. When possible they are
|
||||||
|
* implemented as true processor specific atomic operations. When that
|
||||||
|
* is not possible the are implemented using locks that *do* use the
|
||||||
|
* available atomic operations.
|
||||||
|
*
|
||||||
|
* All of the atomic operations that modify memory are full memory barriers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SDL_atomic_h_
|
#ifndef _SDL_atomic_h_
|
||||||
|
@ -53,154 +63,138 @@ extern "C" {
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \name SDL AtomicLock
|
* \name SDL AtomicLock
|
||||||
*
|
*
|
||||||
* The spin lock functions and type are required and can not be
|
* The atomic locks are efficient spinlocks using CPU instructions,
|
||||||
* emulated because they are used in the emulation code.
|
* 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
|
||||||
|
* 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.
|
* \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.
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock);
|
extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Unlock a spin lock by setting it to 0. Always returns immediately
|
* \brief Unlock a spin lock by setting it to 0. Always returns immediately
|
||||||
*
|
*
|
||||||
* \param lock Points to the lock.
|
* \param lock Points to the lock.
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock);
|
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.
|
* \return SDL_TRUE if the variable has reached zero after decrementing,
|
||||||
*
|
* SDL_FALSE otherwise
|
||||||
* \param ptr The address of the data being changed.
|
|
||||||
* \param value The value to subtract from \c *ptr.
|
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
|
179
src/atomic/SDL_atomic.c
Normal file
179
src/atomic/SDL_atomic.c
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
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: */
|
99
src/atomic/SDL_spinlock.c
Normal file
99
src/atomic/SDL_spinlock.c
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
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: */
|
|
@ -1,469 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
|
|
|
@ -1,510 +0,0 @@
|
||||||
/*
|
|
||||||
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 */
|
|
|
@ -1,469 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
|
|
|
@ -1,505 +0,0 @@
|
||||||
/*
|
|
||||||
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 */
|
|
|
@ -1,512 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
|
|
|
@ -1,18 +1,6 @@
|
||||||
#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,109 +9,60 @@
|
||||||
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)
|
||||||
{
|
{
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
int value;
|
||||||
|
SDL_SpinLock lock = 0;
|
||||||
|
|
||||||
volatile Uint32 val32 = 0;
|
SDL_bool tfret = SDL_FALSE;
|
||||||
Uint32 ret32 = 0;
|
|
||||||
|
|
||||||
volatile Uint64 val64 = 0;
|
printf("\nspin lock---------------------------------------\n\n");
|
||||||
Uint64 ret64 = 0;
|
|
||||||
|
|
||||||
SDL_SpinLock lock = 0;
|
SDL_AtomicLock(&lock);
|
||||||
|
printf("AtomicLock lock=%d\n", lock);
|
||||||
|
SDL_AtomicUnlock(&lock);
|
||||||
|
printf("AtomicUnlock lock=%d\n", lock);
|
||||||
|
|
||||||
SDL_bool tfret = SDL_FALSE;
|
printf("\natomic -----------------------------------------\n\n");
|
||||||
|
|
||||||
printf("\nspin lock---------------------------------------\n\n");
|
SDL_atomic_t v;
|
||||||
|
|
||||||
SDL_AtomicLock(&lock);
|
SDL_AtomicSet(&v, 0);
|
||||||
printf("AtomicLock lock=%d\n", lock);
|
tfret = SDL_AtomicSet(&v, 10) == 0;
|
||||||
SDL_AtomicUnlock(&lock);
|
printf("AtomicSet(10) tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
|
||||||
printf("AtomicUnlock lock=%d\n", lock);
|
tfret = SDL_AtomicAdd(&v, 10) == 10;
|
||||||
|
printf("AtomicAdd(10) tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
|
||||||
|
|
||||||
printf("\n32 bit -----------------------------------------\n\n");
|
SDL_AtomicSet(&v, 0);
|
||||||
|
SDL_AtomicIncRef(&v);
|
||||||
|
tfret = (SDL_AtomicGet(&v) == 1);
|
||||||
|
printf("AtomicIncRef() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
|
||||||
|
SDL_AtomicIncRef(&v);
|
||||||
|
tfret = (SDL_AtomicGet(&v) == 2);
|
||||||
|
printf("AtomicIncRef() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
|
||||||
|
tfret = (SDL_AtomicDecRef(&v) == SDL_FALSE);
|
||||||
|
printf("AtomicDecRef() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
|
||||||
|
tfret = (SDL_AtomicDecRef(&v) == SDL_TRUE);
|
||||||
|
printf("AtomicDecRef() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
|
||||||
|
|
||||||
val32 = 0;
|
SDL_AtomicSet(&v, 10);
|
||||||
tfret = SDL_AtomicTestThenSet32(&val32);
|
tfret = (SDL_AtomicCAS(&v, 0, 20) != 0);
|
||||||
printf("TestThenSet32 tfret=%s val=%"PRIu32"\n", tf(tfret), val32);
|
printf("AtomicCAS() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
|
||||||
tfret = SDL_AtomicTestThenSet32(&val32);
|
value = SDL_AtomicGet(&v);
|
||||||
printf("TestThenSet32 tfret=%s val=%"PRIu32"\n", tf(tfret), val32);
|
tfret = (SDL_AtomicCAS(&v, value, 20) == value);
|
||||||
|
printf("AtomicCAS() tfret=%s val=%"PRIu32"\n", tf(tfret), SDL_AtomicGet(&v));
|
||||||
|
|
||||||
SDL_AtomicClear32(&val32);
|
return 0;
|
||||||
printf("Clear32 val=%"PRIu32"\n", val32);
|
}
|
||||||
|
|
||||||
ret32 = SDL_AtomicFetchThenIncrement32(&val32);
|
|
||||||
printf("FetchThenIncrement32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
|
|
||||||
|
|
||||||
ret32 = SDL_AtomicFetchThenDecrement32(&val32);
|
|
||||||
printf("FetchThenDecrement32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
|
|
||||||
|
|
||||||
ret32 = SDL_AtomicFetchThenAdd32(&val32, 10);
|
|
||||||
printf("FetchThenAdd32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
|
|
||||||
|
|
||||||
ret32 = SDL_AtomicFetchThenSubtract32(&val32, 10);
|
|
||||||
printf("FetchThenSubtract32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
|
|
||||||
|
|
||||||
ret32 = SDL_AtomicIncrementThenFetch32(&val32);
|
|
||||||
printf("IncrementThenFetch32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
|
|
||||||
|
|
||||||
ret32 = SDL_AtomicDecrementThenFetch32(&val32);
|
|
||||||
printf("DecrementThenFetch32 ret=%"PRIu32" val=%"PRIu32"\n", ret32, val32);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue