Add TrackedMutex and measureFunctionCallTime

This commit is contained in:
Vinnie Falco
2013-08-23 04:36:04 -07:00
parent 5e827ba863
commit b0533a91fe
31 changed files with 1753 additions and 63 deletions

View File

@@ -61,6 +61,7 @@ UI_HEADERS_DIR += ../../modules/ripple_basics
SOURCES += \ SOURCES += \
../../Subtrees/beast/modules/beast_asio/beast_asio.cpp \ ../../Subtrees/beast/modules/beast_asio/beast_asio.cpp \
../../Subtrees/beast/modules/beast_basics/beast_basics.cpp \ ../../Subtrees/beast/modules/beast_basics/beast_basics.cpp \
../../Subtrees/beast/modules/beast_boost/beast_boost.cpp \
../../Subtrees/beast/modules/beast_core/beast_core.cpp \ ../../Subtrees/beast/modules/beast_core/beast_core.cpp \
../../Subtrees/beast/modules/beast_crypto/beast_crypto.cpp \ ../../Subtrees/beast/modules/beast_crypto/beast_crypto.cpp \
../../Subtrees/beast/modules/beast_db/beast_db.cpp \ ../../Subtrees/beast/modules/beast_db/beast_db.cpp \

View File

@@ -1021,6 +1021,7 @@
<ClCompile Include="..\..\src\cpp\protobuf_core.cpp" /> <ClCompile Include="..\..\src\cpp\protobuf_core.cpp" />
<ClCompile Include="..\..\Subtrees\beast\modules\beast_asio\beast_asio.cpp" /> <ClCompile Include="..\..\Subtrees\beast\modules\beast_asio\beast_asio.cpp" />
<ClCompile Include="..\..\Subtrees\beast\modules\beast_basics\beast_basics.cpp" /> <ClCompile Include="..\..\Subtrees\beast\modules\beast_basics\beast_basics.cpp" />
<ClCompile Include="..\..\Subtrees\beast\modules\beast_boost\beast_boost.cpp" />
<ClCompile Include="..\..\Subtrees\beast\modules\beast_core\beast_core.cpp" /> <ClCompile Include="..\..\Subtrees\beast\modules\beast_core\beast_core.cpp" />
<ClCompile Include="..\..\Subtrees\beast\modules\beast_crypto\beast_crypto.cpp" /> <ClCompile Include="..\..\Subtrees\beast\modules\beast_crypto\beast_crypto.cpp" />
<ClCompile Include="..\..\Subtrees\beast\modules\beast_db\beast_db.cpp" /> <ClCompile Include="..\..\Subtrees\beast\modules\beast_db\beast_db.cpp" />

View File

@@ -891,6 +891,9 @@
<ClCompile Include="..\..\modules\ripple_app\boost\ripple_SslContext.cpp"> <ClCompile Include="..\..\modules\ripple_app\boost\ripple_SslContext.cpp">
<Filter>[1] Ripple\ripple_app\boost</Filter> <Filter>[1] Ripple\ripple_app\boost</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\Subtrees\beast\modules\beast_boost\beast_boost.cpp">
<Filter>[0] Subtrees\beast</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\Subtrees\sqlite\sqlite3.h"> <ClInclude Include="..\..\Subtrees\sqlite\sqlite3.h">

View File

