tracy/test/test.cpp

416 lines
10 KiB
C++
Raw Normal View History

#include <atomic>
2017-09-22 17:32:49 +00:00
#include <chrono>
#include <iostream>
2017-10-03 23:39:43 +00:00
#include <mutex>
2017-09-22 17:32:49 +00:00
#include <thread>
2024-07-17 16:19:33 +00:00
#include <signal.h>
#include <stdlib.h>
#include "tracy/Tracy.hpp"
2017-09-22 17:32:49 +00:00
2019-06-12 23:53:47 +00:00
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_JPEG
#include "stb_image.h"
2018-08-13 10:13:28 +00:00
struct static_init_test_t
{
static_init_test_t()
{
ZoneScoped;
2024-08-08 17:52:47 +00:00
ZoneTextF( "Static %s", "init test" );
2018-08-13 10:13:28 +00:00
new char[64*1024];
}
};
static std::atomic<bool> s_triggerCrash{false};
static std::atomic<bool> s_triggerInstrumentationFailure{false};
void SignalHandler_TriggerCrash(int)
{
s_triggerCrash.store(true, std::memory_order_relaxed);
}
void SignalHandler_TriggerInstrumentationFailure(int)
{
s_triggerInstrumentationFailure.store(true, std::memory_order_relaxed);
}
2018-08-13 10:13:28 +00:00
static const static_init_test_t static_init_test;
void* operator new( std::size_t count )
{
auto ptr = malloc( count );
TracyAllocS( ptr, count, 10 );
return ptr;
}
void operator delete( void* ptr ) noexcept
{
TracyFreeS( ptr, 10 );
free( ptr );
}
2020-09-22 16:22:53 +00:00
void* CustomAlloc( size_t count )
{
auto ptr = malloc( count );
TracyAllocNS( ptr, count, 10, "Custom alloc" );
return ptr;
}
void CustomFree( void* ptr )
{
TracyFreeNS( ptr, 10, "Custom alloc" );
free( ptr );
}
2017-09-22 17:32:49 +00:00
void TestFunction()
{
tracy::SetThreadName( "First/second thread" );
2017-09-22 17:32:49 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
2017-11-14 22:24:40 +00:00
ZoneScopedN( "Test function" );
2017-09-22 17:32:49 +00:00
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
}
void ResolutionCheck()
{
tracy::SetThreadName( "Resolution check" );
2017-09-22 17:32:49 +00:00
for(;;)
{
{
ZoneScoped;
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
{
ZoneScoped;
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
}
}
2017-09-23 19:37:14 +00:00
void ScopeCheck()
{
tracy::SetThreadName( "Scope check" );
2017-09-23 19:37:14 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
ZoneScoped;
}
}
2017-09-22 17:32:49 +00:00
2017-10-04 13:41:23 +00:00
static TracyLockable( std::mutex, mutex );
2017-10-25 21:08:14 +00:00
static TracyLockable( std::recursive_mutex, recmutex );
2017-10-03 23:39:43 +00:00
void Lock1()
{
tracy::SetThreadName( "Lock 1" );
2017-10-03 23:39:43 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 4 ) );
2017-10-04 13:41:23 +00:00
std::lock_guard<LockableBase( std::mutex )> lock( mutex );
2017-10-06 16:15:00 +00:00
LockMark( mutex );
2017-10-03 23:39:43 +00:00
ZoneScoped;
std::this_thread::sleep_for( std::chrono::milliseconds( 4 ) );
}
}
void Lock2()
{
tracy::SetThreadName( "Lock 2" );
2017-10-03 23:39:43 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 3 ) );
2017-10-04 13:41:23 +00:00
std::unique_lock<LockableBase( std::mutex )> lock( mutex );
2017-10-06 16:15:00 +00:00
LockMark( mutex );
2017-10-03 23:39:43 +00:00
ZoneScoped;
std::this_thread::sleep_for( std::chrono::milliseconds( 5 ) );
}
}
void Lock3()
{
tracy::SetThreadName( "Lock 3" );
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
std::unique_lock<LockableBase( std::mutex )> lock( mutex );
LockMark( mutex );
ZoneScoped;
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
}
2017-10-25 21:08:14 +00:00
void RecLock()
{
tracy::SetThreadName( "Recursive mtx 1/2" );
2017-10-25 21:08:14 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 7 ) );
std::lock_guard<LockableBase( std::recursive_mutex )> lock1( recmutex );
TracyMessageL( "First lock" );
LockMark( recmutex );
ZoneScoped;
{
std::this_thread::sleep_for( std::chrono::milliseconds( 3 ) );
std::lock_guard<LockableBase( std::recursive_mutex )> lock2( recmutex );
TracyMessageL( "Second lock" );
LockMark( recmutex );
std::this_thread::sleep_for( std::chrono::milliseconds( 2 ) );
}
}
}
2017-10-19 16:57:41 +00:00
void Plot()
{
tracy::SetThreadNameWithHint( "Plot 1/2", -1 );
2017-10-19 16:57:41 +00:00
unsigned char i = 0;
for(;;)
{
for( int j=0; j<1024; j++ )
{
TracyPlot( "Test plot", (int64_t)i++ );
}
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
}
2017-10-20 16:30:28 +00:00
void MessageTest()
{
tracy::SetThreadName( "Message test" );
2017-10-20 16:30:28 +00:00
for(;;)
{
TracyMessage( "Tock", 4 );
std::this_thread::sleep_for( std::chrono::milliseconds( 5 ) );
}
}
2019-01-20 15:55:09 +00:00
static int Fibonacci( int n );
static inline int FibonacciInline( int n )
{
return Fibonacci( n );
}
2017-10-22 13:57:08 +00:00
static int Fibonacci( int n )
{
ZoneScoped;
if( n < 2 ) return n;
2019-01-20 15:55:09 +00:00
return FibonacciInline( n-1 ) + FibonacciInline( n-2 );
2017-10-22 13:57:08 +00:00
}
void DepthTest()
{
tracy::SetThreadName( "Depth test" );
2017-10-22 13:57:08 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
ZoneScoped;
const auto txt = "Fibonacci (15)";
ZoneText( txt, strlen( txt ) );
2017-10-22 13:57:08 +00:00
Fibonacci( 15 );
}
}
2020-05-13 16:11:48 +00:00
#ifdef __cpp_lib_shared_mutex
#include <shared_mutex>
2017-12-10 20:52:26 +00:00
static TracySharedLockable( std::shared_mutex, sharedMutex );
2017-12-10 19:36:10 +00:00
2017-12-10 20:59:17 +00:00
void SharedRead1()
2017-12-10 19:36:10 +00:00
{
tracy::SetThreadName( "Shared read 1/2" );
2017-12-10 19:36:10 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
2017-12-10 20:52:26 +00:00
std::shared_lock<SharedLockableBase( std::shared_mutex )> lock( sharedMutex );
2017-12-10 19:36:10 +00:00
std::this_thread::sleep_for( std::chrono::milliseconds( 4 ) );
}
}
2017-12-10 20:59:17 +00:00
void SharedRead2()
2017-12-10 19:36:10 +00:00
{
tracy::SetThreadName( "Shared read 3" );
2017-12-10 19:36:10 +00:00
for(;;)
{
2017-12-10 20:59:17 +00:00
std::this_thread::sleep_for( std::chrono::milliseconds( 6 ) );
std::shared_lock<SharedLockableBase( std::shared_mutex )> lock( sharedMutex );
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
}
void SharedWrite1()
{
tracy::SetThreadName( "Shared write 1" );
2017-12-10 20:59:17 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 3 ) );
std::unique_lock<SharedLockableBase( std::shared_mutex )> lock( sharedMutex );
std::this_thread::sleep_for( std::chrono::milliseconds( 2 ) );
}
}
void SharedWrite2()
{
tracy::SetThreadName( "Shared write 2" );
2017-12-10 20:59:17 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 5 ) );
2017-12-10 20:52:26 +00:00
std::unique_lock<SharedLockableBase( std::shared_mutex )> lock( sharedMutex );
2017-12-10 19:36:10 +00:00
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
}
2020-05-13 16:11:48 +00:00
#endif
2018-06-24 15:55:05 +00:00
void CaptureCallstack()
{
ZoneScopedS( 10 );
}
void CallstackTime()
{
tracy::SetThreadName( "Callstack time" );
2018-06-24 15:55:05 +00:00
for(;;)
{
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
CaptureCallstack();
}
}
2018-08-27 23:48:03 +00:00
void OnlyMemory()
{
tracy::SetThreadName( "Only memory" );
2018-08-27 23:48:03 +00:00
new int;
2020-09-22 16:22:53 +00:00
void* ptrs[16];
for( int i=1; i<16; i++ )
{
ptrs[i] = CustomAlloc( i * 1024 );
}
for( int i=1; i<16; i++ )
{
CustomFree( ptrs[i] );
}
2018-08-27 23:48:03 +00:00
}
2019-01-09 19:15:45 +00:00
static TracyLockable( std::mutex, deadlockMutex1 );
static TracyLockable( std::mutex, deadlockMutex2 );
void DeadlockTest1()
{
tracy::SetThreadName( "Deadlock test 1" );
2019-01-09 19:15:45 +00:00
deadlockMutex1.lock();
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
deadlockMutex2.lock();
}
void DeadlockTest2()
{
tracy::SetThreadName( "Deadlock test 2" );
2019-01-09 19:15:45 +00:00
deadlockMutex2.lock();
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
deadlockMutex1.lock();
}
2024-10-21 15:44:16 +00:00
void ArenaAllocatorTest()
{
tracy::SetThreadName( "Arena allocator test" );
auto arena = (char*)0x12345678;
auto aptr = arena;
for( int i=0; i<10; i++ )
{
for( int j=0; j<10; j++ )
{
const auto allocSize = 1024 + j * 128 - i * 64;
TracyAllocN( aptr, allocSize, "Arena alloc" );
aptr += allocSize;
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
TracyMemoryDiscard( "Arena alloc" );
aptr = arena;
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
}
2017-09-22 17:32:49 +00:00
int main()
{
#ifdef _WIN32
signal( SIGUSR1, SignalHandler_TriggerCrash );
signal( SIGUSR2, SignalHandler_TriggerInstrumentationFailure );
#else
struct sigaction sigusr1, oldsigusr1,sigusr2, oldsigusr2 ;
memset( &sigusr1, 0, sizeof( sigusr1 ) );
sigusr1.sa_handler = SignalHandler_TriggerCrash;
sigaction( SIGUSR1, &sigusr1, &oldsigusr1 );
memset( &sigusr2, 0, sizeof( sigusr2 ) );
sigusr2.sa_handler = SignalHandler_TriggerInstrumentationFailure;
sigaction( SIGUSR2, &sigusr2, &oldsigusr2 );
#endif
2017-09-22 17:32:49 +00:00
auto t1 = std::thread( TestFunction );
auto t2 = std::thread( TestFunction );
auto t3 = std::thread( ResolutionCheck );
2017-09-23 19:37:14 +00:00
auto t4 = std::thread( ScopeCheck );
2017-10-03 23:39:43 +00:00
auto t5 = std::thread( Lock1 );
auto t6 = std::thread( Lock2 );
auto t7 = std::thread( Lock3 );
2017-10-19 16:57:41 +00:00
auto t8 = std::thread( Plot );
auto t9 = std::thread( Plot );
2017-10-20 16:30:28 +00:00
auto t10 = std::thread( MessageTest );
2017-10-22 13:57:08 +00:00
auto t11 = std::thread( DepthTest );
2017-10-25 21:08:14 +00:00
auto t12 = std::thread( RecLock );
auto t13 = std::thread( RecLock );
2020-05-13 16:11:48 +00:00
#ifdef __cpp_lib_shared_mutex
2017-12-10 20:59:17 +00:00
auto t14 = std::thread( SharedRead1 );
auto t15 = std::thread( SharedRead1 );
auto t16 = std::thread( SharedRead2 );
auto t17 = std::thread( SharedWrite1 );
auto t18 = std::thread( SharedWrite2 );
2020-05-13 16:11:48 +00:00
#endif
2018-06-24 15:55:05 +00:00
auto t19 = std::thread( CallstackTime );
2018-08-27 23:48:03 +00:00
auto t20 = std::thread( OnlyMemory );
2019-01-09 19:15:45 +00:00
auto t21 = std::thread( DeadlockTest1 );
auto t22 = std::thread( DeadlockTest2 );
2024-10-21 15:44:16 +00:00
auto t23 = std::thread( ArenaAllocatorTest );
2017-09-22 17:32:49 +00:00
2019-06-12 23:53:47 +00:00
int x, y;
auto image = stbi_load( "image.jpg", &x, &y, nullptr, 4 );
if(image == nullptr)
{
std::cerr << "Could not find image.jpg in the current working directory, skipping" << std::endl;
}
2017-09-22 17:32:49 +00:00
for(;;)
{
2017-10-20 16:30:28 +00:00
TracyMessageL( "Tick" );
2017-09-22 17:32:49 +00:00
std::this_thread::sleep_for( std::chrono::milliseconds( 2 ) );
{
ZoneScoped;
if(s_triggerCrash.load(std::memory_order_relaxed))
{
std::cout << "Abort requested" << std::endl;
std::abort();
}
if (s_triggerInstrumentationFailure.load(std::memory_order_relaxed))
{
std::cout << "Triggering instrumentation failure" << std::endl;
char const* randomPtr = "Hello!";
TracyFree(randomPtr);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
return 2;
}
2017-09-22 17:32:49 +00:00
std::this_thread::sleep_for( std::chrono::milliseconds( 2 ) );
}
if(image != nullptr)
{
FrameImage( image, x, y, 0, false );
}
2017-09-22 17:32:49 +00:00
FrameMark;
}
}