wxWidgets/tests/thread/atomic.cpp
Vadim Zeitlin 8169464516 Suppress harmless MSVC warnings in atomic unit test
The changes of 50bc3ceb04 (Get rid of CppUnit boilerplate in atomic unit
test, 2022-05-11) resulted in warnings about possibly uninitialized
variables in this test, so do initialize them for MSVC even if it isn't
really necessary.
2022-05-23 15:05:47 +01:00

173 lines
4.3 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: tests/thread/atomic.cpp
// Purpose: wxAtomic??? unit test
// Author: Armel Asselin
// Created: 2006-12-14
// Copyright: (c) 2006 Armel Asselin
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifndef WX_PRECOMP
#endif // WX_PRECOMP
#include "wx/atomic.h"
#include "wx/thread.h"
#include "wx/dynarray.h"
#include "wx/log.h"
#include "wx/vector.h"
typedef wxVector<wxThread*> wxArrayThread;
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
static const wxInt32 ITERATIONS_NUM = 10000;
// ----------------------------------------------------------------------------
// test helper thread
// ----------------------------------------------------------------------------
namespace
{
enum ETestType
{
IncAndDecMixed,
IncOnly,
DecOnly
};
class MyThread : public wxThread
{
public:
MyThread(wxAtomicInt &operateOn, ETestType testType) : wxThread(wxTHREAD_JOINABLE),
m_operateOn(operateOn), m_testType(testType) {}
// thread execution starts here
virtual void *Entry() wxOVERRIDE;
public:
wxAtomicInt &m_operateOn;
ETestType m_testType;
};
} // anonymous namespace
// ----------------------------------------------------------------------------
// the tests themselves
// ----------------------------------------------------------------------------
TEST_CASE("Atomic::NoThread", "[atomic]")
{
wxAtomicInt int1 = 0,
int2 = 0;
for ( wxInt32 i = 0; i < ITERATIONS_NUM; ++i )
{
wxAtomicInc(int1);
wxAtomicDec(int2);
}
CHECK( int1 == ITERATIONS_NUM );
CHECK( int2 == -ITERATIONS_NUM );
}
TEST_CASE("Atomic::ReturnValue", "[atomic]")
{
wxAtomicInt i(0);
REQUIRE( wxAtomicInc(i) == 1 );
REQUIRE( wxAtomicInc(i) == 2 );
REQUIRE( wxAtomicDec(i) == 1 );
REQUIRE( wxAtomicDec(i) == 0 );
}
TEST_CASE("Atomic::WithThreads", "[atomic]")
{
int count wxDUMMY_INITIALIZE(0);
ETestType testType wxDUMMY_INITIALIZE(DecOnly);
SECTION( "2 threads using inc and dec") { count = 2; testType = IncAndDecMixed; }
SECTION("10 threads using inc and dec") { count = 10; testType = IncAndDecMixed; }
SECTION( "2 threads using inc or dec" ) { count = 2; testType = IncOnly; }
SECTION("10 threads using inc or dec" ) { count = 10; testType = IncOnly; }
wxAtomicInt int1=0;
wxArrayThread threads;
int i;
for ( i = 0; i < count; ++i )
{
ETestType actualThreadType;
switch(testType)
{
default:
actualThreadType = testType;
break;
case IncOnly:
actualThreadType = (i&1)==0 ? IncOnly : DecOnly;
break;
}
MyThread *thread = new MyThread(int1, actualThreadType);
if ( thread->Create() != wxTHREAD_NO_ERROR )
{
wxLogError(wxT("Can't create thread!"));
delete thread;
}
else
threads.push_back(thread);
}
for ( i = 0; i < count; ++i )
{
threads[i]->Run();
}
for ( i = 0; i < count; ++i )
{
// each thread should return 0, else it detected some problem
CHECK (threads[i]->Wait() == (wxThread::ExitCode)0);
delete threads[i];
}
CHECK( int1 == 0 );
}
// ----------------------------------------------------------------------------
void *MyThread::Entry()
{
wxInt32 negativeValuesSeen = 0;
for ( wxInt32 i = 0; i < ITERATIONS_NUM; ++i )
{
switch ( m_testType )
{
case IncAndDecMixed:
wxAtomicInc(m_operateOn);
if ( wxAtomicDec(m_operateOn) < 0 )
++negativeValuesSeen;
break;
case IncOnly:
wxAtomicInc(m_operateOn);
break;
case DecOnly:
wxAtomicDec(m_operateOn);
break;
}
}
return wxUIntToPtr(negativeValuesSeen);
}