@@ -133,7 +133,7 @@ else:
COMPILED_FILES.extend([ COMPILED_FILES.extend([
'Subtrees/beast/modules/beast_asio/beast_asio.cpp', 'Subtrees/beast/modules/beast_asio/beast_asio.cpp',
'Subtrees/beast/modules/beast_basics/beast_basics.cpp', 'Subtrees/beast/modules/beast_basics/beast_basics.cpp',
# 'Subtrees/beast/modules/beast_core/beast_core.cpp', 'Subtrees/beast/modules/beast_boost/beast_boost.cpp',
'Subtrees/beast/modules/beast_crypto/beast_crypto.cpp', 'Subtrees/beast/modules/beast_crypto/beast_crypto.cpp',
'Subtrees/beast/modules/beast_db/beast_db.cpp', 'Subtrees/beast/modules/beast_db/beast_db.cpp',
'Subtrees/beast/modules/beast_sqdb/beast_sqdb.cpp', 'Subtrees/beast/modules/beast_sqdb/beast_sqdb.cpp',

View File

@@ -116,17 +116,17 @@
<ClInclude Include="..\..\modules\beast_basics\memory\beast_GlobalPagedFreeStore.h" /> <ClInclude Include="..\..\modules\beast_basics\memory\beast_GlobalPagedFreeStore.h" />
<ClInclude Include="..\..\modules\beast_basics\memory\beast_PagedFreeStore.h" /> <ClInclude Include="..\..\modules\beast_basics\memory\beast_PagedFreeStore.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_CallQueue.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_CallQueue.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SharedData.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_GlobalThreadGroup.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_GlobalThreadGroup.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_InterruptibleThread.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_InterruptibleThread.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_Listeners.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_Listeners.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ParallelFor.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_ParallelFor.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ReadWriteMutex.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_Semaphore.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_Semaphore.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SerialFor.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_SerialFor.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ThreadGroup.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_ThreadGroup.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ThreadWithCallQueue.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_ThreadWithCallQueue.h" />
<ClInclude Include="..\..\modules\beast_basics\threads\beast_Workers.h" /> <ClInclude Include="..\..\modules\beast_basics\threads\beast_Workers.h" />
<ClInclude Include="..\..\modules\beast_boost\beast_boost.h" />
<ClInclude Include="..\..\modules\beast_boost\traits\beast_BoostLockableTraits.h" />
<ClInclude Include="..\..\modules\beast_core\beast_core.h" /> <ClInclude Include="..\..\modules\beast_core\beast_core.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_AbstractFifo.h" /> <ClInclude Include="..\..\modules\beast_core\containers\beast_AbstractFifo.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_Array.h" /> <ClInclude Include="..\..\modules\beast_core\containers\beast_Array.h" />
@@ -159,6 +159,7 @@
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_Throw.h" /> <ClInclude Include="..\..\modules\beast_core\diagnostic\beast_Throw.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_UnitTest.h" /> <ClInclude Include="..\..\modules\beast_core\diagnostic\beast_UnitTest.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_UnitTestUtilities.h" /> <ClInclude Include="..\..\modules\beast_core\diagnostic\beast_UnitTestUtilities.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\MeasureFunctionCallTime.h" />
<ClInclude Include="..\..\modules\beast_core\files\beast_DirectoryIterator.h" /> <ClInclude Include="..\..\modules\beast_core\files\beast_DirectoryIterator.h" />
<ClInclude Include="..\..\modules\beast_core\files\beast_File.h" /> <ClInclude Include="..\..\modules\beast_core\files\beast_File.h" />
<ClInclude Include="..\..\modules\beast_core\files\beast_FileInputStream.h" /> <ClInclude Include="..\..\modules\beast_core\files\beast_FileInputStream.h" />
@@ -235,7 +236,6 @@
<ClInclude Include="..\..\modules\beast_core\text\beast_LexicalCast.h" /> <ClInclude Include="..\..\modules\beast_core\text\beast_LexicalCast.h" />
<ClInclude Include="..\..\modules\beast_core\text\beast_LocalisedStrings.h" /> <ClInclude Include="..\..\modules\beast_core\text\beast_LocalisedStrings.h" />
<ClInclude Include="..\..\modules\beast_core\text\beast_NewLine.h" /> <ClInclude Include="..\..\modules\beast_core\text\beast_NewLine.h" />
<ClInclude Include="..\..\modules\beast_core\text\beast_NumberToString.h" />
<ClInclude Include="..\..\modules\beast_core\text\beast_String.h" /> <ClInclude Include="..\..\modules\beast_core\text\beast_String.h" />
<ClInclude Include="..\..\modules\beast_core\text\beast_StringArray.h" /> <ClInclude Include="..\..\modules\beast_core\text\beast_StringArray.h" />
<ClInclude Include="..\..\modules\beast_core\text\beast_StringPairArray.h" /> <ClInclude Include="..\..\modules\beast_core\text\beast_StringPairArray.h" />
@@ -248,9 +248,11 @@
<ClInclude Include="..\..\modules\beast_core\threads\beast_InterProcessLock.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_InterProcessLock.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_Process.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_Process.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_ReadWriteLock.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_ReadWriteLock.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_ReadWriteMutex.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedLock.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedLock.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedReadLock.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedReadLock.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedWriteLock.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedWriteLock.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_SharedData.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_SpinDelay.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_SpinDelay.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_SpinLock.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_SpinLock.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_Thread.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_Thread.h" />
@@ -258,6 +260,13 @@
<ClInclude Include="..\..\modules\beast_core\threads\beast_ThreadPool.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_ThreadPool.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_TimeSliceThread.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_TimeSliceThread.h" />
<ClInclude Include="..\..\modules\beast_core\threads\beast_WaitableEvent.h" /> <ClInclude Include="..\..\modules\beast_core\threads\beast_WaitableEvent.h" />
<ClInclude Include="..\..\modules\beast_core\thread\detail\ScopedLock.h" />
<ClInclude Include="..\..\modules\beast_core\thread\detail\TrackedMutex.h" />
<ClInclude Include="..\..\modules\beast_core\thread\impl\TrackedMutex.h" />
<ClInclude Include="..\..\modules\beast_core\thread\impl\TrackedMutexType.h" />
<ClInclude Include="..\..\modules\beast_core\thread\impl\UntrackedMutexType.h" />
<ClInclude Include="..\..\modules\beast_core\thread\MutexTraits.h" />
<ClInclude Include="..\..\modules\beast_core\thread\TrackedMutex.h" />
<ClInclude Include="..\..\modules\beast_core\time\beast_PerformanceCounter.h" /> <ClInclude Include="..\..\modules\beast_core\time\beast_PerformanceCounter.h" />
<ClInclude Include="..\..\modules\beast_core\time\beast_PerformedAtExit.h" /> <ClInclude Include="..\..\modules\beast_core\time\beast_PerformedAtExit.h" />
<ClInclude Include="..\..\modules\beast_core\time\beast_RelativeTime.h" /> <ClInclude Include="..\..\modules\beast_core\time\beast_RelativeTime.h" />
@@ -466,12 +475,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ReadWriteMutex.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_basics\threads\beast_Semaphore.cpp"> <ClCompile Include="..\..\modules\beast_basics\threads\beast_Semaphore.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -496,6 +499,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\beast_boost\beast_boost.cpp" />
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp" /> <ClCompile Include="..\..\modules\beast_core\beast_core.cpp" />
<ClCompile Include="..\..\modules\beast_core\containers\beast_AbstractFifo.cpp"> <ClCompile Include="..\..\modules\beast_core\containers\beast_AbstractFifo.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -915,12 +919,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\beast_core\text\beast_NumberToString.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\text\beast_String.cpp"> <ClCompile Include="..\..\modules\beast_core\text\beast_String.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -969,6 +967,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\beast_core\threads\beast_ReadWriteMutex.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\threads\beast_SpinDelay.cpp"> <ClCompile Include="..\..\modules\beast_core\threads\beast_SpinDelay.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -993,6 +997,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\beast_core\thread\impl\TrackedMutex.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\time\beast_PerformanceCounter.cpp"> <ClCompile Include="..\..\modules\beast_core\time\beast_PerformanceCounter.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>

View File

@@ -161,6 +161,21 @@
<Filter Include="beast_asio\async"> <Filter Include="beast_asio\async">
<UniqueIdentifier>{beb81776-4aad-401d-8826-81478dbbf30b}</UniqueIdentifier> <UniqueIdentifier>{beb81776-4aad-401d-8826-81478dbbf30b}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="beast_boost">
<UniqueIdentifier>{0eac8b8d-7049-4eda-b6b4-53194d336a97}</UniqueIdentifier>
</Filter>
<Filter Include="beast_boost\traits">
<UniqueIdentifier>{1e6959ed-fcb9-4a3b-ac5a-eb26973e21f6}</UniqueIdentifier>
</Filter>
<Filter Include="beast_core\thread">
<UniqueIdentifier>{493db217-b3e4-4b08-97b2-a2d753cc8c35}</UniqueIdentifier>
</Filter>
<Filter Include="beast_core\thread\detail">
<UniqueIdentifier>{1b2e8962-c087-4453-8107-7077c2de5846}</UniqueIdentifier>
</Filter>
<Filter Include="beast_core\thread\impl">
<UniqueIdentifier>{91538dcf-b219-4c80-9861-bb4949089775}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\modules\beast_core\beast_core.h"> <ClInclude Include="..\..\modules\beast_core\beast_core.h">
@@ -545,9 +560,6 @@
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ParallelFor.h"> <ClInclude Include="..\..\modules\beast_basics\threads\beast_ParallelFor.h">
<Filter>beast_basics\threads</Filter> <Filter>beast_basics\threads</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ReadWriteMutex.h">
<Filter>beast_basics\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_basics\threads\beast_Semaphore.h"> <ClInclude Include="..\..\modules\beast_basics\threads\beast_Semaphore.h">
<Filter>beast_basics\threads</Filter> <Filter>beast_basics\threads</Filter>
</ClInclude> </ClInclude>
@@ -632,9 +644,6 @@
<ClInclude Include="..\..\modules\beast_core\time\beast_PerformedAtExit.h"> <ClInclude Include="..\..\modules\beast_core\time\beast_PerformedAtExit.h">
<Filter>beast_core\time</Filter> <Filter>beast_core\time</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SharedData.h">
<Filter>beast_basics\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_basics\events\beast_DeadlineTimer.h"> <ClInclude Include="..\..\modules\beast_basics\events\beast_DeadlineTimer.h">
<Filter>beast_basics\events</Filter> <Filter>beast_basics\events</Filter>
</ClInclude> </ClInclude>
@@ -869,8 +878,41 @@
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_InputParser.h"> <ClInclude Include="..\..\modules\beast_asio\handshake\beast_InputParser.h">
<Filter>beast_asio\handshake</Filter> <Filter>beast_asio\handshake</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\modules\beast_core\text\beast_NumberToString.h"> <ClInclude Include="..\..\modules\beast_core\diagnostic\MeasureFunctionCallTime.h">
<Filter>beast_core\text</Filter> <Filter>beast_core\diagnostic</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_boost\beast_boost.h">
<Filter>beast_boost</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\threads\beast_ReadWriteMutex.h">
<Filter>beast_core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\threads\beast_SharedData.h">
<Filter>beast_core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_boost\traits\beast_BoostLockableTraits.h">
<Filter>beast_boost\traits</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\MutexTraits.h">
<Filter>beast_core\thread</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\TrackedMutex.h">
<Filter>beast_core\thread</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\detail\TrackedMutex.h">
<Filter>beast_core\thread\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\detail\ScopedLock.h">
<Filter>beast_core\thread\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\impl\TrackedMutex.h">
<Filter>beast_core\thread\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\impl\TrackedMutexType.h">
<Filter>beast_core\thread\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\thread\impl\UntrackedMutexType.h">
<Filter>beast_core\thread\impl</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -1150,9 +1192,6 @@
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ParallelFor.cpp"> <ClCompile Include="..\..\modules\beast_basics\threads\beast_ParallelFor.cpp">
<Filter>beast_basics\threads</Filter> <Filter>beast_basics\threads</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ReadWriteMutex.cpp">
<Filter>beast_basics\threads</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_basics\threads\beast_Semaphore.cpp"> <ClCompile Include="..\..\modules\beast_basics\threads\beast_Semaphore.cpp">
<Filter>beast_basics\threads</Filter> <Filter>beast_basics\threads</Filter>
</ClCompile> </ClCompile>
@@ -1339,8 +1378,14 @@
<ClCompile Include="..\..\modules\beast_asio\async\beast_SharedHandler.cpp"> <ClCompile Include="..\..\modules\beast_asio\async\beast_SharedHandler.cpp">
<Filter>beast_asio\async</Filter> <Filter>beast_asio\async</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\beast_core\text\beast_NumberToString.cpp"> <ClCompile Include="..\..\modules\beast_boost\beast_boost.cpp">
<Filter>beast_core\text</Filter> <Filter>beast_boost</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\threads\beast_ReadWriteMutex.cpp">
<Filter>beast_core\threads</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\thread\impl\TrackedMutex.cpp">
<Filter>beast_core\thread\impl</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -53,7 +53,6 @@ namespace beast
#include "threads/beast_Listeners.cpp" #include "threads/beast_Listeners.cpp"
#include "threads/beast_ManualCallQueue.cpp" #include "threads/beast_ManualCallQueue.cpp"
#include "threads/beast_ParallelFor.cpp" #include "threads/beast_ParallelFor.cpp"
#include "threads/beast_ReadWriteMutex.cpp"
#include "threads/beast_ThreadGroup.cpp" #include "threads/beast_ThreadGroup.cpp"
#include "threads/beast_ThreadWithCallQueue.cpp" #include "threads/beast_ThreadWithCallQueue.cpp"
#include "threads/beast_Workers.cpp" #include "threads/beast_Workers.cpp"

View File

@@ -259,10 +259,8 @@ namespace beast
#include "threads/beast_Semaphore.h" #include "threads/beast_Semaphore.h"
#include "threads/beast_SerialFor.h" #include "threads/beast_SerialFor.h"
#include "threads/beast_InterruptibleThread.h" #include "threads/beast_InterruptibleThread.h"
#include "threads/beast_ReadWriteMutex.h"
#include "threads/beast_ThreadGroup.h" #include "threads/beast_ThreadGroup.h"
#include "threads/beast_CallQueue.h" #include "threads/beast_CallQueue.h"
#include "threads/beast_SharedData.h"
#include "threads/beast_GlobalThreadGroup.h" #include "threads/beast_GlobalThreadGroup.h"
#include "threads/beast_Listeners.h" #include "threads/beast_Listeners.h"
#include "threads/beast_ManualCallQueue.h" #include "threads/beast_ManualCallQueue.h"

View File

@@ -1,2 +1 @@
/boost-subtree /boost-subtree
*.cpp

View File

@@ -0,0 +1,29 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "BeastConfig.h"
#include "beast_boost.h"
namespace beast
{
}

View File

@@ -0,0 +1,43 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_BOOST_H_INCLUDED
#define BEAST_BOOST_H_INCLUDED
// Adds boost-specific features to beast.
#include <boost/version.hpp>
// lockable_traits was added in 1.53.0
#ifndef BEAST_BOOST_HAS_LOCKABLES
# if BOOST_VERSION >= 105300
# define BEAST_BOOST_HAS_LOCKABLES 1
# else
# define BEAST_BOOST_HAS_LOCKABLES 0
# endif
#endif
#if BEAST_BOOST_HAS_LOCKABLES
# include <boost/thread/lockable_traits.hpp>
#endif
#if BEAST_BOOST_HAS_LOCKABLES
# include "traits/beast_BoostLockableTraits.h"
#endif
#endif

View File

@@ -0,0 +1,125 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_BOOSTLOCKABLERAITS_H_INCLUDED
#define BEAST_BOOSTLOCKABLERAITS_H_INCLUDED
// Adds beast specializations for boost lockables.
// beast forward declarations
namespace beast
{
class CriticalSection;
template <typename Mutex>
class TrackedMutex;
template <typename Mutex>
class UntrackedMutex;
}
//------------------------------------------------------------------------------
// boost Mutex concepts
//
// http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts
namespace boost
{
namespace sync
{
//------------------------------------------------------------------------------
//
// CriticalSection
//
// BasicLockable
//
template <>
struct is_basic_lockable <beast::CriticalSection>
: public boost::true_type { };
// Lockable
//
template <>
struct is_lockable <beast::CriticalSection>
: public boost::true_type { };
// RecursiveLockable
//
template <>
struct is_recursive_mutex_sur_parole <beast::CriticalSection>
: public boost::true_type { };
//------------------------------------------------------------------------------
//
// TrackedMutex <>
//
// BasicLockable
//
template <class Mutex>
class is_basic_lockable <beast::TrackedMutex <Mutex> >
: public boost::sync::is_basic_lockable <Mutex> { };
// Lockable
//
template <class Mutex>
class is_lockable <beast::TrackedMutex <Mutex> >
: public boost::sync::is_lockable <Mutex> { };
// RecursiveLockable
//
template <class Mutex>
struct is_recursive_mutex_sur_parole <beast::TrackedMutex <Mutex> >
: public boost::true_type { };
//------------------------------------------------------------------------------
//
// UntrackedMutex <>
//
// BasicLockable
//
template <class Mutex>
class is_basic_lockable <beast::UntrackedMutex <Mutex> >
: public boost::sync::is_basic_lockable <Mutex> { };
// Lockable
//
template <class Mutex>
class is_lockable <beast::UntrackedMutex <Mutex> >
: public boost::sync::is_lockable <Mutex> { };
// RecursiveLockable
//
template <class Mutex>
struct is_recursive_mutex_sur_parole <beast::UntrackedMutex <Mutex> >
: public boost::true_type { };
}
}
#endif

View File

@@ -204,8 +204,11 @@ namespace beast
#include "text/beast_StringPool.cpp" #include "text/beast_StringPool.cpp"
#include "text/beast_TextDiff.cpp" #include "text/beast_TextDiff.cpp"
#include "thread/impl/TrackedMutex.cpp"
#include "threads/beast_ChildProcess.cpp" #include "threads/beast_ChildProcess.cpp"
#include "threads/beast_ReadWriteLock.cpp" #include "threads/beast_ReadWriteLock.cpp"
#include "threads/beast_ReadWriteMutex.cpp"
#include "threads/beast_SpinDelay.cpp" #include "threads/beast_SpinDelay.cpp"
#include "threads/beast_Thread.cpp" #include "threads/beast_Thread.cpp"
#include "threads/beast_ThreadPool.cpp" #include "threads/beast_ThreadPool.cpp"

View File

@@ -198,6 +198,8 @@ namespace beast
#include "system/beast_PlatformDefs.h" #include "system/beast_PlatformDefs.h"
#include "system/beast_TargetPlatform.h" #include "system/beast_TargetPlatform.h"
#include "diagnostic/beast_Throw.h"
#include "system/beast_Functional.h" #include "system/beast_Functional.h"
#include "maths/beast_MathsFunctions.h" #include "maths/beast_MathsFunctions.h"
@@ -206,6 +208,7 @@ namespace beast
#include "memory/beast_AtomicFlag.h" #include "memory/beast_AtomicFlag.h"
#include "memory/beast_AtomicPointer.h" #include "memory/beast_AtomicPointer.h"
#include "memory/beast_AtomicState.h" #include "memory/beast_AtomicState.h"
#include "containers/beast_List.h"
#include "containers/beast_LockFreeStack.h" #include "containers/beast_LockFreeStack.h"
#include "threads/beast_SpinDelay.h" #include "threads/beast_SpinDelay.h"
#include "memory/beast_StaticObject.h" #include "memory/beast_StaticObject.h"
@@ -213,12 +216,26 @@ namespace beast
#include "text/beast_String.h" #include "text/beast_String.h"
#include "memory/beast_MemoryAlignment.h"
#include "memory/beast_CacheLine.h"
#include "threads/beast_CriticalSection.h" #include "threads/beast_CriticalSection.h"
#include "diagnostic/beast_FatalError.h" #include "threads/beast_ReadWriteMutex.h"
#include "threads/beast_SharedData.h"
#include "diagnostic/beast_SafeBool.h" #include "diagnostic/beast_SafeBool.h"
#include "time/beast_PerformedAtExit.h"
#include "diagnostic/beast_LeakChecked.h"
#include "threads/beast_WaitableEvent.h"
#include "threads/beast_Thread.h"
#include "threads/beast_SpinLock.h"
#include "threads/beast_ThreadLocalValue.h"
#include "thread/MutexTraits.h"
#include "containers/beast_Array.h"
#include "text/beast_StringArray.h"
#include "thread/TrackedMutex.h"
#include "diagnostic/beast_FatalError.h"
#include "diagnostic/beast_Error.h" #include "diagnostic/beast_Error.h"
#include "diagnostic/beast_Debug.h" #include "diagnostic/beast_Debug.h"
#include "diagnostic/beast_Throw.h"
#include "text/beast_CharacterFunctions.h" #include "text/beast_CharacterFunctions.h"
#include "text/beast_CharPointer_ASCII.h" #include "text/beast_CharPointer_ASCII.h"
@@ -228,23 +245,18 @@ namespace beast
#include "text/beast_LexicalCast.h" #include "text/beast_LexicalCast.h"
#include "memory/beast_ContainerDeletePolicy.h" #include "memory/beast_ContainerDeletePolicy.h"
#include "time/beast_PerformedAtExit.h"
#include "diagnostic/beast_LeakChecked.h"
#include "memory/beast_ByteOrder.h" #include "memory/beast_ByteOrder.h"
#include "memory/beast_ByteSwap.h" #include "memory/beast_ByteSwap.h"
#include "maths/beast_uint24.h" #include "maths/beast_uint24.h"
#include "logging/beast_Logger.h" #include "logging/beast_Logger.h"
#include "threads/beast_Thread.h"
#include "diagnostic/beast_FPUFlags.h" #include "diagnostic/beast_FPUFlags.h"
#include "diagnostic/beast_ProtectedCall.h" #include "diagnostic/beast_ProtectedCall.h"
#include "containers/beast_AbstractFifo.h" #include "containers/beast_AbstractFifo.h"
#include "containers/beast_Array.h"
#include "containers/beast_ArrayAllocationBase.h" #include "containers/beast_ArrayAllocationBase.h"
#include "containers/beast_DynamicObject.h" #include "containers/beast_DynamicObject.h"
#include "containers/beast_ElementComparator.h" #include "containers/beast_ElementComparator.h"
#include "maths/beast_Random.h" #include "maths/beast_Random.h"
#include "containers/beast_HashMap.h" #include "containers/beast_HashMap.h"
#include "containers/beast_List.h"
#include "containers/beast_LinkedListPointer.h" #include "containers/beast_LinkedListPointer.h"
#include "containers/beast_LockFreeQueue.h" #include "containers/beast_LockFreeQueue.h"
#include "containers/beast_NamedValueSet.h" #include "containers/beast_NamedValueSet.h"
@@ -281,11 +293,8 @@ namespace beast
#include "memory/beast_OptionalScopedPointer.h" #include "memory/beast_OptionalScopedPointer.h"
#include "memory/beast_SharedObject.h" #include "memory/beast_SharedObject.h"
#include "memory/beast_ScopedPointer.h" #include "memory/beast_ScopedPointer.h"
#include "threads/beast_SpinLock.h"
#include "memory/beast_SharedSingleton.h" #include "memory/beast_SharedSingleton.h"
#include "memory/beast_WeakReference.h" #include "memory/beast_WeakReference.h"
#include "memory/beast_MemoryAlignment.h"
#include "memory/beast_CacheLine.h"
#include "memory/beast_RecycledObjectPool.h" #include "memory/beast_RecycledObjectPool.h"
#include "misc/beast_Main.h" #include "misc/beast_Main.h"
#include "misc/beast_Result.h" #include "misc/beast_Result.h"
@@ -309,7 +318,6 @@ namespace beast
#include "text/beast_Identifier.h" #include "text/beast_Identifier.h"
#include "text/beast_LocalisedStrings.h" #include "text/beast_LocalisedStrings.h"
#include "text/beast_NewLine.h" #include "text/beast_NewLine.h"
#include "text/beast_StringArray.h"
#include "diagnostic/beast_SemanticVersion.h" #include "diagnostic/beast_SemanticVersion.h"
#include "text/beast_StringPairArray.h" #include "text/beast_StringPairArray.h"
#include "text/beast_StringPool.h" #include "text/beast_StringPool.h"
@@ -323,10 +331,8 @@ namespace beast
#include "threads/beast_ScopedLock.h" #include "threads/beast_ScopedLock.h"
#include "threads/beast_ScopedReadLock.h" #include "threads/beast_ScopedReadLock.h"
#include "threads/beast_ScopedWriteLock.h" #include "threads/beast_ScopedWriteLock.h"
#include "threads/beast_ThreadLocalValue.h"
#include "threads/beast_ThreadPool.h" #include "threads/beast_ThreadPool.h"
#include "threads/beast_TimeSliceThread.h" #include "threads/beast_TimeSliceThread.h"
#include "threads/beast_WaitableEvent.h"
#include "time/beast_PerformanceCounter.h" #include "time/beast_PerformanceCounter.h"
#include "time/beast_RelativeTime.h" #include "time/beast_RelativeTime.h"
#include "time/beast_Time.h" #include "time/beast_Time.h"
@@ -338,6 +344,8 @@ namespace beast
#include "zip/beast_GZIPDecompressorInputStream.h" #include "zip/beast_GZIPDecompressorInputStream.h"
#include "zip/beast_ZipFile.h" #include "zip/beast_ZipFile.h"
#include "diagnostic/MeasureFunctionCallTime.h"
} }
#ifdef _CRTDBG_MAP_ALLOC #ifdef _CRTDBG_MAP_ALLOC

View File

@@ -0,0 +1,80 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_DIAGNOSTIC_MEASUREFUNCTIONCALLTIME_H_INCLUDED
#define BEAST_CORE_DIAGNOSTIC_MEASUREFUNCTIONCALLTIME_H_INCLUDED
/** Measures the speed of invoking a function. */
/** @{ */
template <typename Function>
double measureFunctionCallTime (Function f)
{
int64 const startTime (Time::getHighResolutionTicks ());
f ();
return Time::highResolutionTicksToSeconds (
Time::getHighResolutionTicks () - startTime);
}
#if 0
template <typename Function,
typename P1, typename P2, typename P3, typename P4,
typename P5, typename P6, typename P7, typename P8>
double measureFunctionCallTime (Function f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
{
int64 const startTime (Time::getHighResolutionTicks ());
f (p1, p2, p3, p4, p5 ,p6 ,p7 ,p8);
return Time::highResolutionTicksToSeconds (
Time::getHighResolutionTicks () - startTime);
}
template <typename Function,
typename P1, typename P2, typename P3, typename P4,
typename P5, typename P6, typename P7, typename P8>
double measureFunctionCallTime (Function f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
{
int64 const startTime (Time::getHighResolutionTicks ());
f (p1, p2, p3, p4, p5 ,p6 ,p7 ,p8);
return Time::highResolutionTicksToSeconds (
Time::getHighResolutionTicks () - startTime);
}
template <typename Function,
typename P1, typename P2, typename P3, typename P4,
typename P5, typename P6, typename P7, typename P8>
double measureFunctionCallTime (Function f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
{
int64 const startTime (Time::getHighResolutionTicks ());
f (p1, p2, p3, p4, p5 ,p6 ,p7 ,p8);
return Time::highResolutionTicksToSeconds (
Time::getHighResolutionTicks () - startTime);
}
template <typename Function,
typename P1, typename P2, typename P3, typename P4,
typename P5, typename P6, typename P7, typename P8>
double measureFunctionCallTime (Function f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
{
int64 const startTime (Time::getHighResolutionTicks ());
f (p1, p2, p3, p4, p5 ,p6 ,p7 ,p8);
return Time::highResolutionTicksToSeconds (
Time::getHighResolutionTicks () - startTime);
}
#endif
#endif

View File

@@ -118,9 +118,36 @@ void checkHeap ()
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const String getFileNameFromPath (const char* sourceFileName) String getSourceLocation (char const* fileName, int lineNumber,
int numberOfParents)
{ {
return File::createFileWithoutCheckingPath (sourceFileName).getFileName (); return getFileNameFromPath (fileName, numberOfParents) +
"(" + String::fromNumber (lineNumber) + ")";
}
String getFileNameFromPath (const char* sourceFileName, int numberOfParents)
{
String fullPath (sourceFileName);
#if BEAST_WINDOWS
// Convert everything to forward slash
fullPath = fullPath.replaceCharacter ('\\', '/');
#endif
String path;
int chopPoint = fullPath.lastIndexOfChar ('/');
path = fullPath.substring (chopPoint + 1);
while (chopPoint >= 0 && numberOfParents > 0)
{
--numberOfParents;
fullPath = fullPath.substring (0, chopPoint);
chopPoint = fullPath.lastIndexOfChar ('/');
path = fullPath.substring (chopPoint + 1) + '/' + path;
}
return path;
} }
// Returns a String with double quotes escaped // Returns a String with double quotes escaped

View File

@@ -31,11 +31,16 @@ namespace Debug
*/ */
extern void breakPoint (); extern void breakPoint ();
// VFALCO NOTE IS THIS REALLY THE RIGHT PLACE FOR THESE?? /** Given a file and line number this formats a suitable string.
// Usually you will pass __FILE__ and __LINE__ here.
// Return only the filename portion of sourceFileName */
// This hides the programmer's directory structure from end-users. String getSourceLocation (char const* fileName, int lineNumber,
const String getFileNameFromPath (const char* sourceFileName); int numberOfParents = 0);
/** Retrieve the file name from a full path.
The nubmer of parents can be chosen
*/
String getFileNameFromPath (const char* sourceFileName, int numberOfParents = 0);
// Convert a String that may contain double quotes and newlines // Convert a String that may contain double quotes and newlines
// into a String with double quotes escaped as \" and each // into a String with double quotes escaped as \" and each

View File

@@ -25,6 +25,11 @@
This provides an opportunity to utilize the debugger before This provides an opportunity to utilize the debugger before
the stack is unwound. the stack is unwound.
*/ */
namespace Debug
{
extern void breakPoint ();
};
template <class Exception> template <class Exception>
inline void Throw (Exception const& e, char const* = "", int = 0) inline void Throw (Exception const& e, char const* = "", int = 0)
{ {

View File

@@ -0,0 +1,75 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_THREAD_MUTEXTRAITS_H_INCLUDED
#define BEAST_CORE_THREAD_MUTEXTRAITS_H_INCLUDED
/** Adapt a Mutex type to meet the boost::Mutex concept requirements.
The default implementation assumes adherance to the boost::Mutex concepts,
with one important exception. We make the member functions const, for
convenience.
*/
template <typename Mutex>
struct MutexTraits
{
// BasicLockable
// http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.basic_lockable
//
static inline void lock (Mutex const& mutex) noexcept
{
(const_cast <Mutex&> (mutex)).lock ();
}
static inline void unlock (Mutex const& mutex) noexcept
{
(const_cast <Mutex&> (mutex)).unlock ();
}
// Lockable
// http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.basic_lockable
//
static inline bool try_lock (Mutex const& mutex) noexcept
{
return (const_cast <Mutex&> (mutex)).try_lock ();
}
};
//------------------------------------------------------------------------------
/** MutexTraits Specialization for a beast CriticalSection. */
template <>
struct MutexTraits <CriticalSection>
{
static inline void lock (CriticalSection const& mutex) noexcept
{
mutex.lock ();
}
static inline void unlock (CriticalSection const& mutex) noexcept
{
mutex.unlock ();
}
static inline bool try_lock (CriticalSection const& mutex) noexcept
{
return mutex.try_lock ();
}
};
#endif

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_THREAD_TRACKEDMUTEX_H_INCLUDED
#define BEAST_CORE_THREAD_TRACKEDMUTEX_H_INCLUDED
#include "detail/TrackedMutex.h"
#include "detail/ScopedLock.h"
#include "impl/TrackedMutex.h"
#include "impl/TrackedMutexType.h"
#include "impl/UntrackedMutexType.h"
#endif

View File

@@ -0,0 +1,251 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_THREAD_DETAIL_SCOPEDLOCK_H_INCLUDED
#define BEAST_CORE_THREAD_DETAIL_SCOPEDLOCK_H_INCLUDED
#include "../MutexTraits.h"
namespace detail
{
template <typename Mutex>
class TrackedScopedLock : public Uncopyable
{
public:
inline explicit TrackedScopedLock (Mutex const& mutex,
char const* fileName, int lineNumber) noexcept
: m_mutex (mutex)
, m_lock_count (0)
{
lock (fileName, lineNumber);
}
inline ~TrackedScopedLock () noexcept
{
if (m_lock_count > 0)
unlock ();
}
inline void lock (char const* fileName, int lineNumber) noexcept
{
++m_lock_count;
m_mutex.lock (fileName, lineNumber);
}
inline void unlock () noexcept
{
m_mutex.unlock ();
--m_lock_count;
}
private:
Mutex const& m_mutex;
int m_lock_count;
};
//--------------------------------------------------------------------------
template <typename Mutex>
class TrackedScopedTryLock : public Uncopyable
{
public:
inline explicit TrackedScopedTryLock (Mutex const& mutex,
char const* fileName, int lineNumber) noexcept
: m_mutex (mutex)
, m_lock_count (0)
{
try_lock (fileName, lineNumber);
}
inline ~TrackedScopedTryLock () noexcept
{
if (m_lock_count > 0)
unlock ();
}
inline bool owns_lock () const noexcept
{
return m_lock_count > 0;
}
inline bool try_lock (char const* fileName, int lineNumber) noexcept
{
bool const success = m_mutex.try_lock (fileName, lineNumber);
if (success)
++m_lock_count;
return success;
}
inline void unlock () noexcept
{
m_mutex.unlock ();
--m_lock_count;
}
private:
Mutex const& m_mutex;
int m_lock_count;
};
//--------------------------------------------------------------------------
template <typename Mutex>
class TrackedScopedUnlock : public Uncopyable
{
public:
inline explicit TrackedScopedUnlock (Mutex const& mutex,
char const* fileName, int lineNumber) noexcept
: m_mutex (mutex)
, m_fileName (fileName)
, m_lineNumber (lineNumber)
{
m_mutex.unlock ();
}
inline ~TrackedScopedUnlock () noexcept
{
m_mutex.lock (m_fileName, m_lineNumber);
}
private:
Mutex const& m_mutex;
char const* const m_fileName;
int const m_lineNumber;
};
//--------------------------------------------------------------------------
template <typename Mutex>
class UntrackedScopedLock : public Uncopyable
{
public:
inline explicit UntrackedScopedLock (Mutex const& mutex,
char const*, int) noexcept
: m_mutex (mutex)
, m_lock_count (0)
{
lock ();
}
inline ~UntrackedScopedLock () noexcept
{
if (m_lock_count > 0)
unlock ();
}
inline void lock () noexcept
{
++m_lock_count;
m_mutex.lock ();
}
inline void lock (char const*, int) noexcept
{
lock ();
}
inline void unlock () noexcept
{
m_mutex.unlock ();
--m_lock_count;
}
private:
Mutex const& m_mutex;
int m_lock_count;
};
//--------------------------------------------------------------------------
template <typename Mutex>
class UntrackedScopedTryLock : public Uncopyable
{
public:
inline explicit UntrackedScopedTryLock (Mutex const& mutex,
char const*, int) noexcept
: m_mutex (mutex)
{
try_lock ();
}
inline ~UntrackedScopedTryLock () noexcept
{
if (m_lock_count > 0)
unlock ();
}
inline bool owns_lock () const noexcept
{
return m_lock_count > 0;
}
inline bool try_lock () noexcept
{
bool const success = m_mutex.try_lock ();
if (success)
++m_lock_count;
return success;
}
inline bool try_lock (char const*, int) noexcept
{
return try_lock ();
}
inline void unlock () noexcept
{
m_mutex.unlock ();
--m_lock_count;
}
private:
Mutex const& m_mutex;
int m_lock_count;
};
//--------------------------------------------------------------------------
template <typename Mutex>
class UntrackedScopedUnlock : public Uncopyable
{
public:
UntrackedScopedUnlock (Mutex const& mutex,
char const*, int) noexcept
: m_mutex (mutex)
, m_owns_lock (true)
{
MutexTraits <Mutex>::unlock (m_mutex);
m_owns_lock = false;
}
~UntrackedScopedUnlock () noexcept
{
MutexTraits <Mutex>::lock (m_mutex);
m_owns_lock = true;
}
private:
Mutex const& m_mutex;
bool m_owns_lock;
};
} // namespace detail
#endif

View File

@@ -0,0 +1,100 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_THREAD_DETAIL_TRACKEDMUTEX_H_INCLUDED
#define BEAST_CORE_THREAD_DETAIL_TRACKEDMUTEX_H_INCLUDED
#include "../../containers/beast_List.h"
#include "../../memory/beast_Atomic.h"
#include "../../threads/beast_ThreadLocalValue.h"
class TrackedMutex;
namespace detail
{
struct TrackedMutexBasics
{
struct PerThreadData;
typedef List <TrackedMutex> ThreadLockList;
typedef List <PerThreadData> GlobalThreadList;
// Retrieve an atomic counter unique to class Object
template <typename Object>
static Atomic <int>& getCounter () noexcept
{
static Atomic <int> counter;
return counter;
}
template <typename Object>
inline static String createName (String name,
char const* fileName, int lineNumber)
{
return createName (name, fileName, lineNumber,
++getCounter <Object> ());
}
static String createName (String name,
char const* fileName, int lineNumber, int instanceNumber = 0);
struct PerThreadData
: GlobalThreadList::Node
{
PerThreadData ();
int id;
int refCount;
ThreadLockList list;
CriticalSection mutex;
TrackedMutex const* blocked;
String threadName; // at the time of the block
String sourceLocation; // at the time of the block
};
// This turns the thread local into a POD which will be
// initialized to all zeroes. We use the 'id' flag to
// know to initialize.
//
struct PerThreadDataStorage
{
BEAST_ALIGN(8)
unsigned char bytes [sizeof (PerThreadData)];
};
static Atomic <int> lastThreadId;
static ThreadLocalValue <PerThreadDataStorage> threadLocal;
static PerThreadData& getPerThreadData ();
struct Lists
{
GlobalThreadList allThreads;
};
static CriticalSection& getGlobalMutex ();
static Lists& getLists ();
};
} // namespace detail
#endif

View File

@@ -0,0 +1,476 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace detail
{
// Example:
//
// m_mutex[2] @ beast_deadlineTimer.cpp(25)
//
String detail::TrackedMutexBasics::createName (String name,
char const* fileName, int lineNumber, int instanceNumber)
{
return name +
((instanceNumber > 1) ?
(String ("[") + String::fromNumber (instanceNumber) + "] (") : " (") +
Debug::getFileNameFromPath (fileName) + "," +
String::fromNumber (lineNumber) + ")";
}
Atomic <int> TrackedMutexBasics::lastThreadId;
ThreadLocalValue <TrackedMutexBasics::PerThreadDataStorage> TrackedMutexBasics::threadLocal;
TrackedMutexBasics::PerThreadData::PerThreadData ()
: id (++lastThreadId)
{
}
TrackedMutexBasics::PerThreadData& TrackedMutexBasics::getPerThreadData ()
{
PerThreadData& thread (*reinterpret_cast <PerThreadData*>(&threadLocal.get ()));
// Manually call the constructor with placement new if needed
if (! thread.id)
{
::new (&thread) PerThreadData ();
bassert (thread.id != 0);
}
return thread;
}
CriticalSection& TrackedMutexBasics::getGlobalMutex ()
{
static CriticalSection mutex;
return mutex;
}
TrackedMutexBasics::Lists& TrackedMutexBasics::getLists ()
{
static Lists lists;
return lists;
}
//------------------------------------------------------------------------------
} // namespace detail
//==============================================================================
TrackedMutex::Record::Record (String mutexName,
String threadName, String sourceLocation)
: m_mutexName (mutexName)
, m_threadName (threadName)
, m_sourceLocation (sourceLocation)
{
}
TrackedMutex::Record::Record () noexcept
{
}
TrackedMutex::Record::Record (Record const& other) noexcept
: m_mutexName (other.m_mutexName)
, m_threadName (other.m_threadName)
, m_sourceLocation (other.m_sourceLocation)
{
}
TrackedMutex::Record& TrackedMutex::Record::operator= (Record const& other) noexcept
{
m_mutexName = other.m_mutexName;
m_threadName = other.m_threadName;
m_sourceLocation = other.m_sourceLocation;
return *this;
}
bool TrackedMutex::Record::isNull () const noexcept
{
return m_mutexName == "";
}
bool TrackedMutex::Record::isNotNull () const noexcept
{
return m_mutexName != "";
}
bool TrackedMutex::Record::asBoolean () const noexcept
{
return isNotNull ();
}
String TrackedMutex::Record::getMutexName () const noexcept
{
return m_mutexName;
}
String TrackedMutex::Record::getThreadName () const noexcept
{
return m_threadName;
}
String TrackedMutex::Record::getSourceLocation () const noexcept
{
return m_sourceLocation;
}
//------------------------------------------------------------------------------
TrackedMutex::Agent::Agent (detail::TrackedMutexBasics::PerThreadData* thread)
: m_thread (thread)
, m_threadName (thread->threadName)
{
}
TrackedMutex::Agent::Agent () noexcept
: m_thread (nullptr)
{
}
TrackedMutex::Agent::Agent (Agent const& other) noexcept
: m_thread (other.m_thread)
, m_threadName (other.m_threadName)
, m_blocked (other.m_blocked)
{
}
TrackedMutex::Agent& TrackedMutex::Agent::operator= (Agent const& other) noexcept
{
m_thread = other.m_thread;
m_threadName = other.m_threadName;
m_blocked = other.m_blocked;
return *this;
}
bool TrackedMutex::Agent::isNull () const noexcept
{
return m_thread == nullptr;
}
bool TrackedMutex::Agent::isNotNull () const noexcept
{
return m_thread != nullptr;
}
bool TrackedMutex::Agent::asBoolean () const noexcept
{
return isNotNull ();
}
String TrackedMutex::Agent::getThreadName () const noexcept
{
return m_threadName;
}
TrackedMutex::Record TrackedMutex::Agent::getBlockedRecord () const noexcept
{
return m_blocked;
}
bool TrackedMutex::Agent::getLockedList (Array <Record>& output)
{
bassert (isNotNull ());
output.clearQuick ();
typedef detail::TrackedMutexBasics::ThreadLockList ListType;
{
CriticalSection::ScopedLockType lock (m_thread->mutex);
ListType const& list (m_thread->list);
output.ensureStorageAllocated (list.size ());
for (ListType::const_iterator iter = list.begin ();
iter != list.end (); ++iter)
{
TrackedMutex const& mutex = *iter;
{
TrackedMutex::SharedState::ReadAccess state (mutex.m_state);
output.add (state->owner);
}
}
}
return output.size () > 0;
}
//------------------------------------------------------------------------------
TrackedMutex::State::State ()
: thread (nullptr)
{
}
//------------------------------------------------------------------------------
TrackedMutex::TrackedMutex (String const& name) noexcept
: m_name (name)
, m_count (0)
{
}
String TrackedMutex::getName () const noexcept
{
return m_name;
}
TrackedMutex::Record TrackedMutex::getOwnerRecord () const noexcept
{
{
SharedState::ReadAccess state (m_state);
return state->owner;
}
}
TrackedMutex::Agent TrackedMutex::getOwnerAgent () const noexcept
{
{
SharedState::ReadAccess state (m_state);
if (state->thread != nullptr)
return Agent (state->thread);
}
return Agent ();
}
//------------------------------------------------------------------------------
void TrackedMutex::generateGlobalBlockedReport (StringArray& report)
{
report.clear ();
{
CriticalSection::ScopedLockType lock (
detail::TrackedMutexBasics::getGlobalMutex ());
typedef detail::TrackedMutexBasics::GlobalThreadList ListType;
ListType const& list (detail::TrackedMutexBasics::getLists ().allThreads);
for (ListType::const_iterator iter = list.begin (); iter != list.end (); ++iter)
{
detail::TrackedMutexBasics::PerThreadData const* thread (
&(*iter));
typedef detail::TrackedMutexBasics::ThreadLockList LockedList;
LockedList const& owned (thread->list);
if (thread->blocked)
{
String s;
s << thread->threadName << " blocked on " <<
thread->blocked->getName () << " at " <<
thread->sourceLocation;
if (owned.size () > 0)
s << " and owns these locks:";
report.add (s);
}
else if (owned.size () > 0)
{
String s;
s << thread->threadName << " owns these locks:";
report.add (s);
}
if (owned.size () > 0)
{
for (LockedList::const_iterator iter = owned.begin (); iter != owned.end (); ++iter)
{
String s;
TrackedMutex const& mutex (*iter);
TrackedMutex::SharedState::ReadAccess state (mutex.m_state);
s << " " << mutex.getName () <<
" from " << state->owner.getSourceLocation ();
report.add (s);
}
}
}
}
}
//------------------------------------------------------------------------------
// Called before we attempt to acquire the mutex.
//
void TrackedMutex::block (char const* fileName, int lineNumber) const noexcept
{
// Get calling thread data.
detail::TrackedMutexBasics::PerThreadData& thread
(detail::TrackedMutexBasics::getPerThreadData ());
++thread.refCount;
String const sourceLocation (makeSourceLocation (fileName, lineNumber));
{
// Take a global lock.
CriticalSection::ScopedLockType globalLock (
detail::TrackedMutexBasics::getGlobalMutex ());
{
// Take a thread lock.
CriticalSection::ScopedLockType threadLock (thread.mutex);
// Set the thread's blocked record
thread.blocked = this;
thread.threadName = makeThreadName (thread);
thread.sourceLocation = sourceLocation;
// Add this thread to threads list.
if (thread.refCount == 1)
detail::TrackedMutexBasics::getLists().allThreads.push_back (thread);
}
}
}
//------------------------------------------------------------------------------
// Called after we already have ownership of the mutex
//
void TrackedMutex::acquired (char const* fileName, int lineNumber) const noexcept
{
// Retrieve the per-thread data for the calling thread.
detail::TrackedMutexBasics::PerThreadData& thread
(detail::TrackedMutexBasics::getPerThreadData ());
// If this goes off it means block() wasn't called.
bassert (thread.refCount > 0);
++m_count;
// Take ownership on the first count.
if (m_count == 1)
{
// Thread is a new owner of the mutex.
String const sourceLocation (makeSourceLocation (fileName, lineNumber));
String const threadName (makeThreadName (thread));
{
// Take a global lock.
CriticalSection::ScopedLockType globalLock (
detail::TrackedMutexBasics::getGlobalMutex ());
{
// Take a state lock.
SharedState::WriteAccess state (m_state);
// Set the mutex ownership record
state->owner = Record (getName (), threadName, sourceLocation);
state->thread = &thread;
{
// Take a thread lock.
CriticalSection::ScopedLockType threadLock (thread.mutex);
// Add the mutex to the thread's list.
thread.list.push_back (const_cast <TrackedMutex&>(*this));
// Unblock the thread record.
thread.blocked = nullptr;
thread.sourceLocation = "";
}
}
}
}
else
{
// Thread already had ownership of the mutex.
bassert (SharedState::UnlockedAccess (m_state)->thread == &thread);
// If this goes off it means we counted wrong.
bassert (thread.refCount >= m_count);
}
}
//------------------------------------------------------------------------------
void TrackedMutex::release () const noexcept
{
// If this goes off it means we don't own the mutex!
bassert (m_count > 0);
// Retrieve the per-thread data for the calling thread.
detail::TrackedMutexBasics::PerThreadData& thread
(detail::TrackedMutexBasics::getPerThreadData ());
// If this goes off it means we counted wrong.
bassert (thread.refCount >= m_count);
--m_count;
--thread.refCount;
// Give up ownership when the count drops to zero.
if (m_count == 0)
{
// Take the global mutex
CriticalSection::ScopedLockType globalLock (
detail::TrackedMutexBasics::getGlobalMutex ());
{
// Take the mutex' state lock
SharedState::WriteAccess state (m_state);
// Clear the mutex ownership record
state->owner = Record ();
state->thread = nullptr;
{
// Take the thread mutex
CriticalSection::ScopedLockType threadLock (thread.mutex);
// Remove this mutex from the list of the thread's owned locks.
thread.list.erase (thread.list.iterator_to (
const_cast <TrackedMutex&>(*this)));
// Remove this thread from the threads list.
if (thread.refCount == 0)
{
typedef detail::TrackedMutexBasics::GlobalThreadList ListType;
ListType& list (detail::TrackedMutexBasics::getLists().allThreads);
list.erase (list.iterator_to (thread));
}
}
}
}
}
//------------------------------------------------------------------------------
String TrackedMutex::makeThreadName (
detail::TrackedMutexBasics::PerThreadData const& thread) noexcept
{
String threadName;
Thread const* const currentThread (Thread::getCurrentThread ());
if (currentThread != nullptr)
threadName = currentThread->getThreadName ();
threadName = threadName + "[" + String::fromNumber (thread.id) + "]";
return threadName;
}
String TrackedMutex::makeSourceLocation (char const* fileName, int lineNumber) noexcept
{
String const sourceLocation (Debug::getFileNameFromPath (fileName, 1) + "(" +
String::fromNumber (lineNumber) + ")");
return sourceLocation;
}

View File

@@ -0,0 +1,168 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_THREAD_IMPL_TRACKEDMUTEX_H_INCLUDED
#define BEAST_CORE_THREAD_IMPL_TRACKEDMUTEX_H_INCLUDED
/** Common types and member functions for a TrackedMutex */
class TrackedMutex
: public detail::TrackedMutexBasics::ThreadLockList::Node
{
public:
class Agent;
class Location;
//--------------------------------------------------------------------------
/** A triplet identifying a mutex, a thread, and source code location.
*/
class Record : public SafeBool <Record>
{
public:
Record () noexcept;
Record (Record const& other) noexcept;
Record& operator= (Record const& other) noexcept;
bool isNull () const noexcept;
bool isNotNull () const noexcept;
bool asBoolean () const noexcept;
/** Returns the name of the mutex.
Since the Mutex may not exist after the Record record is
created, we only provide a String, which is always valid.
*/
String getMutexName () const noexcept;
/** Returns the name of the associated thread.
The name is generated at the time the record is created,
and might have changed since that time, or may no longer exist.
*/
String getThreadName () const noexcept;
/** Returns the position within the source code.
This will either be the place a lock was acquired, or the place
where a thread is trying to acquire a lock. The vaue is only
meaningful at the time the Record is created. Since then, the
thread may have changed its state.
*/
String getSourceLocation () const noexcept;
private:
friend class TrackedMutex;
Record (String mutexName, String threadName, String sourceLocation);
String m_mutexName;
String m_threadName;
String m_sourceLocation;
};
//--------------------------------------------------------------------------
/** Describes a thread that can acquire mutexes. */
class Agent : public SafeBool <Agent>
{
public:
Agent () noexcept;
Agent (Agent const& other) noexcept;
Agent& operator= (Agent const& other) noexcept;
bool isNull () const noexcept;
bool isNotNull () const noexcept;
bool asBoolean () const noexcept;
/** Returns the name of the thread.
The name is generated at the time the Agent record is created,
and might have changed since that time.
*/
String getThreadName () const noexcept;
/** Returns a Record indicating where the thread is blocked on a mutex.
If the thread is not blocked, a null Record is returned.
The value is only meaningful at the moment of the call as conditions
can change.
*/
Record getBlockedRecord () const noexcept;
/** Retrieve a list of other locks that this thread holds.
Each lock is represented by a Location indicating the place
The value is only meaningful at the moment of the call as conditions
can change.
@return `true` if the list is not empty.
*/
bool getLockedList (Array <Record>& list);
private:
friend class TrackedMutex;
explicit Agent (detail::TrackedMutexBasics::PerThreadData* thread);
detail::TrackedMutexBasics::PerThreadData* m_thread;
String m_threadName;
Record m_blocked;
};
//--------------------------------------------------------------------------
/** Retrieve the name of this mutex.
Thread safety: May be called from any thread.
*/
String getName () const noexcept;
/** Retrieve a Record for the current owner.
It is only valid at the one instant in time, as the person holding it
might have released it shortly afterwards. If there is no owner,
a null Record is returned.
*/
Record getOwnerRecord () const noexcept;
/** Retrieve the Agent for the current owner.
It is only valid at the one instant in time, as the person holding it
might have released it shortly afterwards. If there is no owner,
a null Agent is returned.
*/
Agent getOwnerAgent () const noexcept;
/** Produce a report on the state of all blocked threads. */
static void generateGlobalBlockedReport (StringArray& report);
protected:
static String makeThreadName (detail::TrackedMutexBasics::PerThreadData const&) noexcept;
static String makeSourceLocation (char const* fileName, int lineNumber) noexcept;
TrackedMutex (String const& name) noexcept;
void block (char const* fileName, int lineNumber) const noexcept;
void acquired (char const* fileName, int lineNumber) const noexcept;
void release () const noexcept;
private:
struct State
{
State ();
Record owner;
detail::TrackedMutexBasics::PerThreadData* thread;
};
typedef SharedData <State> SharedState;
String const m_name;
int mutable m_count;
SharedState mutable m_state;
};
#endif

View File

@@ -0,0 +1,95 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_THREAD_TRACKEDMUTEXTYPE_H_INCLUDED
#define BEAST_CORE_THREAD_TRACKEDMUTEXTYPE_H_INCLUDED
/** A template that gives a Mutex diagnostic tracking capabilities. */
template <typename Mutex>
class TrackedMutexType
: public TrackedMutex
{
public:
/** The type of ScopedLock to use with this TrackedMutexType object. */
typedef detail::TrackedScopedLock <TrackedMutexType <Mutex> > ScopedLockType;
/** The type of ScopedTrylock to use with this TrackedMutexType object. */
typedef detail::TrackedScopedTryLock <TrackedMutexType <Mutex> > ScopedTryLockType;
/** The type of ScopedUnlock to use with this TrackedMutexType object. */
typedef detail::TrackedScopedUnlock <TrackedMutexType <Mutex> > ScopedUnlockType;
/** Construct a mutex, keyed to a particular class.
Just pass 'this' for owner and give it the name of the data member
of your class.
*/
template <typename Object>
TrackedMutexType (Object const* object,
String name,
char const* fileName,
int lineNumber)
: TrackedMutex (detail::TrackedMutexBasics::createName <Object> (
name, fileName, lineNumber))
{
}
/** Construct a mutex, without a class association.
These will all get numbered together as a group.
*/
TrackedMutexType (String name, char const* fileName, int lineNumber)
: TrackedMutex (detail::TrackedMutexBasics::createName (name,
fileName, lineNumber))
{
}
~TrackedMutexType () noexcept
{
}
inline void lock (char const* fileName, int lineNumber) const noexcept
{
block (fileName, lineNumber);
MutexTraits <Mutex>::lock (m_mutex);
acquired (fileName, lineNumber);
}
inline void unlock () const noexcept
{
release ();
MutexTraits <Mutex>::unlock (m_mutex);
}
// VFALCO NOTE: We could use enable_if here...
inline bool try_lock (char const* fileName, int lineNumber) const noexcept
{
bool const success = MutexTraits <Mutex>::try_lock (m_mutex);
if (success)
{
// Hack, call block to prevent counts from going wrong.
block (fileName, lineNumber);
acquired (fileName, lineNumber);
}
return success;
}
private:
Mutex const m_mutex;
};
#endif

View File

@@ -0,0 +1,82 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_THREAD_IMPL_UNTRACKEDMUTEX_H_INCLUDED
#define BEAST_CORE_THREAD_IMPL_UNTRACKEDMUTEX_H_INCLUDED
/** A drop-in replacement for TrackedMutex without the tracking.
*/
template <typename Mutex>
class UntrackedMutexType
: public Uncopyable
{
public:
typedef detail::UntrackedScopedLock <UntrackedMutexType <Mutex> > ScopedLockType;
typedef detail::UntrackedScopedTryLock <UntrackedMutexType <Mutex> > ScopedTryLockType;
typedef detail::UntrackedScopedUnlock <UntrackedMutexType <Mutex> > ScopedUnlockType;
template <typename Object>
inline UntrackedMutexType (Object const*, String name, char const*, int) noexcept
{
}
inline UntrackedMutexType (String, char const*, int) noexcept
{
}
inline UntrackedMutexType () noexcept
{
}
inline ~UntrackedMutexType () noexcept
{
}
inline void lock () const noexcept
{
MutexTraits <Mutex>::lock (m_mutex);
}
inline void lock (char const*, int) const noexcept
{
MutexTraits <Mutex>::lock (m_mutex);
}
inline void unlock () const noexcept
{
MutexTraits <Mutex>::unlock (m_mutex);
}
// VFALCO NOTE: We could use enable_if here...
inline bool try_lock () const noexcept
{
return MutexTraits <Mutex>::try_lock (m_mutex);
}
inline bool try_lock (char const*, int) const noexcept
{
return MutexTraits <Mutex>::try_lock (m_mutex);
}
private:
Mutex mutable m_mutex;
};
#endif

View File

@@ -96,6 +96,20 @@ public:
/** Provides the type of scoped try-locker to use with a CriticalSection. */ /** Provides the type of scoped try-locker to use with a CriticalSection. */
typedef GenericScopedTryLock <CriticalSection> ScopedTryLockType; typedef GenericScopedTryLock <CriticalSection> ScopedTryLockType;
//--------------------------------------------------------------------------
//
// Boost concept compatibility
// http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts
//
// BasicLockable
inline void lock () const noexcept { enter (); }
inline void unlock () const noexcept { exit (); }
// Lockable
inline bool try_lock () const noexcept { return tryEnter (); }
//--------------------------------------------------------------------------
private: private:
//============================================================================== //==============================================================================

View File

@@ -24,7 +24,6 @@
#ifndef BEAST_SCOPEDLOCK_BEASTHEADER #ifndef BEAST_SCOPEDLOCK_BEASTHEADER
#define BEAST_SCOPEDLOCK_BEASTHEADER #define BEAST_SCOPEDLOCK_BEASTHEADER
//============================================================================== //==============================================================================
/** /**
Automatically locks and unlocks a mutex object. Automatically locks and unlocks a mutex object.
@@ -64,21 +63,27 @@ public:
otherwise there are no guarantees what will happen! Best just to use it otherwise there are no guarantees what will happen! Best just to use it
as a local stack object, rather than creating one with the new() operator. as a local stack object, rather than creating one with the new() operator.
*/ */
inline explicit GenericScopedLock (const LockType& lock) noexcept : lock_ (lock) { lock.enter(); } inline explicit GenericScopedLock (const LockType& lock) noexcept
: lock_ (lock)
{
lock.enter();
}
/** Destructor. /** Destructor.
The lock will be released when the destructor is called. The lock will be released when the destructor is called.
Make sure this object is created and deleted by the same thread, otherwise there are Make sure this object is created and deleted by the same thread, otherwise there are
no guarantees what will happen! no guarantees what will happen!
*/ */
inline ~GenericScopedLock() noexcept { lock_.exit(); } inline ~GenericScopedLock() noexcept
{
lock_.exit();
}
private: private:
//============================================================================== //==============================================================================
const LockType& lock_; const LockType& lock_;
}; };
//============================================================================== //==============================================================================
/** /**
Automatically unlocks and re-locks a mutex object. Automatically unlocks and re-locks a mutex object.
@@ -132,7 +137,11 @@ public:
otherwise there are no guarantees what will happen! Best just to use it otherwise there are no guarantees what will happen! Best just to use it
as a local stack object, rather than creating one with the new() operator. as a local stack object, rather than creating one with the new() operator.
*/ */
inline explicit GenericScopedUnlock (const LockType& lock) noexcept : lock_ (lock) { lock.exit(); } inline explicit GenericScopedUnlock (const LockType& lock) noexcept
: lock_ (lock)
{
lock.exit();
}
/** Destructor. /** Destructor.
@@ -141,7 +150,10 @@ public:
Make sure this object is created and deleted by the same thread, Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen! otherwise there are no guarantees what will happen!
*/ */
inline ~GenericScopedUnlock() noexcept { lock_.enter(); } inline ~GenericScopedUnlock() noexcept
{
lock_.enter();
}
private: private:
@@ -149,7 +161,6 @@ private:
const LockType& lock_; const LockType& lock_;
}; };
//============================================================================== //==============================================================================
/** /**
Automatically locks and unlocks a mutex object. Automatically locks and unlocks a mutex object.
@@ -211,10 +222,17 @@ public:
Make sure this object is created and deleted by the same thread, Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen! otherwise there are no guarantees what will happen!
*/ */
inline ~GenericScopedTryLock() noexcept { if (lockWasSuccessful) lock_.exit(); } inline ~GenericScopedTryLock() noexcept
{
if (lockWasSuccessful)
lock_.exit();
}
/** Returns true if the mutex was successfully locked. */ /** Returns true if the mutex was successfully locked. */
bool isLocked() const noexcept { return lockWasSuccessful; } bool isLocked() const noexcept
{
return lockWasSuccessful;
}
private: private:
//============================================================================== //==============================================================================
@@ -222,5 +240,5 @@ private:
const bool lockWasSuccessful; const bool lockWasSuccessful;
}; };
#endif
#endif // BEAST_SCOPEDLOCK_BEASTHEADER