Implemented an API for thread-local storage: SDL_TLSCreate(), SDL_TLSSet(), SDL_TLSGet()
This commit is contained in:
parent
ab91b4ce14
commit
bfcb08d569
14 changed files with 618 additions and 156 deletions
|
@ -1132,6 +1132,10 @@
|
||||||
RelativePath="..\..\src\thread\windows\SDL_systhread.c"
|
RelativePath="..\..\src\thread\windows\SDL_systhread.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\thread\windows\SDL_systls.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\thread\SDL_systhread.h"
|
RelativePath="..\..\src\thread\SDL_systhread.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -438,6 +438,7 @@
|
||||||
<ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
|
<ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
|
||||||
<ClCompile Include="..\..\src\thread\windows\SDL_syssem.c" />
|
<ClCompile Include="..\..\src\thread\windows\SDL_syssem.c" />
|
||||||
<ClCompile Include="..\..\src\thread\windows\SDL_systhread.c" />
|
<ClCompile Include="..\..\src\thread\windows\SDL_systhread.c" />
|
||||||
|
<ClCompile Include="..\..\src\thread\windows\SDL_systls.c" />
|
||||||
<ClCompile Include="..\..\src\timer\windows\SDL_systimer.c" />
|
<ClCompile Include="..\..\src\timer\windows\SDL_systimer.c" />
|
||||||
<ClCompile Include="..\..\src\thread\SDL_thread.c" />
|
<ClCompile Include="..\..\src\thread\SDL_thread.c" />
|
||||||
<ClCompile Include="..\..\src\timer\SDL_timer.c" />
|
<ClCompile Include="..\..\src\timer\SDL_timer.c" />
|
||||||
|
@ -462,4 +463,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -441,6 +441,7 @@
|
||||||
<ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
|
<ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
|
||||||
<ClCompile Include="..\..\src\thread\windows\SDL_syssem.c" />
|
<ClCompile Include="..\..\src\thread\windows\SDL_syssem.c" />
|
||||||
<ClCompile Include="..\..\src\thread\windows\SDL_systhread.c" />
|
<ClCompile Include="..\..\src\thread\windows\SDL_systhread.c" />
|
||||||
|
<ClCompile Include="..\..\src\thread\windows\SDL_systls.c" />
|
||||||
<ClCompile Include="..\..\src\timer\windows\SDL_systimer.c" />
|
<ClCompile Include="..\..\src\timer\windows\SDL_systimer.c" />
|
||||||
<ClCompile Include="..\..\src\thread\SDL_thread.c" />
|
<ClCompile Include="..\..\src\thread\SDL_thread.c" />
|
||||||
<ClCompile Include="..\..\src\timer\SDL_timer.c" />
|
<ClCompile Include="..\..\src\timer\SDL_timer.c" />
|
||||||
|
@ -466,4 +467,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
93CB792613FC5F5300BD3E05 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */; };
|
93CB792613FC5F5300BD3E05 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */; };
|
||||||
AA0AD06216647BBB00CE5896 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */; };
|
AA0AD06216647BBB00CE5896 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */; };
|
||||||
AA0AD06516647BD400CE5896 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = AA0AD06416647BD400CE5896 /* SDL_gamecontroller.h */; };
|
AA0AD06516647BD400CE5896 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = AA0AD06416647BD400CE5896 /* SDL_gamecontroller.h */; };
|
||||||
|
AA0F8495178D5F1A00823F9D /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0F8494178D5F1A00823F9D /* SDL_systls.c */; };
|
||||||
AA126AD41617C5E7005ABC8F /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = AA126AD21617C5E6005ABC8F /* SDL_uikitmodes.h */; };
|
AA126AD41617C5E7005ABC8F /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = AA126AD21617C5E6005ABC8F /* SDL_uikitmodes.h */; };
|
||||||
AA126AD51617C5E7005ABC8F /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = AA126AD31617C5E6005ABC8F /* SDL_uikitmodes.m */; };
|
AA126AD51617C5E7005ABC8F /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = AA126AD31617C5E6005ABC8F /* SDL_uikitmodes.m */; };
|
||||||
AA628ADB159369E3005138DD /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628AD9159369E3005138DD /* SDL_rotate.c */; };
|
AA628ADB159369E3005138DD /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628AD9159369E3005138DD /* SDL_rotate.c */; };
|
||||||
|
@ -268,6 +269,7 @@
|
||||||
93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitviewcontroller.m; sourceTree = "<group>"; };
|
93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitviewcontroller.m; sourceTree = "<group>"; };
|
||||||
AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gamecontroller.c; sourceTree = "<group>"; };
|
AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gamecontroller.c; sourceTree = "<group>"; };
|
||||||
AA0AD06416647BD400CE5896 /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = "<group>"; };
|
AA0AD06416647BD400CE5896 /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = "<group>"; };
|
||||||
|
AA0F8494178D5F1A00823F9D /* SDL_systls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_systls.c; sourceTree = "<group>"; };
|
||||||
AA126AD21617C5E6005ABC8F /* SDL_uikitmodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitmodes.h; sourceTree = "<group>"; };
|
AA126AD21617C5E6005ABC8F /* SDL_uikitmodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitmodes.h; sourceTree = "<group>"; };
|
||||||
AA126AD31617C5E6005ABC8F /* SDL_uikitmodes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitmodes.m; sourceTree = "<group>"; };
|
AA126AD31617C5E6005ABC8F /* SDL_uikitmodes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitmodes.m; sourceTree = "<group>"; };
|
||||||
AA628AD9159369E3005138DD /* SDL_rotate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_rotate.c; sourceTree = "<group>"; };
|
AA628AD9159369E3005138DD /* SDL_rotate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_rotate.c; sourceTree = "<group>"; };
|
||||||
|
@ -851,6 +853,7 @@
|
||||||
FD99BA0A0DD52EDC00FB1D6B /* SDL_syssem.c */,
|
FD99BA0A0DD52EDC00FB1D6B /* SDL_syssem.c */,
|
||||||
FD99BA0B0DD52EDC00FB1D6B /* SDL_systhread.c */,
|
FD99BA0B0DD52EDC00FB1D6B /* SDL_systhread.c */,
|
||||||
FD99BA0C0DD52EDC00FB1D6B /* SDL_systhread_c.h */,
|
FD99BA0C0DD52EDC00FB1D6B /* SDL_systhread_c.h */,
|
||||||
|
AA0F8494178D5F1A00823F9D /* SDL_systls.c */,
|
||||||
);
|
);
|
||||||
path = pthread;
|
path = pthread;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1189,6 +1192,7 @@
|
||||||
AA704DD7162AA90A0076D1C1 /* SDL_dropevents.c in Sources */,
|
AA704DD7162AA90A0076D1C1 /* SDL_dropevents.c in Sources */,
|
||||||
AABCC3951640643D00AB8930 /* SDL_uikitmessagebox.m in Sources */,
|
AABCC3951640643D00AB8930 /* SDL_uikitmessagebox.m in Sources */,
|
||||||
AA0AD06216647BBB00CE5896 /* SDL_gamecontroller.c in Sources */,
|
AA0AD06216647BBB00CE5896 /* SDL_gamecontroller.c in Sources */,
|
||||||
|
AA0F8495178D5F1A00823F9D /* SDL_systls.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -398,6 +398,9 @@
|
||||||
A77E6EB4167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
A77E6EB4167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
A77E6EB5167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; };
|
A77E6EB5167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; };
|
||||||
AA0AD09D16648D1700CE5896 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = BBFC088A164C6514003E6A99 /* SDL_gamecontroller.c */; };
|
AA0AD09D16648D1700CE5896 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = BBFC088A164C6514003E6A99 /* SDL_gamecontroller.c */; };
|
||||||
|
AA0F8491178D5ECC00823F9D /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0F8490178D5ECC00823F9D /* SDL_systls.c */; };
|
||||||
|
AA0F8492178D5ECC00823F9D /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0F8490178D5ECC00823F9D /* SDL_systls.c */; };
|
||||||
|
AA0F8493178D5ECC00823F9D /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0F8490178D5ECC00823F9D /* SDL_systls.c */; };
|
||||||
AA41F88014B8F1F500993C4F /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = 566CDE8E148F0AC200C5A9BB /* SDL_dropevents.c */; };
|
AA41F88014B8F1F500993C4F /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = 566CDE8E148F0AC200C5A9BB /* SDL_dropevents.c */; };
|
||||||
AA628ACA159367B7005138DD /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628AC8159367B7005138DD /* SDL_rotate.c */; };
|
AA628ACA159367B7005138DD /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628AC8159367B7005138DD /* SDL_rotate.c */; };
|
||||||
AA628ACB159367B7005138DD /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628AC8159367B7005138DD /* SDL_rotate.c */; };
|
AA628ACB159367B7005138DD /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628AC8159367B7005138DD /* SDL_rotate.c */; };
|
||||||
|
@ -984,6 +987,7 @@
|
||||||
566CDE8D148F0AC200C5A9BB /* SDL_dropevents_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dropevents_c.h; sourceTree = "<group>"; };
|
566CDE8D148F0AC200C5A9BB /* SDL_dropevents_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dropevents_c.h; sourceTree = "<group>"; };
|
||||||
566CDE8E148F0AC200C5A9BB /* SDL_dropevents.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dropevents.c; sourceTree = "<group>"; };
|
566CDE8E148F0AC200C5A9BB /* SDL_dropevents.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dropevents.c; sourceTree = "<group>"; };
|
||||||
A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = "<group>"; };
|
A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = "<group>"; };
|
||||||
|
AA0F8490178D5ECC00823F9D /* SDL_systls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_systls.c; sourceTree = "<group>"; };
|
||||||
AA628AC8159367B7005138DD /* SDL_rotate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_rotate.c; sourceTree = "<group>"; };
|
AA628AC8159367B7005138DD /* SDL_rotate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_rotate.c; sourceTree = "<group>"; };
|
||||||
AA628AC9159367B7005138DD /* SDL_rotate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_rotate.h; sourceTree = "<group>"; };
|
AA628AC9159367B7005138DD /* SDL_rotate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_rotate.h; sourceTree = "<group>"; };
|
||||||
AA628ACF159367F2005138DD /* SDL_x11xinput2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11xinput2.c; sourceTree = "<group>"; };
|
AA628ACF159367F2005138DD /* SDL_x11xinput2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11xinput2.c; sourceTree = "<group>"; };
|
||||||
|
@ -1462,6 +1466,7 @@
|
||||||
04BDFE8112E6671800899322 /* SDL_syssem.c */,
|
04BDFE8112E6671800899322 /* SDL_syssem.c */,
|
||||||
04BDFE8212E6671800899322 /* SDL_systhread.c */,
|
04BDFE8212E6671800899322 /* SDL_systhread.c */,
|
||||||
04BDFE8312E6671800899322 /* SDL_systhread_c.h */,
|
04BDFE8312E6671800899322 /* SDL_systhread_c.h */,
|
||||||
|
AA0F8490178D5ECC00823F9D /* SDL_systls.c */,
|
||||||
);
|
);
|
||||||
path = pthread;
|
path = pthread;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2403,6 +2408,7 @@
|
||||||
AA9E4093163BE51E007A2AD0 /* SDL_x11messagebox.c in Sources */,
|
AA9E4093163BE51E007A2AD0 /* SDL_x11messagebox.c in Sources */,
|
||||||
AABCC38F164063D200AB8930 /* SDL_cocoamessagebox.m in Sources */,
|
AABCC38F164063D200AB8930 /* SDL_cocoamessagebox.m in Sources */,
|
||||||
AA0AD09D16648D1700CE5896 /* SDL_gamecontroller.c in Sources */,
|
AA0AD09D16648D1700CE5896 /* SDL_gamecontroller.c in Sources */,
|
||||||
|
AA0F8491178D5ECC00823F9D /* SDL_systls.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -2519,6 +2525,7 @@
|
||||||
AA628AD2159367F2005138DD /* SDL_x11xinput2.c in Sources */,
|
AA628AD2159367F2005138DD /* SDL_x11xinput2.c in Sources */,
|
||||||
AA9E4094163BE51E007A2AD0 /* SDL_x11messagebox.c in Sources */,
|
AA9E4094163BE51E007A2AD0 /* SDL_x11messagebox.c in Sources */,
|
||||||
AABCC390164063D200AB8930 /* SDL_cocoamessagebox.m in Sources */,
|
AABCC390164063D200AB8930 /* SDL_cocoamessagebox.m in Sources */,
|
||||||
|
AA0F8492178D5ECC00823F9D /* SDL_systls.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -2635,6 +2642,7 @@
|
||||||
DB31406817554B71006C0E22 /* SDL_x11xinput2.c in Sources */,
|
DB31406817554B71006C0E22 /* SDL_x11xinput2.c in Sources */,
|
||||||
DB31406917554B71006C0E22 /* SDL_x11messagebox.c in Sources */,
|
DB31406917554B71006C0E22 /* SDL_x11messagebox.c in Sources */,
|
||||||
DB31406A17554B71006C0E22 /* SDL_cocoamessagebox.m in Sources */,
|
DB31406A17554B71006C0E22 /* SDL_cocoamessagebox.m in Sources */,
|
||||||
|
AA0F8493178D5ECC00823F9D /* SDL_systls.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
25
configure
vendored
25
configure
vendored
|
@ -1511,7 +1511,7 @@ Optional Features:
|
||||||
--enable-sse use SSE assembly routines [[default=yes]]
|
--enable-sse use SSE assembly routines [[default=yes]]
|
||||||
--enable-sse2 use SSE2 assembly routines [[default=no]]
|
--enable-sse2 use SSE2 assembly routines [[default=no]]
|
||||||
--enable-altivec use Altivec assembly routines [[default=yes]]
|
--enable-altivec use Altivec assembly routines [[default=yes]]
|
||||||
--enable-oss support the OSS audio API [[default=yes]]
|
--enable-oss support the OSS audio API [[default=maybe]]
|
||||||
--enable-alsa support the ALSA audio API [[default=yes]]
|
--enable-alsa support the ALSA audio API [[default=yes]]
|
||||||
--disable-alsatest Do not try to compile and run a test Alsa program
|
--disable-alsatest Do not try to compile and run a test Alsa program
|
||||||
--enable-alsa-shared dynamically load ALSA audio support [[default=yes]]
|
--enable-alsa-shared dynamically load ALSA audio support [[default=yes]]
|
||||||
|
@ -17535,9 +17535,21 @@ CheckOSS()
|
||||||
if test "${enable_oss+set}" = set; then :
|
if test "${enable_oss+set}" = set; then :
|
||||||
enableval=$enable_oss;
|
enableval=$enable_oss;
|
||||||
else
|
else
|
||||||
enable_oss=yes
|
enable_oss=maybe
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# OpenBSD "has" OSS, but it's not really for app use. They want you to
|
||||||
|
# use sndio instead. So on there, we default to disabled. You can force
|
||||||
|
# it on if you really want, though.
|
||||||
|
if test x$enable_oss = xmaybe; then
|
||||||
|
enable_oss=yes
|
||||||
|
case "$host" in
|
||||||
|
*-*-openbsd*)
|
||||||
|
enable_oss=no;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
if test x$enable_audio = xyes -a x$enable_oss = xyes; then
|
if test x$enable_audio = xyes -a x$enable_oss = xyes; then
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSS audio support" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSS audio support" >&5
|
||||||
$as_echo_n "checking for OSS audio support... " >&6; }
|
$as_echo_n "checking for OSS audio support... " >&6; }
|
||||||
|
@ -21423,6 +21435,9 @@ $as_echo "$has_pthread_set_name_np" >&6; }
|
||||||
# We can fake these with semaphores and mutexes if necessary
|
# We can fake these with semaphores and mutexes if necessary
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/pthread/SDL_syscond.c"
|
SOURCES="$SOURCES $srcdir/src/thread/pthread/SDL_syscond.c"
|
||||||
|
|
||||||
|
# Thread local storage
|
||||||
|
SOURCES="$SOURCES $srcdir/src/thread/pthread/SDL_systls.c"
|
||||||
|
|
||||||
have_threads=yes
|
have_threads=yes
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -22206,7 +22221,7 @@ $as_echo "#define SDL_AUDIO_DRIVER_SUNAUDIO 1" >>confdefs.h
|
||||||
SOURCES="$SOURCES $srcdir/src/audio/sun/*.c"
|
SOURCES="$SOURCES $srcdir/src/audio/sun/*.c"
|
||||||
have_audio=yes
|
have_audio=yes
|
||||||
;;
|
;;
|
||||||
netbsd|openbsd)
|
netbsd) # Don't use this on OpenBSD, it's busted.
|
||||||
|
|
||||||
$as_echo "#define SDL_AUDIO_DRIVER_BSD 1" >>confdefs.h
|
$as_echo "#define SDL_AUDIO_DRIVER_BSD 1" >>confdefs.h
|
||||||
|
|
||||||
|
@ -22367,9 +22382,7 @@ $as_echo "#define SDL_POWER_WINDOWS 1" >>confdefs.h
|
||||||
|
|
||||||
$as_echo "#define SDL_THREAD_WINDOWS 1" >>confdefs.h
|
$as_echo "#define SDL_THREAD_WINDOWS 1" >>confdefs.h
|
||||||
|
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_sysmutex.c"
|
SOURCES="$SOURCES $srcdir/src/thread/windows/*.c"
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_syssem.c"
|
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_systhread.c"
|
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c"
|
SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c"
|
||||||
have_threads=yes
|
have_threads=yes
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -657,6 +657,7 @@ AC_HELP_STRING([--enable-oss], [support the OSS audio API [[default=maybe]]]),
|
||||||
case "$host" in
|
case "$host" in
|
||||||
*-*-openbsd*)
|
*-*-openbsd*)
|
||||||
enable_oss=no;;
|
enable_oss=no;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$enable_audio = xyes -a x$enable_oss = xyes; then
|
if test x$enable_audio = xyes -a x$enable_oss = xyes; then
|
||||||
|
@ -2019,6 +2020,9 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]])
|
||||||
# We can fake these with semaphores and mutexes if necessary
|
# We can fake these with semaphores and mutexes if necessary
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/pthread/SDL_syscond.c"
|
SOURCES="$SOURCES $srcdir/src/thread/pthread/SDL_syscond.c"
|
||||||
|
|
||||||
|
# Thread local storage
|
||||||
|
SOURCES="$SOURCES $srcdir/src/thread/pthread/SDL_systls.c"
|
||||||
|
|
||||||
have_threads=yes
|
have_threads=yes
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -2470,9 +2474,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
|
||||||
# Set up files for the thread library
|
# Set up files for the thread library
|
||||||
if test x$enable_threads = xyes; then
|
if test x$enable_threads = xyes; then
|
||||||
AC_DEFINE(SDL_THREAD_WINDOWS, 1, [ ])
|
AC_DEFINE(SDL_THREAD_WINDOWS, 1, [ ])
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_sysmutex.c"
|
SOURCES="$SOURCES $srcdir/src/thread/windows/*.c"
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_syssem.c"
|
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_systhread.c"
|
|
||||||
SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c"
|
SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c"
|
||||||
have_threads=yes
|
have_threads=yes
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "SDL_error.h"
|
#include "SDL_error.h"
|
||||||
|
|
||||||
/* Thread synchronization primitives */
|
/* Thread synchronization primitives */
|
||||||
|
#include "SDL_atomic.h"
|
||||||
#include "SDL_mutex.h"
|
#include "SDL_mutex.h"
|
||||||
|
|
||||||
#include "begin_code.h"
|
#include "begin_code.h"
|
||||||
|
@ -47,6 +48,9 @@ typedef struct SDL_Thread SDL_Thread;
|
||||||
/* The SDL thread ID */
|
/* The SDL thread ID */
|
||||||
typedef unsigned long SDL_threadID;
|
typedef unsigned long SDL_threadID;
|
||||||
|
|
||||||
|
/* Thread local storage ID */
|
||||||
|
typedef int SDL_TLSID;
|
||||||
|
|
||||||
/* The SDL thread priority
|
/* The SDL thread priority
|
||||||
*
|
*
|
||||||
* Note: On many systems you require special privileges to set high priority.
|
* Note: On many systems you require special privileges to set high priority.
|
||||||
|
@ -166,6 +170,63 @@ extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_ThreadPriority priority);
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status);
|
extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Create an identifier that is globally visible to all threads but refers to data that is thread-specific.
|
||||||
|
*
|
||||||
|
* \return The newly created thread local storage identifier, or 0 on error
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* static SDL_SpinLock tls_lock;
|
||||||
|
* static SDL_TLSID thread_local_storage;
|
||||||
|
*
|
||||||
|
* void SetMyThreadData(void *value)
|
||||||
|
* {
|
||||||
|
* if (!thread_local_storage) {
|
||||||
|
* SDL_AtomicLock(&tls_lock);
|
||||||
|
* if (!thread_local_storage) {
|
||||||
|
* thread_local_storage = SDL_TLSCreate();
|
||||||
|
* }
|
||||||
|
* SDL_AtomicUnLock(&tls_lock);
|
||||||
|
* }
|
||||||
|
* SDL_TLSSet(thread_local_storage, value);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* void *GetMyThreadData(void)
|
||||||
|
* {
|
||||||
|
* return SDL_TLSGet(thread_local_storage);
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \sa SDL_TLSGet()
|
||||||
|
* \sa SDL_TLSSet()
|
||||||
|
*/
|
||||||
|
extern DECLSPEC SDL_TLSID SDLCALL SDL_TLSCreate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get the value associated with a thread local storage ID for the current thread.
|
||||||
|
*
|
||||||
|
* \param id The thread local storage ID
|
||||||
|
*
|
||||||
|
* \return The value associated with the ID for the current thread, or NULL if no value has been set.
|
||||||
|
*
|
||||||
|
* \sa SDL_TLSCreate()
|
||||||
|
* \sa SDL_TLSSet()
|
||||||
|
*/
|
||||||
|
extern DECLSPEC void * SDLCALL SDL_TLSGet(SDL_TLSID id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the value associated with a thread local storage ID for the current thread.
|
||||||
|
*
|
||||||
|
* \param id The thread local storage ID
|
||||||
|
* \param value The value to associate with the ID for the current thread
|
||||||
|
*
|
||||||
|
* \return 0 on success, -1 on error
|
||||||
|
*
|
||||||
|
* \sa SDL_TLSCreate()
|
||||||
|
* \sa SDL_TLSGet()
|
||||||
|
*/
|
||||||
|
extern DECLSPEC int SDLCALL SDL_TLSSet(SDL_TLSID id, const void *value);
|
||||||
|
|
||||||
|
|
||||||
/* Ends C function definitions when using C++ */
|
/* Ends C function definitions when using C++ */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -22,158 +22,46 @@
|
||||||
|
|
||||||
/* System independent thread management routines for SDL */
|
/* System independent thread management routines for SDL */
|
||||||
|
|
||||||
#include "SDL_mutex.h"
|
|
||||||
#include "SDL_thread.h"
|
#include "SDL_thread.h"
|
||||||
#include "SDL_thread_c.h"
|
#include "SDL_thread_c.h"
|
||||||
#include "SDL_systhread.h"
|
#include "SDL_systhread.h"
|
||||||
#include "../SDL_error_c.h"
|
#include "../SDL_error_c.h"
|
||||||
|
|
||||||
#define ARRAY_CHUNKSIZE 32
|
|
||||||
/* The array of threads currently active in the application
|
|
||||||
(except the main thread)
|
|
||||||
The manipulation of an array here is safer than using a linked list.
|
|
||||||
*/
|
|
||||||
static int SDL_maxthreads = 0;
|
|
||||||
static int SDL_numthreads = 0;
|
|
||||||
static SDL_Thread **SDL_Threads = NULL;
|
|
||||||
static SDL_mutex *thread_lock = NULL;
|
|
||||||
|
|
||||||
static int
|
|
||||||
SDL_ThreadsInit(void)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
retval = 0;
|
|
||||||
thread_lock = SDL_CreateMutex();
|
|
||||||
if (thread_lock == NULL) {
|
|
||||||
retval = -1;
|
|
||||||
}
|
|
||||||
return (retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This should never be called...
|
|
||||||
If this is called by SDL_Quit(), we don't know whether or not we should
|
|
||||||
clean up threads here. If any threads are still running after this call,
|
|
||||||
they will no longer have access to any per-thread data.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
static void
|
|
||||||
SDL_ThreadsQuit(void)
|
|
||||||
{
|
|
||||||
SDL_mutex *mutex;
|
|
||||||
|
|
||||||
mutex = thread_lock;
|
|
||||||
thread_lock = NULL;
|
|
||||||
if (mutex != NULL) {
|
|
||||||
SDL_DestroyMutex(mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Routines for manipulating the thread list */
|
|
||||||
static void
|
|
||||||
SDL_AddThread(SDL_Thread * thread)
|
|
||||||
{
|
|
||||||
/* WARNING:
|
|
||||||
If the very first threads are created simultaneously, then
|
|
||||||
there could be a race condition causing memory corruption.
|
|
||||||
In practice, this isn't a problem because by definition there
|
|
||||||
is only one thread running the first time this is called.
|
|
||||||
*/
|
|
||||||
if (!thread_lock) {
|
|
||||||
if (SDL_ThreadsInit() < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDL_LockMutex(thread_lock);
|
|
||||||
|
|
||||||
/* Expand the list of threads, if necessary */
|
|
||||||
#ifdef DEBUG_THREADS
|
|
||||||
printf("Adding thread (%d already - %d max)\n",
|
|
||||||
SDL_numthreads, SDL_maxthreads);
|
|
||||||
#endif
|
|
||||||
if (SDL_numthreads == SDL_maxthreads) {
|
|
||||||
SDL_Thread **threads;
|
|
||||||
threads = (SDL_Thread **) SDL_realloc(SDL_Threads,
|
|
||||||
(SDL_maxthreads +
|
|
||||||
ARRAY_CHUNKSIZE) *
|
|
||||||
(sizeof *threads));
|
|
||||||
if (threads == NULL) {
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
SDL_maxthreads += ARRAY_CHUNKSIZE;
|
|
||||||
SDL_Threads = threads;
|
|
||||||
}
|
|
||||||
SDL_Threads[SDL_numthreads++] = thread;
|
|
||||||
done:
|
|
||||||
SDL_mutexV(thread_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
SDL_DelThread(SDL_Thread * thread)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!thread_lock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SDL_LockMutex(thread_lock);
|
|
||||||
for (i = 0; i < SDL_numthreads; ++i) {
|
|
||||||
if (thread == SDL_Threads[i]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i < SDL_numthreads) {
|
|
||||||
if (--SDL_numthreads > 0) {
|
|
||||||
while (i < SDL_numthreads) {
|
|
||||||
SDL_Threads[i] = SDL_Threads[i + 1];
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SDL_maxthreads = 0;
|
|
||||||
SDL_free(SDL_Threads);
|
|
||||||
SDL_Threads = NULL;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_THREADS
|
|
||||||
printf("Deleting thread (%d left - %d max)\n",
|
|
||||||
SDL_numthreads, SDL_maxthreads);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
SDL_mutexV(thread_lock);
|
|
||||||
|
|
||||||
#if 0 /* There could be memory corruption if another thread is starting */
|
|
||||||
if (SDL_Threads == NULL) {
|
|
||||||
SDL_ThreadsQuit();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The default (non-thread-safe) global error variable */
|
|
||||||
static SDL_error SDL_global_error;
|
|
||||||
|
|
||||||
/* Routine to get the thread-specific error variable */
|
/* Routine to get the thread-specific error variable */
|
||||||
SDL_error *
|
SDL_error *
|
||||||
SDL_GetErrBuf(void)
|
SDL_GetErrBuf(void)
|
||||||
{
|
{
|
||||||
|
static SDL_SpinLock spinlock;
|
||||||
|
static SDL_bool tls_being_created;
|
||||||
|
static SDL_TLSID tls_errbuf;
|
||||||
|
static SDL_error SDL_global_errbuf;
|
||||||
SDL_error *errbuf;
|
SDL_error *errbuf;
|
||||||
|
|
||||||
errbuf = &SDL_global_error;
|
if (!tls_errbuf && !tls_being_created) {
|
||||||
if (SDL_Threads) {
|
SDL_AtomicLock(&spinlock);
|
||||||
int i;
|
if (!tls_errbuf) {
|
||||||
SDL_threadID this_thread;
|
/* SDL_TLSCreate() could fail and call SDL_SetError() */
|
||||||
|
tls_being_created = SDL_TRUE;
|
||||||
this_thread = SDL_ThreadID();
|
tls_errbuf = SDL_TLSCreate();
|
||||||
SDL_LockMutex(thread_lock);
|
tls_being_created = SDL_FALSE;
|
||||||
for (i = 0; i < SDL_numthreads; ++i) {
|
|
||||||
if (this_thread == SDL_Threads[i]->threadid) {
|
|
||||||
errbuf = &SDL_Threads[i]->errbuf;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SDL_mutexV(thread_lock);
|
SDL_AtomicUnlock(&spinlock);
|
||||||
}
|
}
|
||||||
return (errbuf);
|
if (!tls_errbuf) {
|
||||||
|
return &SDL_global_errbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
errbuf = SDL_TLSGet(tls_errbuf);
|
||||||
|
if (!errbuf) {
|
||||||
|
errbuf = (SDL_error *)SDL_malloc(sizeof(*errbuf));
|
||||||
|
if (!errbuf) {
|
||||||
|
return &SDL_global_errbuf;
|
||||||
|
}
|
||||||
|
SDL_zerop(errbuf);
|
||||||
|
SDL_TLSSet(tls_errbuf, errbuf);
|
||||||
|
}
|
||||||
|
return errbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,9 +152,6 @@ SDL_CreateThread(int (SDLCALL * fn) (void *),
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the thread to the list of available threads */
|
|
||||||
SDL_AddThread(thread);
|
|
||||||
|
|
||||||
/* Create the thread and go! */
|
/* Create the thread and go! */
|
||||||
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||||
ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread);
|
ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread);
|
||||||
|
@ -278,7 +163,6 @@ SDL_CreateThread(int (SDLCALL * fn) (void *),
|
||||||
SDL_SemWait(args->wait);
|
SDL_SemWait(args->wait);
|
||||||
} else {
|
} else {
|
||||||
/* Oops, failed. Gotta free everything */
|
/* Oops, failed. Gotta free everything */
|
||||||
SDL_DelThread(thread);
|
|
||||||
SDL_free(thread->name);
|
SDL_free(thread->name);
|
||||||
SDL_free(thread);
|
SDL_free(thread);
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
|
@ -323,7 +207,6 @@ SDL_WaitThread(SDL_Thread * thread, int *status)
|
||||||
if (status) {
|
if (status) {
|
||||||
*status = thread->status;
|
*status = thread->status;
|
||||||
}
|
}
|
||||||
SDL_DelThread(thread);
|
|
||||||
SDL_free(thread->name);
|
SDL_free(thread->name);
|
||||||
SDL_free(thread);
|
SDL_free(thread);
|
||||||
}
|
}
|
||||||
|
|
106
src/thread/beos/SDL_systls.c
Normal file
106
src/thread/beos/SDL_systls.c
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SDL_config.h"
|
||||||
|
#include "SDL_thread.h"
|
||||||
|
|
||||||
|
#if SDL_THREAD_BEOS
|
||||||
|
|
||||||
|
#include <support/TLS.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define TLS_ALLOC_CHUNKSIZE 8
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int limit;
|
||||||
|
void *data[1];
|
||||||
|
} SDL_TLSData;
|
||||||
|
|
||||||
|
static SDL_SpinLock tls_lock;
|
||||||
|
static int32 thread_local_storage = B_NO_MEMORY;
|
||||||
|
static SDL_atomic_t tls_id;
|
||||||
|
|
||||||
|
|
||||||
|
SDL_TLSID
|
||||||
|
SDL_TLSCreate()
|
||||||
|
{
|
||||||
|
if (thread_local_storage == B_NO_MEMORY) {
|
||||||
|
SDL_AtomicLock(&tls_lock);
|
||||||
|
if (thread_local_storage == B_NO_MEMORY) {
|
||||||
|
thread_local_storage = tls_allocate();
|
||||||
|
if (thread_local_storage == B_NO_MEMORY) {
|
||||||
|
SDL_SetError("tls_allocate() failed");
|
||||||
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
|
}
|
||||||
|
return SDL_AtomicIncRef(&tls_id)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
SDL_TLSGet(SDL_TLSID id)
|
||||||
|
{
|
||||||
|
SDL_TLSData *data;
|
||||||
|
|
||||||
|
data = (SDL_TLSData *)tls_get(thread_local_storage);
|
||||||
|
if (!data || id <= 0 || id > data->limit) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return data->data[id-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SDL_TLSSet(SDL_TLSID id, const void *value)
|
||||||
|
{
|
||||||
|
SDL_TLSData *data;
|
||||||
|
|
||||||
|
if (thread_local_storage == B_NO_MEMORY || id <= 0) {
|
||||||
|
return SDL_InvalidParamError(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (SDL_TLSData *)tls_get(thread_local_storage);
|
||||||
|
if (!data || id > data->limit) {
|
||||||
|
int i, oldlimit, newlimit;
|
||||||
|
|
||||||
|
oldlimit = data ? data->limit : 0;
|
||||||
|
newlimit = (id + TLS_ALLOC_CHUNKSIZE);
|
||||||
|
data = (SDL_TLSData *)SDL_realloc(data, sizeof(*data)+(newlimit-1)*sizeof(void*));
|
||||||
|
if (!data) {
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
data->limit = newlimit;
|
||||||
|
for (i = oldlimit; i < newlimit; ++i) {
|
||||||
|
data->data[i] = NULL;
|
||||||
|
}
|
||||||
|
if (!tls_set(thread_local_storage, data)) {
|
||||||
|
return SDL_SetError("TlsSetValue() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data->data[id-1] = SDL_const_cast(void*, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SDL_THREAD_BEOS */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
163
src/thread/generic/SDL_systls.c
Normal file
163
src/thread/generic/SDL_systls.c
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SDL_config.h"
|
||||||
|
#include "SDL_thread.h"
|
||||||
|
|
||||||
|
/* This is a generic implementation of thread-local storage which doesn't
|
||||||
|
require additional OS support.
|
||||||
|
|
||||||
|
It is not especially efficient and doesn't clean up thread-local storage
|
||||||
|
as threads exit. If there is a real OS that doesn't support thread-local
|
||||||
|
storage this implementation should be improved to be production quality.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TLS_ALLOC_CHUNKSIZE 8
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int limit;
|
||||||
|
void *data[1];
|
||||||
|
} SDL_TLSData;
|
||||||
|
|
||||||
|
typedef struct SDL_TLSEntry {
|
||||||
|
SDL_threadID thread;
|
||||||
|
SDL_TLSData *data;
|
||||||
|
struct SDL_TLSEntry *next;
|
||||||
|
} SDL_TLSEntry;
|
||||||
|
|
||||||
|
static SDL_SpinLock tls_lock;
|
||||||
|
static SDL_mutex *tls_mutex;
|
||||||
|
static SDL_TLSEntry *thread_local_storage;
|
||||||
|
static SDL_atomic_t tls_id;
|
||||||
|
|
||||||
|
|
||||||
|
static SDL_TLSData *GetTLSData()
|
||||||
|
{
|
||||||
|
SDL_threadID thread = SDL_ThreadID();
|
||||||
|
SDL_TLSEntry *entry;
|
||||||
|
SDL_TLSData *data = NULL;
|
||||||
|
|
||||||
|
if (!tls_mutex) {
|
||||||
|
SDL_AtomicLock(&tls_lock);
|
||||||
|
if (!tls_mutex) {
|
||||||
|
tls_mutex = SDL_CreateMutex();
|
||||||
|
if (!tls_mutex) {
|
||||||
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_LockMutex(tls_mutex);
|
||||||
|
for (entry = thread_local_storage; entry; entry = entry->next) {
|
||||||
|
if (entry->thread == thread) {
|
||||||
|
data = entry->data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_UnlockMutex(tls_mutex);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SetTLSData(SDL_TLSData *data)
|
||||||
|
{
|
||||||
|
SDL_threadID thread = SDL_ThreadID();
|
||||||
|
SDL_TLSEntry *entry;
|
||||||
|
|
||||||
|
/* GetTLSData() is always called first, so we can assume tls_mutex */
|
||||||
|
SDL_LockMutex(tls_mutex);
|
||||||
|
for (entry = thread_local_storage; entry; entry = entry->next) {
|
||||||
|
if (entry->thread == thread) {
|
||||||
|
entry->data = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!entry) {
|
||||||
|
entry = (SDL_TLSEntry *)SDL_malloc(sizeof(*entry));
|
||||||
|
if (entry) {
|
||||||
|
entry->thread = thread;
|
||||||
|
entry->data = data;
|
||||||
|
entry->next = thread_local_storage;
|
||||||
|
thread_local_storage = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_UnlockMutex(tls_mutex);
|
||||||
|
|
||||||
|
if (!entry) {
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SDL_TLSID
|
||||||
|
SDL_TLSCreate()
|
||||||
|
{
|
||||||
|
return SDL_AtomicIncRef(&tls_id)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
SDL_TLSGet(SDL_TLSID id)
|
||||||
|
{
|
||||||
|
SDL_TLSData *data;
|
||||||
|
|
||||||
|
data = GetTLSData();
|
||||||
|
if (!data || id <= 0 || id > data->limit) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return data->data[id-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SDL_TLSSet(SDL_TLSID id, const void *value)
|
||||||
|
{
|
||||||
|
SDL_TLSData *data;
|
||||||
|
|
||||||
|
if (id <= 0) {
|
||||||
|
return SDL_InvalidParamError(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = GetTLSData();
|
||||||
|
if (!data || id > data->limit) {
|
||||||
|
int i, oldlimit, newlimit;
|
||||||
|
|
||||||
|
oldlimit = data ? data->limit : 0;
|
||||||
|
newlimit = (id + TLS_ALLOC_CHUNKSIZE);
|
||||||
|
data = (SDL_TLSData *)SDL_realloc(data, sizeof(*data)+(newlimit-1)*sizeof(void*));
|
||||||
|
if (!data) {
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
data->limit = newlimit;
|
||||||
|
for (i = oldlimit; i < newlimit; ++i) {
|
||||||
|
data->data[i] = NULL;
|
||||||
|
}
|
||||||
|
if (SetTLSData(data) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data->data[id-1] = SDL_const_cast(void*, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
101
src/thread/pthread/SDL_systls.c
Normal file
101
src/thread/pthread/SDL_systls.c
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SDL_config.h"
|
||||||
|
#include "SDL_thread.h"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define TLS_ALLOC_CHUNKSIZE 8
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int limit;
|
||||||
|
void *data[1];
|
||||||
|
} SDL_TLSData;
|
||||||
|
|
||||||
|
static SDL_SpinLock tls_lock;
|
||||||
|
static pthread_key_t thread_local_storage;
|
||||||
|
static SDL_atomic_t tls_id;
|
||||||
|
|
||||||
|
|
||||||
|
SDL_TLSID
|
||||||
|
SDL_TLSCreate()
|
||||||
|
{
|
||||||
|
if (!thread_local_storage) {
|
||||||
|
SDL_AtomicLock(&tls_lock);
|
||||||
|
if (!thread_local_storage) {
|
||||||
|
if (pthread_key_create(&thread_local_storage, NULL) != 0) {
|
||||||
|
SDL_SetError("pthread_key_create() failed");
|
||||||
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
|
}
|
||||||
|
return SDL_AtomicIncRef(&tls_id)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
SDL_TLSGet(SDL_TLSID id)
|
||||||
|
{
|
||||||
|
SDL_TLSData *data;
|
||||||
|
|
||||||
|
data = (SDL_TLSData *)pthread_getspecific(thread_local_storage);
|
||||||
|
if (!data || id <= 0 || id > data->limit) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return data->data[id-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SDL_TLSSet(SDL_TLSID id, const void *value)
|
||||||
|
{
|
||||||
|
SDL_TLSData *data;
|
||||||
|
|
||||||
|
if (!thread_local_storage || id <= 0) {
|
||||||
|
return SDL_InvalidParamError(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (SDL_TLSData *)pthread_getspecific(thread_local_storage);
|
||||||
|
if (!data || id > data->limit) {
|
||||||
|
int i, oldlimit, newlimit;
|
||||||
|
|
||||||
|
oldlimit = data ? data->limit : 0;
|
||||||
|
newlimit = (id + TLS_ALLOC_CHUNKSIZE);
|
||||||
|
data = (SDL_TLSData *)SDL_realloc(data, sizeof(*data)+(newlimit-1)*sizeof(void*));
|
||||||
|
if (!data) {
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
data->limit = newlimit;
|
||||||
|
for (i = oldlimit; i < newlimit; ++i) {
|
||||||
|
data->data[i] = NULL;
|
||||||
|
}
|
||||||
|
if (pthread_setspecific(thread_local_storage, data) != 0) {
|
||||||
|
return SDL_SetError("pthread_setspecific() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data->data[id-1] = SDL_const_cast(void*, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
106
src/thread/windows/SDL_systls.c
Normal file
106
src/thread/windows/SDL_systls.c
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SDL_config.h"
|
||||||
|
#include "SDL_thread.h"
|
||||||
|
|
||||||
|
#if SDL_THREAD_WINDOWS
|
||||||
|
|
||||||
|
#include "../../core/windows/SDL_windows.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TLS_ALLOC_CHUNKSIZE 8
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int limit;
|
||||||
|
void *data[1];
|
||||||
|
} SDL_TLSData;
|
||||||
|
|
||||||
|
static SDL_SpinLock tls_lock;
|
||||||
|
static DWORD thread_local_storage = TLS_OUT_OF_INDEXES;
|
||||||
|
static SDL_atomic_t tls_id;
|
||||||
|
|
||||||
|
|
||||||
|
SDL_TLSID
|
||||||
|
SDL_TLSCreate()
|
||||||
|
{
|
||||||
|
if (thread_local_storage == TLS_OUT_OF_INDEXES) {
|
||||||
|
SDL_AtomicLock(&tls_lock);
|
||||||
|
if (thread_local_storage == TLS_OUT_OF_INDEXES) {
|
||||||
|
thread_local_storage = TlsAlloc();
|
||||||
|
if (thread_local_storage == TLS_OUT_OF_INDEXES) {
|
||||||
|
SDL_SetError("TlsAlloc() failed");
|
||||||
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
|
}
|
||||||
|
return SDL_AtomicIncRef(&tls_id)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
SDL_TLSGet(SDL_TLSID id)
|
||||||
|
{
|
||||||
|
SDL_TLSData *data;
|
||||||
|
|
||||||
|
data = (SDL_TLSData *)TlsGetValue(thread_local_storage);
|
||||||
|
if (!data || id <= 0 || id > data->limit) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return data->data[id-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SDL_TLSSet(SDL_TLSID id, const void *value)
|
||||||
|
{
|
||||||
|
SDL_TLSData *data;
|
||||||
|
|
||||||
|
if (thread_local_storage == TLS_OUT_OF_INDEXES || id <= 0) {
|
||||||
|
return SDL_InvalidParamError(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (SDL_TLSData *)TlsGetValue(thread_local_storage);
|
||||||
|
if (!data || id > data->limit) {
|
||||||
|
int i, oldlimit, newlimit;
|
||||||
|
|
||||||
|
oldlimit = data ? data->limit : 0;
|
||||||
|
newlimit = (id + TLS_ALLOC_CHUNKSIZE);
|
||||||
|
data = (SDL_TLSData *)SDL_realloc(data, sizeof(*data)+(newlimit-1)*sizeof(void*));
|
||||||
|
if (!data) {
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
data->limit = newlimit;
|
||||||
|
for (i = oldlimit; i < newlimit; ++i) {
|
||||||
|
data->data[i] = NULL;
|
||||||
|
}
|
||||||
|
if (!TlsSetValue(thread_local_storage, data)) {
|
||||||
|
return SDL_SetError("TlsSetValue() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data->data[id-1] = SDL_const_cast(void*, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SDL_THREAD_WINDOWS */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -19,6 +19,7 @@
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_thread.h"
|
#include "SDL_thread.h"
|
||||||
|
|
||||||
|
static SDL_TLSID tls;
|
||||||
static int alive = 0;
|
static int alive = 0;
|
||||||
|
|
||||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||||
|
@ -32,8 +33,9 @@ quit(int rc)
|
||||||
int SDLCALL
|
int SDLCALL
|
||||||
ThreadFunc(void *data)
|
ThreadFunc(void *data)
|
||||||
{
|
{
|
||||||
printf("Started thread %s: My thread id is %lu\n",
|
SDL_TLSSet(tls, "baby thread");
|
||||||
(char *) data, SDL_ThreadID());
|
printf("Started thread %s: My thread id is %lu, thread data = %s\n",
|
||||||
|
(char *) data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls));
|
||||||
while (alive) {
|
while (alive) {
|
||||||
printf("Thread '%s' is alive!\n", (char *) data);
|
printf("Thread '%s' is alive!\n", (char *) data);
|
||||||
SDL_Delay(1 * 1000);
|
SDL_Delay(1 * 1000);
|
||||||
|
@ -62,6 +64,11 @@ main(int argc, char *argv[])
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tls = SDL_TLSCreate();
|
||||||
|
SDL_assert(tls);
|
||||||
|
SDL_TLSSet(tls, "main thread");
|
||||||
|
printf("Main thread data initially: %s\n", (const char *)SDL_TLSGet(tls));
|
||||||
|
|
||||||
alive = 1;
|
alive = 1;
|
||||||
thread = SDL_CreateThread(ThreadFunc, "One", "#1");
|
thread = SDL_CreateThread(ThreadFunc, "One", "#1");
|
||||||
if (thread == NULL) {
|
if (thread == NULL) {
|
||||||
|
@ -73,6 +80,8 @@ main(int argc, char *argv[])
|
||||||
alive = 0;
|
alive = 0;
|
||||||
SDL_WaitThread(thread, NULL);
|
SDL_WaitThread(thread, NULL);
|
||||||
|
|
||||||
|
printf("Main thread data finally: %s\n", (const char *)SDL_TLSGet(tls));
|
||||||
|
|
||||||
alive = 1;
|
alive = 1;
|
||||||
signal(SIGTERM, killed);
|
signal(SIGTERM, killed);
|
||||||
thread = SDL_CreateThread(ThreadFunc, "Two", "#2");
|
thread = SDL_CreateThread(ThreadFunc, "Two", "#2");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue