Merge branch '7.0' release 7.4.0.1 into PSI-7.0
Conflicts: .gitmodules modules/database/src/ioc/db/Makefile modules/libcom/test/epicsAtomicTest.cpp modules/pvAccess modules/pvData modules/pvDatabase modules/pva2pva
This commit is contained in:
@@ -114,6 +114,11 @@ epicsThreadTest_SRCS += epicsThreadTest.cpp
|
||||
testHarness_SRCS += epicsThreadTest.cpp
|
||||
TESTS += epicsThreadTest
|
||||
|
||||
TESTPROD_HOST += epicsThreadClassTest
|
||||
epicsThreadClassTest_SRCS += epicsThreadClassTest.cpp
|
||||
testHarness_SRCS += epicsThreadClassTest.cpp
|
||||
TESTS += epicsThreadClassTest
|
||||
|
||||
TESTPROD_HOST += epicsThreadOnceTest
|
||||
epicsThreadOnceTest_SRCS += epicsThreadOnceTest.c
|
||||
testHarness_SRCS += epicsThreadOnceTest.c
|
||||
@@ -260,6 +265,16 @@ iocshTest_SRCS += iocshTest.cpp
|
||||
TESTS += iocshTest
|
||||
TESTFILES += $(wildcard ../iocshTest*.cmd)
|
||||
|
||||
TESTPROD_HOST += epicsLoadTest
|
||||
epicsLoadTest_SRCS += epicsLoadTest.cpp
|
||||
# test linked against static libCom?
|
||||
epicsLoadTest_CPPFLAGS_STATIC_YES = -DLINKING_STATIC
|
||||
epicsLoadTest_CPPFLAGS += $(epicsLoadTest_CPPFLAGS_STATIC_$(STATIC_BUILD))
|
||||
# are dynamic libraries built?
|
||||
epicsLoadTest_CPPFLAGS_SHARED_YES = -DBUILDING_SHARED_LIBRARIES
|
||||
epicsLoadTest_CPPFLAGS += $(epicsLoadTest_CPPFLAGS_SHARED_$(SHARED_LIBRARIES))
|
||||
TESTS += epicsLoadTest
|
||||
|
||||
# The testHarness runs all the test programs in a known working order.
|
||||
testHarness_SRCS += epicsRunLibComTests.c
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ protected:
|
||||
};
|
||||
|
||||
circuit::circuit ( SOCKET sockIn ) :
|
||||
sock ( sockIn ),
|
||||
sock ( sockIn ),
|
||||
id ( 0 ),
|
||||
recvWakeup ( false ),
|
||||
recvWakeup ( false ),
|
||||
sendWakeup ( false )
|
||||
{
|
||||
testOk ( this->sock != INVALID_SOCKET, "Socket valid" );
|
||||
@@ -102,7 +102,7 @@ void circuit::recvTest ()
|
||||
{
|
||||
char buf [1];
|
||||
while ( true ) {
|
||||
int status = recv ( this->sock,
|
||||
int status = recv ( this->sock,
|
||||
buf, (int) sizeof ( buf ), 0 );
|
||||
if ( status == 0 ) {
|
||||
testDiag ( "%s was disconnected", this->pName () );
|
||||
@@ -114,7 +114,7 @@ void circuit::recvTest ()
|
||||
}
|
||||
else {
|
||||
char sockErrBuf[64];
|
||||
epicsSocketConvertErrnoToString (
|
||||
epicsSocketConvertErrnoToString (
|
||||
sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
testDiag ( "%s socket recv() error was \"%s\"",
|
||||
this->pName (), sockErrBuf );
|
||||
@@ -134,14 +134,14 @@ clientCircuit::clientCircuit ( const address & addrIn ) :
|
||||
circuit ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) )
|
||||
{
|
||||
address tmpAddr = addrIn;
|
||||
int status = ::connect (
|
||||
int status = ::connect (
|
||||
this->sock, & tmpAddr.sa, sizeof ( tmpAddr ) );
|
||||
testOk ( status == 0, "Client end connected" );
|
||||
|
||||
circuit * pCir = this;
|
||||
this->id = epicsThreadCreate (
|
||||
"client circuit", epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
this->id = epicsThreadCreate (
|
||||
"client circuit", epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
socketRecvTest, pCir );
|
||||
testOk ( this->id != 0, "Client thread created" );
|
||||
}
|
||||
@@ -179,9 +179,9 @@ server::server ( const address & addrIn ) :
|
||||
|
||||
void server::start ()
|
||||
{
|
||||
this->id = epicsThreadCreate (
|
||||
"server daemon", epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
this->id = epicsThreadCreate (
|
||||
"server daemon", epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
serverDaemon, this );
|
||||
testOk ( this->id != 0, "Server thread created" );
|
||||
}
|
||||
@@ -192,7 +192,7 @@ void server::daemon ()
|
||||
// accept client side
|
||||
address addr;
|
||||
osiSocklen_t addressSize = sizeof ( addr );
|
||||
SOCKET ns = accept ( this->sock,
|
||||
SOCKET ns = accept ( this->sock,
|
||||
& addr.sa, & addressSize );
|
||||
if ( this->exit )
|
||||
break;
|
||||
@@ -256,7 +256,7 @@ MAIN(blockingSockTest)
|
||||
address addr;
|
||||
memset ( (char *) & addr, 0, sizeof ( addr ) );
|
||||
addr.ia.sin_family = AF_INET;
|
||||
addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK );
|
||||
addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK );
|
||||
addr.ia.sin_port = 0;
|
||||
|
||||
server srv ( addr );
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
// epicsAlgorithmTest.cpp
|
||||
// Authors: Jeff Hill & Andrew Johnson
|
||||
// Authors: Jeff Hill & Andrew Johnson
|
||||
|
||||
#include "epicsUnitTest.h"
|
||||
#include "epicsAlgorithm.h"
|
||||
@@ -17,47 +17,47 @@
|
||||
MAIN(epicsAlgorithm)
|
||||
{
|
||||
testPlan(22);
|
||||
|
||||
|
||||
float f1 = 3.3f;
|
||||
float f2 = 3.4f;
|
||||
float Inf = epicsINF;
|
||||
float NaN = epicsNAN;
|
||||
|
||||
|
||||
testOk(epicsMin(f1, f2) == f1, "epicsMin(f1, f2)");
|
||||
testOk(epicsMin(f1, -Inf) == -Inf, "epicsMin(f1, -Inf)");
|
||||
testOk(isnan(epicsMin(f1, NaN)), "epicsMin(f1, NaN)");
|
||||
testOk(epicsMin(f1, Inf) == f1, "epicsMin(f1, Inf)");
|
||||
|
||||
|
||||
testOk(epicsMin(f2, f1) == f1, "epicsMin(f2, f1)");
|
||||
testOk(epicsMin(-Inf, f1) == -Inf, "epicsMin(-Inf, f1)");
|
||||
testOk(isnan(epicsMin(NaN, f1)), "epicsMin(NaN, f1)");
|
||||
testOk(epicsMin(Inf, f1) == f1, "epicsMin(Inf, f1)");
|
||||
|
||||
|
||||
testOk(epicsMax(f2, f1) == f2, "epicsMax(f2, f1)");
|
||||
testOk(epicsMax(-Inf, f1) == f1, "epicsMax(-Inf, f1)");
|
||||
testOk(isnan(epicsMax(NaN, f1)), "epicsMax(NaN, f1)");
|
||||
testOk(epicsMax(Inf, f1) == Inf, "epicsMax(Inf, f1)");
|
||||
|
||||
|
||||
testOk(epicsMax(f1, f2) == f2, "epicsMax(f1, f2)");
|
||||
testOk(epicsMax(f1, -Inf) == f1, "epicsMax(f1, -Inf)");
|
||||
testOk(isnan(epicsMax(f1, NaN)), "epicsMax(f1, NaN)");
|
||||
testOk(epicsMax(f1, Inf) == Inf, "epicsMax(f1, Inf)");
|
||||
|
||||
|
||||
epicsSwap(f1, f2);
|
||||
testOk(f1==3.4f && f2==3.3f, "epicsSwap(f1, f2)");
|
||||
|
||||
|
||||
int i1 = 3;
|
||||
int i2 = 4;
|
||||
|
||||
|
||||
testOk(epicsMin(i1, i2) == i1, "epicsMin(i1,i2)");
|
||||
testOk(epicsMin(i2, i1) == i1, "epicsMin(i2,i1)");
|
||||
|
||||
|
||||
testOk(epicsMax(i1, i2) == i2, "epicsMax(i1,i2)");
|
||||
testOk(epicsMax(i2, i1) == i2, "epicsMax(i2,i1)");
|
||||
|
||||
|
||||
epicsSwap(i1, i2);
|
||||
testOk(i1 == 4 && i2 == 3, "epicsSwap(i1, i2)");
|
||||
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "testMain.h"
|
||||
|
||||
using std :: size_t;
|
||||
using namespace epics;
|
||||
using namespace epics;
|
||||
using namespace atomic;
|
||||
|
||||
class RefCtr {
|
||||
@@ -36,59 +36,59 @@ private:
|
||||
static RefCtr m_noOwnership;
|
||||
};
|
||||
|
||||
inline RefCtr :: RefCtr ()
|
||||
inline RefCtr :: RefCtr ()
|
||||
{
|
||||
epicsAtomicSetSizeT ( & m_cnt, 0 );
|
||||
}
|
||||
|
||||
inline RefCtr :: ~RefCtr ()
|
||||
{
|
||||
inline RefCtr :: ~RefCtr ()
|
||||
{
|
||||
unsigned cnt = epicsAtomicGetSizeT ( & m_cnt );
|
||||
assert ( cnt == 0u );
|
||||
assert ( cnt == 0u );
|
||||
}
|
||||
|
||||
inline void RefCtr :: reference ()
|
||||
{
|
||||
epicsAtomicIncrSizeT ( & m_cnt );
|
||||
inline void RefCtr :: reference ()
|
||||
{
|
||||
epicsAtomicIncrSizeT ( & m_cnt );
|
||||
}
|
||||
|
||||
inline void RefCtr :: unreference ()
|
||||
{
|
||||
epicsAtomicDecrSizeT ( & m_cnt );
|
||||
inline void RefCtr :: unreference ()
|
||||
{
|
||||
epicsAtomicDecrSizeT ( & m_cnt );
|
||||
}
|
||||
|
||||
RefCtr Ownership :: m_noOwnership;
|
||||
|
||||
inline Ownership :: Ownership () :
|
||||
_pRefCtr ( & m_noOwnership )
|
||||
inline Ownership :: Ownership () :
|
||||
_pRefCtr ( & m_noOwnership )
|
||||
{
|
||||
m_noOwnership.reference ();
|
||||
}
|
||||
|
||||
inline Ownership :: Ownership ( RefCtr & refCtr ) :
|
||||
_pRefCtr ( & refCtr )
|
||||
{
|
||||
refCtr.reference ();
|
||||
}
|
||||
inline Ownership :: Ownership ( RefCtr & refCtr ) :
|
||||
_pRefCtr ( & refCtr )
|
||||
{
|
||||
refCtr.reference ();
|
||||
}
|
||||
|
||||
inline Ownership :: Ownership ( const Ownership & ownership ) :
|
||||
_pRefCtr ( ownership._pRefCtr )
|
||||
{
|
||||
_pRefCtr->reference ();
|
||||
}
|
||||
inline Ownership :: Ownership ( const Ownership & ownership ) :
|
||||
_pRefCtr ( ownership._pRefCtr )
|
||||
{
|
||||
_pRefCtr->reference ();
|
||||
}
|
||||
|
||||
inline Ownership :: ~Ownership ()
|
||||
{
|
||||
_pRefCtr->unreference ();
|
||||
}
|
||||
inline Ownership :: ~Ownership ()
|
||||
{
|
||||
_pRefCtr->unreference ();
|
||||
}
|
||||
|
||||
inline Ownership & Ownership ::
|
||||
operator = ( const Ownership & ownership )
|
||||
{
|
||||
RefCtr * const pOldRefCtr = _pRefCtr;
|
||||
_pRefCtr = ownership._pRefCtr;
|
||||
_pRefCtr->reference ();
|
||||
pOldRefCtr->unreference ();
|
||||
_pRefCtr->reference ();
|
||||
pOldRefCtr->unreference ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -99,46 +99,46 @@ inline Ownership retOwnership ( const Ownership & ownership )
|
||||
|
||||
inline Ownership recurRetOwner10 ( const Ownership & ownershipIn )
|
||||
{
|
||||
Ownership ownership =
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
Ownership ownership =
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
retOwnership ( ownershipIn ) ) ) ) );
|
||||
return retOwnership (
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
return retOwnership (
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
retOwnership (
|
||||
retOwnership ( ownership ) ) ) ) );
|
||||
}
|
||||
|
||||
inline Ownership recurRetOwner100 ( const Ownership & ownershipIn )
|
||||
{
|
||||
Ownership ownership =
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
Ownership ownership =
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 ( ownershipIn ) ) ) ) );
|
||||
return recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
return recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 (
|
||||
recurRetOwner10 ( ownership ) ) ) ) );
|
||||
}
|
||||
|
||||
inline Ownership recurRetOwner1000 ( const Ownership & ownershipIn )
|
||||
{
|
||||
Ownership ownership =
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 ( ownershipIn ) ) ) ) );
|
||||
return recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
Ownership ownership =
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 ( ownershipIn ) ) ) ) );
|
||||
return recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 (
|
||||
recurRetOwner100 ( ownership ) ) ) ) );
|
||||
}
|
||||
|
||||
@@ -155,13 +155,13 @@ inline void passRefOwnership10 ( const Ownership & ownershipIn, Ownership & owne
|
||||
passRefOwnership ( ownershipTmp0, ownershipTmp1 );
|
||||
Ownership ownershipTmp2;
|
||||
passRefOwnership ( ownershipTmp1, ownershipTmp2 );
|
||||
Ownership ownershipTmp3;
|
||||
Ownership ownershipTmp3;
|
||||
passRefOwnership ( ownershipTmp2, ownershipTmp3 );
|
||||
Ownership ownershipTmp4;
|
||||
passRefOwnership ( ownershipTmp3, ownershipTmp4 );
|
||||
Ownership ownershipTmp5;
|
||||
passRefOwnership ( ownershipTmp4, ownershipTmp5 );
|
||||
Ownership ownershipTmp6;
|
||||
Ownership ownershipTmp6;
|
||||
passRefOwnership ( ownershipTmp5, ownershipTmp6 );
|
||||
Ownership ownershipTmp7;
|
||||
passRefOwnership ( ownershipTmp6, ownershipTmp7 );
|
||||
@@ -178,13 +178,13 @@ inline void passRefOwnership100 ( const Ownership & ownershipIn, Ownership & own
|
||||
passRefOwnership10 ( ownershipTmp0, ownershipTmp1 );
|
||||
Ownership ownershipTmp2;
|
||||
passRefOwnership10 ( ownershipTmp1, ownershipTmp2 );
|
||||
Ownership ownershipTmp3;
|
||||
Ownership ownershipTmp3;
|
||||
passRefOwnership10 ( ownershipTmp2, ownershipTmp3 );
|
||||
Ownership ownershipTmp4;
|
||||
passRefOwnership10 ( ownershipTmp3, ownershipTmp4 );
|
||||
Ownership ownershipTmp5;
|
||||
passRefOwnership10 ( ownershipTmp4, ownershipTmp5 );
|
||||
Ownership ownershipTmp6;
|
||||
Ownership ownershipTmp6;
|
||||
passRefOwnership10 ( ownershipTmp5, ownershipTmp6 );
|
||||
Ownership ownershipTmp7;
|
||||
passRefOwnership10 ( ownershipTmp6, ownershipTmp7 );
|
||||
@@ -201,13 +201,13 @@ inline void passRefOwnership1000 ( const Ownership & ownershipIn, Ownership & ow
|
||||
passRefOwnership100 ( ownershipTmp0, ownershipTmp1 );
|
||||
Ownership ownershipTmp2;
|
||||
passRefOwnership100 ( ownershipTmp1, ownershipTmp2 );
|
||||
Ownership ownershipTmp3;
|
||||
Ownership ownershipTmp3;
|
||||
passRefOwnership100 ( ownershipTmp2, ownershipTmp3 );
|
||||
Ownership ownershipTmp4;
|
||||
passRefOwnership100 ( ownershipTmp3, ownershipTmp4 );
|
||||
Ownership ownershipTmp5;
|
||||
passRefOwnership100 ( ownershipTmp4, ownershipTmp5 );
|
||||
Ownership ownershipTmp6;
|
||||
Ownership ownershipTmp6;
|
||||
passRefOwnership100 ( ownershipTmp5, ownershipTmp6 );
|
||||
Ownership ownershipTmp7;
|
||||
passRefOwnership100 ( ownershipTmp6, ownershipTmp7 );
|
||||
@@ -224,14 +224,14 @@ public:
|
||||
OrdinaryIncr () : m_target ( 0 ) {}
|
||||
void run ();
|
||||
void diagnostic ( double delay );
|
||||
private:
|
||||
private:
|
||||
T m_target;
|
||||
};
|
||||
|
||||
// tests the time it takes to perform a call to an external
|
||||
// function and also increment an integer word. The
|
||||
// epicsInterruptIsInterruptContext function is an
|
||||
// out-of-line function implemented in a sharable library
|
||||
// tests the time it takes to perform a call to an external
|
||||
// function and also increment an integer word. The
|
||||
// epicsInterruptIsInterruptContext function is an
|
||||
// out-of-line function implemented in a sharable library
|
||||
// so hopefully it wont be optimized away.
|
||||
template < class T >
|
||||
inline void OrdinaryIncr < T > :: run ()
|
||||
@@ -254,7 +254,7 @@ void OrdinaryIncr < T > :: diagnostic ( double delay )
|
||||
delay /= 10.0;
|
||||
delay *= 1e6;
|
||||
const char * const pName = typeid ( T ) . name ();
|
||||
testDiag ( "raw incr of \"%s\" and a NOOP function call takes %f microseconds",
|
||||
testDiag ( "raw incr of \"%s\" and a NOOP function call takes %f microseconds",
|
||||
pName, delay );
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ public:
|
||||
AtomicIncr () : m_target ( 0 ) {}
|
||||
void run ();
|
||||
void diagnostic ( double delay );
|
||||
private:
|
||||
private:
|
||||
T m_target;
|
||||
};
|
||||
|
||||
@@ -289,7 +289,7 @@ void AtomicIncr < T > :: diagnostic ( double delay )
|
||||
delay /= 10.0;
|
||||
delay *= 1e6;
|
||||
const char * const pName = typeid ( T ) . name ();
|
||||
testDiag ( "epicsAtomicIncr \"%s\" takes %f microseconds",
|
||||
testDiag ( "epicsAtomicIncr \"%s\" takes %f microseconds",
|
||||
pName, delay );
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ inline int trueValue < int > () { return 1; }
|
||||
template <>
|
||||
inline int falseValue < int > () { return 0; }
|
||||
|
||||
// size_t
|
||||
// size_t
|
||||
template <>
|
||||
inline size_t trueValue < size_t > () { return 1u; }
|
||||
|
||||
@@ -312,11 +312,11 @@ inline size_t falseValue < size_t > () { return 0u; }
|
||||
|
||||
// EpicsAtomicPtrT
|
||||
template <>
|
||||
inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > ()
|
||||
inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > ()
|
||||
{ static char c; return & c; }
|
||||
|
||||
template <>
|
||||
inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > ()
|
||||
inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > ()
|
||||
{ return 0u; }
|
||||
|
||||
template < class T >
|
||||
@@ -325,7 +325,7 @@ public:
|
||||
AtomicCmpAndSwap () : m_target ( 0 ) {}
|
||||
void run ();
|
||||
void diagnostic ( double delay );
|
||||
private:
|
||||
private:
|
||||
T m_target;
|
||||
};
|
||||
|
||||
@@ -350,7 +350,7 @@ void AtomicCmpAndSwap < T > :: diagnostic ( double delay )
|
||||
delay /= 10.0;
|
||||
delay *= 1e6;
|
||||
const char * const pName = typeid ( T ) . name ();
|
||||
testDiag ( "epicsAtomicCmpAndSwap of \"%s\" takes %f microseconds",
|
||||
testDiag ( "epicsAtomicCmpAndSwap of \"%s\" takes %f microseconds",
|
||||
pName, delay );
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ public:
|
||||
AtomicSet () : m_target ( 0 ) {}
|
||||
void run ();
|
||||
void diagnostic ( double delay );
|
||||
private:
|
||||
private:
|
||||
T m_target;
|
||||
};
|
||||
|
||||
@@ -385,8 +385,8 @@ void AtomicSet < T > :: diagnostic ( double delay )
|
||||
delay /= 10.0;
|
||||
delay *= 1e6;
|
||||
const char * const pName = typeid ( T ) . name ();
|
||||
testDiag ( "epicsAtomicSet of \"%s\" takes %f microseconds",
|
||||
pName, delay );
|
||||
testDiag ( "epicsAtomicSet of \"%s\" takes %f microseconds",
|
||||
pName, delay );
|
||||
}
|
||||
|
||||
static const unsigned N = 10000;
|
||||
@@ -421,7 +421,7 @@ void ownershipPassRefPerformance ()
|
||||
}
|
||||
|
||||
template < class T >
|
||||
class Ten
|
||||
class Ten
|
||||
{
|
||||
public:
|
||||
void run ();
|
||||
@@ -475,7 +475,7 @@ void measurePerformance ()
|
||||
target.diagnostic ( delay );
|
||||
}
|
||||
|
||||
template < class T >
|
||||
template < class T >
|
||||
void measure ()
|
||||
{
|
||||
measurePerformance < typename Ten < T > :: Hundred > ();
|
||||
|
||||
@@ -29,8 +29,8 @@ template < class T >
|
||||
static void incr ( void *arg )
|
||||
{
|
||||
using epics::atomic::increment;
|
||||
TestDataIncrDecr < T > * const pTestData =
|
||||
reinterpret_cast < TestDataIncrDecr < T > * > ( arg );
|
||||
TestDataIncrDecr < T > * const pTestData =
|
||||
reinterpret_cast < TestDataIncrDecr < T > * > ( arg );
|
||||
increment ( pTestData->m_testValue );
|
||||
increment ( pTestData->m_testIterations );
|
||||
}
|
||||
@@ -40,8 +40,8 @@ static void decr ( void *arg )
|
||||
{
|
||||
using epics::atomic::decrement;
|
||||
using epics::atomic::increment;
|
||||
TestDataIncrDecr < T > * const pTestData =
|
||||
reinterpret_cast < TestDataIncrDecr < T > * > ( arg );
|
||||
TestDataIncrDecr < T > * const pTestData =
|
||||
reinterpret_cast < TestDataIncrDecr < T > * > ( arg );
|
||||
decrement ( pTestData->m_testValue );
|
||||
increment ( pTestData->m_testIterations );
|
||||
}
|
||||
@@ -52,8 +52,8 @@ static void add ( void *arg )
|
||||
{
|
||||
using epics::atomic::add;
|
||||
using epics::atomic::increment;
|
||||
TestDataAddSub < T > * const pTestData =
|
||||
reinterpret_cast < TestDataAddSub < T > * > ( arg );
|
||||
TestDataAddSub < T > * const pTestData =
|
||||
reinterpret_cast < TestDataAddSub < T > * > ( arg );
|
||||
epics::atomic::add ( pTestData->m_testValue, TestDataAddSub < T > :: delta );
|
||||
increment ( pTestData->m_testIterations );
|
||||
}
|
||||
@@ -63,8 +63,8 @@ static void sub ( void *arg )
|
||||
{
|
||||
using epics::atomic::subtract;
|
||||
using epics::atomic::increment;
|
||||
TestDataAddSub < T > * const pTestData =
|
||||
reinterpret_cast < TestDataAddSub < T > * > ( arg );
|
||||
TestDataAddSub < T > * const pTestData =
|
||||
reinterpret_cast < TestDataAddSub < T > * > ( arg );
|
||||
subtract ( pTestData->m_testValue, TestDataAddSub < T > :: delta );
|
||||
increment ( pTestData->m_testIterations );
|
||||
}
|
||||
@@ -88,7 +88,7 @@ inline int trueValue < int > () { return 1; }
|
||||
template <>
|
||||
inline int falseValue < int > () { return 0; }
|
||||
|
||||
// size_t
|
||||
// size_t
|
||||
template <>
|
||||
inline size_t trueValue < size_t > () { return 1u; }
|
||||
|
||||
@@ -97,11 +97,11 @@ inline size_t falseValue < size_t > () { return 0u; }
|
||||
|
||||
// EpicsAtomicPtrT
|
||||
template <>
|
||||
inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > ()
|
||||
inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > ()
|
||||
{ static char c; return & c; }
|
||||
|
||||
template <>
|
||||
inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > ()
|
||||
inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > ()
|
||||
{ return 0u; }
|
||||
|
||||
template < class T >
|
||||
@@ -112,15 +112,15 @@ static void cas ( void *arg )
|
||||
using epics::atomic::decrement;
|
||||
using epics::atomic::compareAndSwap;
|
||||
|
||||
TestDataCAS < T > * const pTestData =
|
||||
reinterpret_cast < TestDataCAS < T > * > ( arg );
|
||||
TestDataCAS < T > * const pTestData =
|
||||
reinterpret_cast < TestDataCAS < T > * > ( arg );
|
||||
/*
|
||||
* intentionally waste cpu and maximize
|
||||
* contention for the shared data
|
||||
*/
|
||||
increment ( pTestData->m_testIterationsNotSet );
|
||||
while ( ! compareAndSwap ( pTestData->m_testValue,
|
||||
falseValue < T > (),
|
||||
while ( ! compareAndSwap ( pTestData->m_testValue,
|
||||
falseValue < T > (),
|
||||
trueValue < T > () ) ) {
|
||||
}
|
||||
decrement ( pTestData->m_testIterationsNotSet );
|
||||
@@ -137,21 +137,21 @@ void testIncrDecr ()
|
||||
static const size_t N = 90;
|
||||
static const T NT = static_cast < T > ( N );
|
||||
|
||||
const unsigned int stackSize =
|
||||
const unsigned int stackSize =
|
||||
epicsThreadGetStackSize ( epicsThreadStackSmall );
|
||||
|
||||
TestDataIncrDecr < T > testData = { 0, N };
|
||||
set ( testData.m_testValue, NT );
|
||||
testOk ( get ( testData.m_testValue ) == NT,
|
||||
"get returns initial incr/decr test data value that was set" );
|
||||
"get returns initial incr/decr test data value that was set" );
|
||||
set ( testData.m_testIterations, 0u );
|
||||
testOk ( get ( testData.m_testIterations ) == 0u,
|
||||
"get returns initial incr/decr test thread iterations value that was set" );
|
||||
"get returns initial incr/decr test thread iterations value that was set" );
|
||||
for ( size_t i = 0u; i < N; i++ ) {
|
||||
epicsThreadMustCreate ( "incr",
|
||||
50, stackSize, incr < T >, & testData );
|
||||
50, stackSize, incr < T >, & testData );
|
||||
epicsThreadMustCreate ( "decr",
|
||||
50, stackSize, decr < T >, & testData );
|
||||
50, stackSize, decr < T >, & testData );
|
||||
if(i%10==0)
|
||||
testDiag("iteration %u", (unsigned)i);
|
||||
}
|
||||
@@ -159,9 +159,9 @@ void testIncrDecr ()
|
||||
epicsThreadSleep ( 0.01 );
|
||||
}
|
||||
testOk ( get ( testData.m_testIterations ) == 2 * N,
|
||||
"proper number of incr/decr test thread iterations" );
|
||||
testOk ( get ( testData.m_testValue ) == NT,
|
||||
"proper final incr/decr test value" );
|
||||
"proper number of incr/decr test thread iterations" );
|
||||
testOk ( get ( testData.m_testValue ) == NT,
|
||||
"proper final incr/decr test value" );
|
||||
}
|
||||
|
||||
template < class T >
|
||||
@@ -172,31 +172,31 @@ void testAddSub ()
|
||||
|
||||
static const size_t N = 90;
|
||||
static const T NDT = TestDataAddSub < T > :: delta *
|
||||
static_cast < T > ( N );
|
||||
static_cast < T > ( N );
|
||||
|
||||
const unsigned int stackSize =
|
||||
const unsigned int stackSize =
|
||||
epicsThreadGetStackSize ( epicsThreadStackSmall );
|
||||
|
||||
TestDataIncrDecr < T > testData = { 0, N };
|
||||
set ( testData.m_testValue, NDT );
|
||||
testOk ( get ( testData.m_testValue ) == NDT,
|
||||
"get returns initial add/sub test data value that was set" );
|
||||
"get returns initial add/sub test data value that was set" );
|
||||
set ( testData.m_testIterations, 0u );
|
||||
testOk ( get ( testData.m_testIterations ) == 0u,
|
||||
"get returns initial incr/decr test thread iterations value that was set" );
|
||||
"get returns initial incr/decr test thread iterations value that was set" );
|
||||
for ( size_t i = 0u; i < N; i++ ) {
|
||||
epicsThreadMustCreate ( "add",
|
||||
50, stackSize, add < T >, & testData );
|
||||
50, stackSize, add < T >, & testData );
|
||||
epicsThreadMustCreate ( "sub",
|
||||
50, stackSize, sub < T >, & testData );
|
||||
50, stackSize, sub < T >, & testData );
|
||||
}
|
||||
while ( testData.m_testIterations < 2 * N ) {
|
||||
epicsThreadSleep ( 0.01 );
|
||||
}
|
||||
testOk ( get ( testData.m_testIterations ) == 2 * N,
|
||||
"proper number of add/sub test thread iterations" );
|
||||
testOk ( get ( testData.m_testValue ) == NDT,
|
||||
"proper final add/sub test value" );
|
||||
"proper number of add/sub test thread iterations" );
|
||||
testOk ( get ( testData.m_testValue ) == NDT,
|
||||
"proper final add/sub test value" );
|
||||
}
|
||||
|
||||
template < class T >
|
||||
@@ -205,35 +205,35 @@ void testCAS ()
|
||||
using epics::atomic::set;
|
||||
using epics::atomic::get;
|
||||
|
||||
static const size_t N = 10;
|
||||
static const size_t N = 10;
|
||||
|
||||
const unsigned int stackSize =
|
||||
const unsigned int stackSize =
|
||||
epicsThreadGetStackSize ( epicsThreadStackSmall );
|
||||
|
||||
TestDataCAS < T > testData = { 0, N, N };
|
||||
set ( testData.m_testIterationsSet, 0 );
|
||||
testOk ( get ( testData.m_testIterationsSet ) == 0u,
|
||||
"get returns initial CAS test thread "
|
||||
TestDataCAS < T > testData = { 0, N, N };
|
||||
set ( testData.m_testIterationsSet, 0 );
|
||||
testOk ( get ( testData.m_testIterationsSet ) == 0u,
|
||||
"get returns initial CAS test thread "
|
||||
"iterations set value" );
|
||||
set ( testData.m_testIterationsNotSet, 0 );
|
||||
testOk ( get ( testData.m_testIterationsNotSet ) == 0u,
|
||||
"get returns initial CAS test thread "
|
||||
set ( testData.m_testIterationsNotSet, 0 );
|
||||
testOk ( get ( testData.m_testIterationsNotSet ) == 0u,
|
||||
"get returns initial CAS test thread "
|
||||
"iterations not set value" );
|
||||
set ( testData.m_testValue, trueValue < T > () );
|
||||
testOk ( get ( testData.m_testValue ) == trueValue < T > (),
|
||||
"set/get a true value" );
|
||||
for ( size_t i = 0u; i < N; i++ ) {
|
||||
set ( testData.m_testValue, trueValue < T > () );
|
||||
testOk ( get ( testData.m_testValue ) == trueValue < T > (),
|
||||
"set/get a true value" );
|
||||
for ( size_t i = 0u; i < N; i++ ) {
|
||||
epicsThreadMustCreate ( "tns",
|
||||
50, stackSize, cas < T >, & testData );
|
||||
}
|
||||
set ( testData.m_testValue, falseValue < T > () );
|
||||
while ( testData.m_testIterationsSet < N ) {
|
||||
epicsThreadSleep ( 0.01 );
|
||||
}
|
||||
testOk ( get ( testData.m_testIterationsSet ) == N,
|
||||
"proper number of CAS test thread set iterations" );
|
||||
testOk ( get ( testData.m_testIterationsNotSet ) == 0u,
|
||||
"proper number of CAS test thread not set iterations" );
|
||||
50, stackSize, cas < T >, & testData );
|
||||
}
|
||||
set ( testData.m_testValue, falseValue < T > () );
|
||||
while ( testData.m_testIterationsSet < N ) {
|
||||
epicsThreadSleep ( 0.01 );
|
||||
}
|
||||
testOk ( get ( testData.m_testIterationsSet ) == N,
|
||||
"proper number of CAS test thread set iterations" );
|
||||
testOk ( get ( testData.m_testIterationsNotSet ) == 0u,
|
||||
"proper number of CAS test thread not set iterations" );
|
||||
}
|
||||
|
||||
// template instances, needed for vxWorks 5.5.2
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
// Author: Andrew Johnson
|
||||
// Author: Andrew Johnson
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -21,7 +21,7 @@
|
||||
double doCalc(const char *expr) {
|
||||
/* Evaluate expression, return result */
|
||||
double args[CALCPERFORM_NARGS] = {
|
||||
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0
|
||||
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0
|
||||
};
|
||||
char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1));
|
||||
short err;
|
||||
@@ -34,11 +34,11 @@ double doCalc(const char *expr) {
|
||||
}
|
||||
|
||||
if (postfix(expr, rpn, &err)) {
|
||||
testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr);
|
||||
testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr);
|
||||
} else
|
||||
if (calcPerform(args, &result, rpn) && finite(result)) {
|
||||
testDiag("calcPerform: error evaluating '%s'", expr);
|
||||
}
|
||||
if (calcPerform(args, &result, rpn) && finite(result)) {
|
||||
testDiag("calcPerform: error evaluating '%s'", expr);
|
||||
}
|
||||
free(rpn);
|
||||
return result;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ void testUInt32Calc(const char *expr, epicsUInt32 expected) {
|
||||
testDiag("calcPerform: error evaluating '%s'", expr);
|
||||
}
|
||||
|
||||
uresult = (epicsUInt32) result;
|
||||
uresult = (result < 0.0 ? (epicsUInt32)(epicsInt32)result : (epicsUInt32)result);
|
||||
pass = (uresult == expected);
|
||||
if (!testOk(pass, "%s", expr)) {
|
||||
testDiag("Expected result is 0x%x (%u), actually got 0x%x (%u)",
|
||||
@@ -295,9 +295,9 @@ MAIN(epicsCalcTest)
|
||||
{
|
||||
int repeat;
|
||||
const double a=1.0, b=2.0, c=3.0, d=4.0, e=5.0, f=6.0,
|
||||
g=7.0, h=8.0, i=9.0, j=10.0, k=11.0, l=12.0;
|
||||
|
||||
testPlan(613);
|
||||
g=7.0, h=8.0, i=9.0, j=10.0, k=11.0, l=12.0;
|
||||
|
||||
testPlan(630);
|
||||
|
||||
/* LITERAL_OPERAND elements */
|
||||
testExpr(0);
|
||||
@@ -320,7 +320,7 @@ MAIN(epicsCalcTest)
|
||||
testExpr(Inf);
|
||||
testCalc("Infinity", Inf);
|
||||
testExpr(NaN);
|
||||
|
||||
|
||||
/* OPERAND elements */
|
||||
testExpr(a);
|
||||
testExpr(b);
|
||||
@@ -337,22 +337,22 @@ MAIN(epicsCalcTest)
|
||||
testExpr(PI);
|
||||
testExpr(D2R);
|
||||
testExpr(R2D);
|
||||
|
||||
|
||||
for (repeat=0; repeat<100; repeat++) {
|
||||
double res = doCalc("rndm");
|
||||
if (res<0 || res >1) {
|
||||
testDiag("rndm returned %g", res);
|
||||
break;
|
||||
}
|
||||
double res = doCalc("rndm");
|
||||
if (res<0 || res >1) {
|
||||
testDiag("rndm returned %g", res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
testOk(repeat == 100, "rndm");
|
||||
|
||||
|
||||
/* UNARY_MINUS element */
|
||||
testExpr(-1);
|
||||
testExpr(-Inf);
|
||||
testExpr(- -1);
|
||||
testCalc("-0x80000000", 2147483648.0);
|
||||
|
||||
|
||||
/* UNARY_OPERATOR elements */
|
||||
testExpr((1));
|
||||
testExpr(!0);
|
||||
@@ -544,7 +544,7 @@ MAIN(epicsCalcTest)
|
||||
testExpr(tanh(0.5));
|
||||
testExpr(~5);
|
||||
testExpr(~~5);
|
||||
|
||||
|
||||
/* BINARY_OPERATOR elements */
|
||||
testExpr(0 != 1);
|
||||
testExpr(0 != 0);
|
||||
@@ -565,24 +565,24 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN != Inf);
|
||||
testExpr(NaN != -Inf);
|
||||
testExpr(NaN != NaN);
|
||||
|
||||
|
||||
testCalc("0 # 1", 0 != 1);
|
||||
testCalc("0 # 0", 0 != 0);
|
||||
testCalc("1 # 0", 1 != 0);
|
||||
testCalc("1 # 0 # 2", 1 != 0 != 2);
|
||||
|
||||
|
||||
testExpr(7 % 4);
|
||||
testExpr(-7 % 4);
|
||||
testExpr(63 % 16 % 6)
|
||||
testCalc("1 % 0", NaN);
|
||||
|
||||
|
||||
testExpr(7 & 4);
|
||||
|
||||
|
||||
testExpr(0 && 0);
|
||||
testExpr(0 && 1);
|
||||
testExpr(1 && 0);
|
||||
testExpr(1 && 1);
|
||||
|
||||
|
||||
testExpr(2 * 2);
|
||||
testExpr(0.0 * Inf);
|
||||
testExpr(0.0 * -Inf);
|
||||
@@ -599,32 +599,38 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN * Inf);
|
||||
testExpr(NaN * -Inf);
|
||||
testExpr(NaN * NaN);
|
||||
|
||||
|
||||
testCalc("2 ** 0.2", pow(2., 0.2));
|
||||
testCalc("2 ** -0.2", pow(2., -0.2));
|
||||
testCalc("-0.2 ** 2", pow(-0.2, 2.));
|
||||
testCalc("-0.2 ** -2", pow(-0.2, -2));
|
||||
testCalc("2 ** 2 ** 3", pow(pow(2., 2.), 3.));
|
||||
|
||||
|
||||
testExpr(0 + 1);
|
||||
testExpr(0.0 + Inf);
|
||||
testExpr(0.0 + -Inf);
|
||||
testExpr(0.0 + NaN);
|
||||
testExpr(Inf + 0.0);
|
||||
testExpr(Inf + Inf);
|
||||
// only test CALC as MSVC seems to incorrectly evaluate this expression at compile time.
|
||||
// see note in epicsMathTest
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
testCalc("Inf + -Inf", NaN);
|
||||
#else
|
||||
testExpr(Inf + -Inf);
|
||||
#endif
|
||||
testExpr(Inf + NaN);
|
||||
testExpr(-Inf + 0.0);
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
testCalc("-Inf + Inf", NaN);
|
||||
#else
|
||||
testExpr(-Inf + Inf);
|
||||
#endif
|
||||
testExpr(-Inf + -Inf);
|
||||
testExpr(-Inf + NaN);
|
||||
testExpr(NaN + 0.0);
|
||||
testExpr(NaN + Inf);
|
||||
testExpr(NaN + -Inf);
|
||||
testExpr(NaN + NaN);
|
||||
|
||||
|
||||
testExpr(0 - 1);
|
||||
testExpr(0 - 1 - 2);
|
||||
testExpr(0.0 - Inf);
|
||||
@@ -642,7 +648,7 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN - Inf);
|
||||
testExpr(NaN - -Inf);
|
||||
testExpr(NaN - NaN);
|
||||
|
||||
|
||||
testExpr(2.0 / 3.0);
|
||||
testExpr(1.0 / 2.0 / 3.0);
|
||||
testExpr(0.0 / Inf);
|
||||
@@ -660,7 +666,7 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN / Inf);
|
||||
testExpr(NaN / -Inf);
|
||||
testExpr(NaN / NaN);
|
||||
|
||||
|
||||
testExpr(0 < 1);
|
||||
testExpr(0 < 0);
|
||||
testExpr(1 < 0);
|
||||
@@ -680,10 +686,10 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN < Inf);
|
||||
testExpr(NaN < -Inf);
|
||||
testExpr(NaN < NaN);
|
||||
|
||||
|
||||
testExpr(1 << 2);
|
||||
testExpr(1 << 3 << 2)
|
||||
|
||||
testExpr(1 << 3 << 2);
|
||||
|
||||
testExpr(0 <= 1);
|
||||
testExpr(0 <= 0);
|
||||
testExpr(1 <= 0);
|
||||
@@ -703,12 +709,12 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN <= Inf);
|
||||
testExpr(NaN <= -Inf);
|
||||
testExpr(NaN <= NaN);
|
||||
|
||||
|
||||
testCalc("0 = 1", 0 == 1);
|
||||
testCalc("0 = 0", 0 == 0);
|
||||
testCalc("1 = 0", 1 == 0);
|
||||
testCalc("2 = 2 = 1", 2 == 2 == 1);
|
||||
|
||||
|
||||
testExpr(0 == 1);
|
||||
testExpr(0 == 0);
|
||||
testExpr(1 == 0);
|
||||
@@ -728,7 +734,7 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN == Inf);
|
||||
testExpr(NaN == -Inf);
|
||||
testExpr(NaN == NaN);
|
||||
|
||||
|
||||
testExpr(0 > 1);
|
||||
testExpr(0 > 0);
|
||||
testExpr(1 > 0);
|
||||
@@ -748,7 +754,7 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN > Inf);
|
||||
testExpr(NaN > -Inf);
|
||||
testExpr(NaN > NaN);
|
||||
|
||||
|
||||
testExpr(0 >= 1);
|
||||
testExpr(0 >= 0);
|
||||
testExpr(1 >= 0);
|
||||
@@ -768,29 +774,31 @@ MAIN(epicsCalcTest)
|
||||
testExpr(NaN >= Inf);
|
||||
testExpr(NaN >= -Inf);
|
||||
testExpr(NaN >= NaN);
|
||||
|
||||
|
||||
testExpr(8 >> 1);
|
||||
testCalc("8 >>> 1", 8u >> 1u);
|
||||
testExpr(64 >> 2 >> 1);
|
||||
|
||||
testCalc("64 >>> 2 >>> 1", 64u >> 2u >> 1u);
|
||||
|
||||
testExpr(7 AND 4);
|
||||
|
||||
|
||||
testExpr(1 OR 8);
|
||||
|
||||
|
||||
testExpr(3 XOR 9);
|
||||
|
||||
|
||||
testCalc("2 ^ 0.2", pow(2., 0.2));
|
||||
testCalc("2 ^ -0.2", pow(2., -0.2));
|
||||
testCalc("(-0.2) ^ 2", pow(-0.2, 2.));
|
||||
testCalc("(-0.2) ^ -2", pow(-0.2, -2.));
|
||||
testCalc("2 ^ 2 ^ 3", pow(pow(2., 2.), 3.));
|
||||
|
||||
|
||||
testExpr(1 | 8);
|
||||
|
||||
|
||||
testExpr(0 || 0);
|
||||
testExpr(0 || 1);
|
||||
testExpr(1 || 0);
|
||||
testExpr(1 || 1);
|
||||
|
||||
|
||||
/* CONDITIONAL elements */
|
||||
testExpr(0 ? 1 : 2);
|
||||
testExpr(1 ? 1 : 2);
|
||||
@@ -804,7 +812,7 @@ MAIN(epicsCalcTest)
|
||||
testExpr(0 ? 2 : 1 ? 3 : 4);
|
||||
testExpr(1 ? 2 : 0 ? 3 : 4);
|
||||
testExpr(1 ? 2 : 1 ? 3 : 4);
|
||||
|
||||
|
||||
/* STORE_OPERATOR and EXPR_TERM elements*/
|
||||
testCalc("a := 0; a", 0);
|
||||
testCalc("b := 0; b", 0);
|
||||
@@ -818,7 +826,7 @@ MAIN(epicsCalcTest)
|
||||
testCalc("j := 0; j", 0);
|
||||
testCalc("k := 0; k", 0);
|
||||
testCalc("l := 0; l", 0);
|
||||
|
||||
|
||||
testCalc("a; a := 0", a);
|
||||
testCalc("b; b := 0", b);
|
||||
testCalc("c; c := 0", c);
|
||||
@@ -831,66 +839,69 @@ MAIN(epicsCalcTest)
|
||||
testCalc("j; j := 0", j);
|
||||
testCalc("k; k := 0", k);
|
||||
testCalc("l; l := 0", l);
|
||||
|
||||
|
||||
// Check relative precedences.
|
||||
testExpr(0 ? 1 : 2 | 4); // 0 1
|
||||
testExpr(1 ? 1 : 2 | 4); // 0 1
|
||||
testExpr(0 ? 2 | 4 : 1); // 0 1
|
||||
testExpr(1 ? 2 | 4 : 1); // 0 1
|
||||
testExpr(0 ? 1 : 2 & 3); // 0 2
|
||||
testExpr(1 ? 1 : 2 & 3); // 0 2
|
||||
testExpr(0 ? 2 & 3 : 1); // 0 2
|
||||
testExpr(1 ? 2 & 3 : 1); // 0 2
|
||||
testExpr(0 ? 2 : 3 >= 1); // 0 3
|
||||
testExpr(0 ? 3 >= 1 : 2); // 0 3
|
||||
testExpr(1 ? 0 == 1 : 2); // 0 3
|
||||
testExpr(1 ? 2 : 0 == 1); // 0 3
|
||||
testExpr(0 ? 1 : 2 + 4); // 0 4
|
||||
testExpr(1 ? 1 : 2 + 4); // 0 4
|
||||
testExpr(0 ? 2 + 4 : 1); // 0 4
|
||||
testExpr(1 ? 2 + 4 : 1); // 0 4
|
||||
testExpr(0 ? 1 : 2 * 4); // 0 5
|
||||
testExpr(1 ? 1 : 2 * 4); // 0 5
|
||||
testExpr(0 ? 2 * 4 : 1); // 0 5
|
||||
testExpr(1 ? 2 * 4 : 1); // 0 5
|
||||
testCalc("0 ? 1 : 2 ** 3", 8); // 0 6
|
||||
testCalc("1 ? 1 : 2 ** 3", 1); // 0 6
|
||||
testCalc("0 ? 2 ** 3 : 1", 1); // 0 6
|
||||
testCalc("1 ? 2 ** 3 : 1", 8); // 0 6
|
||||
testCalc("1 | 3 XOR 1", (1 | 3) ^ 1); // 1 1
|
||||
testExpr(1 XOR 3 | 1); // 1 1
|
||||
testExpr(3 | 1 & 2); // 1 2
|
||||
testExpr(2 | 4 > 3); // 1 3
|
||||
testExpr(2 OR 4 > 3); // 1 3
|
||||
testExpr(2 XOR 3 >= 0); // 1 3
|
||||
testExpr(2 | 1 - 3); // 1 4
|
||||
testExpr(2 | 4 / 2); // 1 5
|
||||
testExpr(0 ? 1 : 2 | 4); // 0 1
|
||||
testExpr(1 ? 1 : 2 | 4); // 0 1
|
||||
testExpr(0 ? 2 | 4 : 1); // 0 1
|
||||
testExpr(1 ? 2 | 4 : 1); // 0 1
|
||||
testExpr(0 ? 1 : 2 & 3); // 0 2
|
||||
testExpr(1 ? 1 : 2 & 3); // 0 2
|
||||
testExpr(0 ? 2 & 3 : 1); // 0 2
|
||||
testExpr(1 ? 2 & 3 : 1); // 0 2
|
||||
testExpr(0 ? 2 : 3 >= 1); // 0 3
|
||||
testExpr(0 ? 3 >= 1 : 2); // 0 3
|
||||
testExpr(1 ? 0 == 1 : 2); // 0 3
|
||||
testExpr(1 ? 2 : 0 == 1); // 0 3
|
||||
testExpr(0 ? 1 : 2 + 4); // 0 4
|
||||
testExpr(1 ? 1 : 2 + 4); // 0 4
|
||||
testExpr(0 ? 2 + 4 : 1); // 0 4
|
||||
testExpr(1 ? 2 + 4 : 1); // 0 4
|
||||
testExpr(0 ? 1 : 2 * 4); // 0 5
|
||||
testExpr(1 ? 1 : 2 * 4); // 0 5
|
||||
testExpr(0 ? 2 * 4 : 1); // 0 5
|
||||
testExpr(1 ? 2 * 4 : 1); // 0 5
|
||||
testCalc("0 ? 1 : 2 ** 3", 8); // 0 6
|
||||
testCalc("1 ? 1 : 2 ** 3", 1); // 0 6
|
||||
testCalc("0 ? 2 ** 3 : 1", 1); // 0 6
|
||||
testCalc("1 ? 2 ** 3 : 1", 8); // 0 6
|
||||
testCalc("1 | 3 XOR 1", (1 | 3) ^ 1); // 1 1
|
||||
testExpr(1 XOR 3 | 1); // 1 1
|
||||
testExpr(3 | 1 & 2); // 1 2
|
||||
testExpr(2 | 4 > 3); // 1 3
|
||||
testExpr(2 OR 4 > 3); // 1 3
|
||||
testExpr(2 XOR 3 >= 0); // 1 3
|
||||
testExpr(2 | 1 - 3); // 1 4
|
||||
testExpr(2 | 4 / 2); // 1 5
|
||||
testCalc("1 | 2 ** 3", 1 | (int) pow(2., 3.));// 1 6
|
||||
testExpr(3 << 2 & 10); // 2 2
|
||||
testCalc("18 & 6 << 2", (18 & 6) << 2); // 2 2
|
||||
testExpr(36 >> 2 & 10); // 2 2
|
||||
testCalc("18 & 20 >> 2", (18 & 20) >> 2); // 2 2
|
||||
testExpr(3 & 4 == 4); // 2 3
|
||||
testExpr(3 AND 4 == 4); // 2 3
|
||||
testCalc("1 << 2 != 4", 1 << (2 != 4)); // 2 3
|
||||
testCalc("16 >> 2 != 4", 16 >> (2 != 4)); // 2 3
|
||||
testExpr(3 AND -2); // 2 8
|
||||
testExpr(0 < 1 ? 2 : 3); // 3 0
|
||||
testExpr(1 <= 0 ? 2 : 3); // 3 0
|
||||
testExpr(0 + -1); // 4 8
|
||||
testExpr(0 - -1); // 4 8
|
||||
testExpr(10 + 10 * 2); // 4 5
|
||||
testExpr(20 + 20 / 2); // 4 5
|
||||
testExpr(-1 + 1); // 7 4
|
||||
testExpr(-1 - 2); // 7 4
|
||||
testCalc("-2 ** 2", pow(-2., 2.)); // 7 6
|
||||
testCalc("-2 ^ 2", pow(-2., 2.)); // 7 6
|
||||
|
||||
testExpr(3 << 2 & 10); // 2 2
|
||||
testCalc("18 & 6 << 2", (18 & 6) << 2); // 2 2
|
||||
testExpr(36 >> 2 & 10); // 2 2
|
||||
testCalc("36 >>> 2 & 10", 36u >> 2u & 10u); // 2 2
|
||||
testCalc("18 & 20 >> 2", (18 & 20) >> 2); // 2 2
|
||||
testCalc("18 & 20 >>> 2", (18u & 20u) >> 2);// 2 2
|
||||
testExpr(3 & 4 == 4); // 2 3
|
||||
testExpr(3 AND 4 == 4); // 2 3
|
||||
testCalc("1 << 2 != 4", 1 << (2 != 4)); // 2 3
|
||||
testCalc("16 >> 2 != 4", 16 >> (2 != 4)); // 2 3
|
||||
testCalc("16 >>> 2 != 4", 16u >> (2 != 4)); // 2 3
|
||||
testExpr(3 AND -2); // 2 8
|
||||
testExpr(0 < 1 ? 2 : 3); // 3 0
|
||||
testExpr(1 <= 0 ? 2 : 3); // 3 0
|
||||
testExpr(0 + -1); // 4 8
|
||||
testExpr(0 - -1); // 4 8
|
||||
testExpr(10 + 10 * 2); // 4 5
|
||||
testExpr(20 + 20 / 2); // 4 5
|
||||
testExpr(-1 + 1); // 7 4
|
||||
testExpr(-1 - 2); // 7 4
|
||||
testCalc("-2 ** 2", pow(-2., 2.)); // 7 6
|
||||
testCalc("-2 ^ 2", pow(-2., 2.)); // 7 6
|
||||
|
||||
// Check parentheses
|
||||
testCalc("(1 | 2) ** 3", pow((double) (1 | 2), 3.));// 8 6
|
||||
testCalc("1+(1|2)**3", 1+pow((double) (1 | 2), 3.));// 8 6
|
||||
testExpr(1+(1?(1<2):(1>2))*2);
|
||||
|
||||
|
||||
testArgs("a", A_A, 0);
|
||||
testArgs("A", A_A, 0);
|
||||
testArgs("B", A_B, 0);
|
||||
@@ -905,7 +916,7 @@ MAIN(epicsCalcTest)
|
||||
testArgs("K", A_K, 0);
|
||||
testArgs("L", A_L, 0);
|
||||
testArgs("A+B+C+D+E+F+G+H+I+J+K+L",
|
||||
A_A|A_B|A_C|A_D|A_E|A_F|A_G|A_H|A_I|A_J|A_K|A_L, 0);
|
||||
A_A|A_B|A_C|A_D|A_E|A_F|A_G|A_H|A_I|A_J|A_K|A_L, 0);
|
||||
testArgs("0.1;A:=0", 0, A_A);
|
||||
testArgs("1.1;B:=0", 0, A_B);
|
||||
testArgs("2.1;C:=0", 0, A_C);
|
||||
@@ -920,7 +931,7 @@ MAIN(epicsCalcTest)
|
||||
testArgs("11.1;L:=0", 0, A_L);
|
||||
testArgs("12.1;A:=0;B:=A;C:=B;D:=C", 0, A_A|A_B|A_C|A_D);
|
||||
testArgs("13.1;B:=A;A:=B;C:=D;D:=C", A_A|A_D, A_A|A_B|A_C|A_D);
|
||||
|
||||
|
||||
// Malformed expressions
|
||||
testBadExpr("0x0.1", CALC_ERR_SYNTAX);
|
||||
testBadExpr("1*", CALC_ERR_INCOMPLETE);
|
||||
@@ -945,7 +956,11 @@ MAIN(epicsCalcTest)
|
||||
testUInt32Calc("~0xaaaaaaaa", 0x55555555u);
|
||||
testUInt32Calc("~~0xaaaaaaaa", 0xaaaaaaaau);
|
||||
testUInt32Calc("0xaaaaaaaa >> 8", 0xffaaaaaau);
|
||||
testUInt32Calc("0x55555555 >> 8", 0x00555555u);
|
||||
testUInt32Calc("0xaaaaaaaa >>> 8", 0x00aaaaaau);
|
||||
testUInt32Calc("0x55555555 >>> 8", 0x00555555u);
|
||||
testUInt32Calc("0xaaaaaaaa << 8", 0xaaaaaa00u);
|
||||
testUInt32Calc("0x55555555 << 8", 0x55555500u);
|
||||
// using integer literals assigned to variables
|
||||
testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a AND b", 0xaaaa0000u);
|
||||
testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a OR b", 0xffffaaaau);
|
||||
@@ -953,7 +968,11 @@ MAIN(epicsCalcTest)
|
||||
testUInt32Calc("a:=0xaaaaaaaa; ~a", 0x55555555u);
|
||||
testUInt32Calc("a:=0xaaaaaaaa; ~~a", 0xaaaaaaaau);
|
||||
testUInt32Calc("a:=0xaaaaaaaa; a >> 8", 0xffaaaaaau);
|
||||
testUInt32Calc("a:=0xaaaaaaaa; a >>> 8", 0x00aaaaaau);
|
||||
testUInt32Calc("a:=0xaaaaaaaa; a << 8", 0xaaaaaa00u);
|
||||
testUInt32Calc("a:=0x55555555; a >> 8", 0x00555555u);
|
||||
testUInt32Calc("a:=0x55555555; a >>> 8", 0x00555555u);
|
||||
testUInt32Calc("a:=0x55555555; a << 8", 0x55555500u);
|
||||
|
||||
// Test proper conversion of double values (+ 0.1 enforces double literal)
|
||||
// when used as inputs to the bitwise operations.
|
||||
@@ -973,9 +992,13 @@ MAIN(epicsCalcTest)
|
||||
testUInt32Calc("~ -1431655766.1", 0x55555555u);
|
||||
testUInt32Calc("~ 2863311530.1", 0x55555555u);
|
||||
testUInt32Calc("-1431655766.1 >> 0", 0xaaaaaaaau);
|
||||
testUInt32Calc("-1431655766.1 >>> 0", 0xaaaaaaaau);
|
||||
testUInt32Calc("2863311530.1 >> 0", 0xaaaaaaaau);
|
||||
testUInt32Calc("2863311530.1 >>> 0", 0xaaaaaaaau);
|
||||
testUInt32Calc("-1431655766.1 >> 0.1", 0xaaaaaaaau);
|
||||
testUInt32Calc("-1431655766.1 >>> 0.1", 0xaaaaaaaau);
|
||||
testUInt32Calc("2863311530.1 >> 0.1", 0xaaaaaaaau);
|
||||
testUInt32Calc("2863311530.1 >>> 0.1", 0xaaaaaaaau);
|
||||
testUInt32Calc("-1431655766.1 << 0", 0xaaaaaaaau);
|
||||
testUInt32Calc("2863311530.1 << 0", 0xaaaaaaaau);
|
||||
testUInt32Calc("-1431655766.1 << 0.1", 0xaaaaaaaau);
|
||||
@@ -983,4 +1006,3 @@ MAIN(epicsCalcTest)
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -65,7 +65,7 @@ static void consumer(void *arg)
|
||||
testDiag("consumer: message %p %p\n", message[0], message[1]);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
testOk(errors == 0, "consumer: errors = %d", errors);
|
||||
}
|
||||
@@ -154,31 +154,40 @@ static void eventWakeupTest(void)
|
||||
|
||||
} // extern "C"
|
||||
|
||||
static double eventWaitMeasureDelayError( const epicsEventId &id, const double & delay )
|
||||
static double eventWaitCheckDelayError( const epicsEventId &id, const double & delay )
|
||||
{
|
||||
epicsEventWaitWithTimeout ( id, 0.000001 );
|
||||
|
||||
epicsTime beg = epicsTime::getMonotonic();
|
||||
epicsEventWaitWithTimeout ( id, delay );
|
||||
epicsTime end = epicsTime::getMonotonic();
|
||||
double meas = end - beg;
|
||||
double error = fabs ( delay - meas );
|
||||
testDiag("epicsEventWaitWithTimeout(%.6f) delay error %.6f sec",
|
||||
delay, error );
|
||||
return error;
|
||||
double error = meas - delay;
|
||||
testOk(error >= 0, "epicsEventWaitWithTimeout(%.6f) delay error %.6f sec",
|
||||
delay, error);
|
||||
return fabs(error);
|
||||
}
|
||||
|
||||
#define WAITCOUNT 21
|
||||
static void eventWaitTest()
|
||||
{
|
||||
double errorSum = 0.0;
|
||||
epicsEventId event = epicsEventMustCreate ( epicsEventEmpty );
|
||||
int i;
|
||||
for ( i = 0u; i < 20; i++ ) {
|
||||
#if defined(_WIN32) || defined(__rtems__) || defined(vxWorks)
|
||||
testTodoBegin("Known issue with delay calculation");
|
||||
#endif
|
||||
|
||||
epicsEventId event = epicsEventMustCreate(epicsEventEmpty);
|
||||
double errorSum = eventWaitCheckDelayError(event, 0.0);
|
||||
|
||||
for (int i = 0; i < WAITCOUNT - 1; i++) {
|
||||
double delay = ldexp ( 1.0 , -i );
|
||||
errorSum += eventWaitMeasureDelayError ( event, delay );
|
||||
errorSum += eventWaitCheckDelayError ( event, delay );
|
||||
}
|
||||
errorSum += eventWaitMeasureDelayError ( event, 0.0 );
|
||||
epicsEventDestroy ( event );
|
||||
double meanError = errorSum / ( i + 1 );
|
||||
testOk(meanError < 0.05, "Average error %.6f sec", meanError);
|
||||
double meanError = errorSum / WAITCOUNT;
|
||||
testOk(meanError < 0.05, "Mean delay error was %.6f sec", meanError);
|
||||
|
||||
testTodoEnd();
|
||||
|
||||
epicsEventDestroy(event);
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +199,7 @@ MAIN(epicsEventTest)
|
||||
epicsEventId event;
|
||||
int status;
|
||||
|
||||
testPlan(13+SLEEPERCOUNT);
|
||||
testPlan(13 + SLEEPERCOUNT + WAITCOUNT);
|
||||
|
||||
event = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2020 Michael Davidsaver
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
#include "envDefs.h"
|
||||
#include "epicsFindSymbol.h"
|
||||
#include "epicsThread.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void loadBad()
|
||||
{
|
||||
testOk1(!epicsFindSymbol("noSuchFunction"));
|
||||
}
|
||||
|
||||
// lookup a symbol from libCom
|
||||
// which this executable is linked against (maybe statically)
|
||||
// Doesn't work for static builds on windows
|
||||
void loadCom()
|
||||
{
|
||||
testDiag("Lookup symbol from Com");
|
||||
|
||||
#if defined (_WIN32) && defined(LINKING_STATIC)
|
||||
testTodoBegin("windows static build");
|
||||
#endif
|
||||
|
||||
void* ptr = epicsFindSymbol("epicsThreadGetCPUs");
|
||||
testOk(ptr==(void*)&epicsThreadGetCPUs,
|
||||
"%p == %p (epicsThreadGetCPUs) : %s",
|
||||
ptr, (void*)&epicsThreadGetCPUs,
|
||||
epicsLoadError());
|
||||
|
||||
testTodoEnd();
|
||||
}
|
||||
|
||||
void loadCA()
|
||||
{
|
||||
testDiag("Load and lookup symbol from libca");
|
||||
|
||||
std::string libname;
|
||||
{
|
||||
std::ostringstream strm;
|
||||
// running in eg. modules/libcom/test/O.linux-x86_64-debug
|
||||
#ifdef _WIN32
|
||||
strm<<"..\\..\\..\\..\\bin\\"<<envGetConfigParamPtr(&EPICS_BUILD_TARGET_ARCH)<<"\\ca.dll";
|
||||
#else
|
||||
strm<<"../../../../lib/"<<envGetConfigParamPtr(&EPICS_BUILD_TARGET_ARCH)<<"/";
|
||||
# ifdef __APPLE__
|
||||
strm<<"libca.dylib";
|
||||
# else
|
||||
strm<<"libca.so";
|
||||
# endif
|
||||
#endif
|
||||
libname = strm.str();
|
||||
}
|
||||
testDiag("Loading %s", libname.c_str());
|
||||
|
||||
void *ptr = epicsLoadLibrary(libname.c_str());
|
||||
testOk(!!ptr, "Loaded %p : %s", ptr, epicsLoadError());
|
||||
|
||||
ptr = epicsFindSymbol("dbf_text");
|
||||
testOk(!!ptr, "dbf_text %p : %s", ptr, epicsLoadError());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(epicsLoadTest)
|
||||
{
|
||||
testPlan(4);
|
||||
|
||||
// reference to ensure linkage when linking statically,
|
||||
// and actually use the result to make extra doubly sure that
|
||||
// this call isn't optimized out by eg. an LTO pass.
|
||||
testDiag("# of CPUs %d", epicsThreadGetCPUs());
|
||||
|
||||
loadBad();
|
||||
#if defined(__rtems__) || defined(vxWorks)
|
||||
testSkip(3, "Target does not implement epicsFindSymbol()");
|
||||
#else
|
||||
loadCom();
|
||||
# if defined(BUILDING_SHARED_LIBRARIES)
|
||||
loadCA();
|
||||
# else
|
||||
testSkip(2, "Shared libraries not built");
|
||||
# endif
|
||||
#endif
|
||||
return testDone();
|
||||
}
|
||||
@@ -20,38 +20,38 @@ MAIN(epicsMathTest)
|
||||
double huge = 1e300;
|
||||
double tiny = 1e-300;
|
||||
double c;
|
||||
|
||||
|
||||
testPlan(35);
|
||||
|
||||
|
||||
testOk1(!isnan(0.0));
|
||||
testOk1(!isinf(0.0));
|
||||
|
||||
|
||||
testOk1(!isnan(epicsINF));
|
||||
testOk1(isinf(epicsINF));
|
||||
testOk1(epicsINF == epicsINF);
|
||||
testOk1(epicsINF > 0.0);
|
||||
testOk1(epicsINF - epicsINF != 0.0);
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
testTodoBegin("Known failure on windows (MSVC optimizer bug?)");
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
testTodoBegin("Known failure on windows-x64 and win32-x86");
|
||||
#endif
|
||||
testOk1(epicsINF + -epicsINF != 0.0);
|
||||
testOk1(-epicsINF + epicsINF != 0.0);
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
testTodoEnd();
|
||||
#endif
|
||||
|
||||
testOk1(isnan(epicsINF - epicsINF));
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
testTodoBegin("Known failure on windows (MSVC optimizer bug?)");
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
testTodoBegin("Known failure on windows-x64 and win32-x86");
|
||||
#endif
|
||||
testOk1(isnan(epicsINF + -epicsINF));
|
||||
testOk1(isnan(-epicsINF + epicsINF));
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
testTodoEnd();
|
||||
#endif
|
||||
|
||||
|
||||
testOk1(isnan(epicsNAN));
|
||||
testOk1(!isinf(epicsNAN));
|
||||
testOk1(epicsNAN != epicsNAN);
|
||||
@@ -62,34 +62,34 @@ MAIN(epicsMathTest)
|
||||
testOk1(!(epicsNAN > epicsNAN));
|
||||
testOk1(isnan(epicsNAN - epicsNAN));
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
testTodoBegin("Known failure on windows (MSVC optimizer bug?)");
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
testTodoBegin("Known failure on windows-x64 and win32-x86");
|
||||
#endif
|
||||
testOk1(isnan(epicsNAN + -epicsNAN));
|
||||
testOk1(isnan(-epicsNAN + epicsNAN));
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
testTodoEnd();
|
||||
#endif
|
||||
|
||||
|
||||
c = huge / tiny;
|
||||
testOk(!isnan(c), "!isnan(1e300 / 1e-300)");
|
||||
testOk(isinf(c), "isinf(1e300 / 1e-300)");
|
||||
testOk(c > 0.0, "1e300 / 1e-300 > 0.0");
|
||||
|
||||
|
||||
c = (-huge) / tiny;
|
||||
testOk(!isnan(c), "!isnan(-1e300 / 1e-300)");
|
||||
testOk(isinf(c), "isinf(-1e300 / 1e-300)");
|
||||
testOk(c < 0.0, "-1e300 / 1e-300 < 0.0");
|
||||
|
||||
|
||||
c = huge / huge;
|
||||
testOk(!isnan(c), "!isnan(1e300 / 1e300)");
|
||||
testOk(!isinf(c), "!isinf(1e300 / 1e300)");
|
||||
testOk(c == 1.0, "1e300 / 1e300 == 1.0");
|
||||
|
||||
|
||||
c = tiny / tiny;
|
||||
testOk(!isnan(c), "!isnan(1e-300 / 1e-300)");
|
||||
testOk(!isinf(c), "!isinf(1e-300 / 1e-300)");
|
||||
testOk(c == 1.0, "1e300 / 1e-300 == 1.0");
|
||||
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ static volatile int recvExit = 0;
|
||||
static epicsEventId finished;
|
||||
static unsigned int mediumStack;
|
||||
|
||||
#define SLEEPY_TESTS 500
|
||||
static int numSent, numReceived;
|
||||
static epicsEventId complete;
|
||||
|
||||
/*
|
||||
* In Numerical Recipes in C: The Art of Scientific Computing (William H.
|
||||
* Press, Brian P. Flannery, Saul A. Teukolsky, William T. Vetterling; New
|
||||
@@ -115,6 +119,112 @@ receiver(void *arg)
|
||||
epicsEventSignal(finished);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
fastReceiver(void *arg)
|
||||
{
|
||||
epicsMessageQueue *q = (epicsMessageQueue *)arg;
|
||||
char cbuf[80];
|
||||
int len;
|
||||
numReceived = 0;
|
||||
while (!recvExit) {
|
||||
len = q->receive(cbuf, sizeof cbuf, 0.010);
|
||||
if (len > 0) {
|
||||
numReceived++;
|
||||
}
|
||||
}
|
||||
recvExit = 0;
|
||||
epicsEventSignal(complete);
|
||||
}
|
||||
|
||||
void sleepySender(double delay)
|
||||
{
|
||||
testDiag("sleepySender: sending every %.3f seconds", delay);
|
||||
epicsMessageQueue q(4, 20);
|
||||
epicsThreadCreate("Fast Receiver", epicsThreadPriorityMedium,
|
||||
mediumStack, fastReceiver, &q);
|
||||
|
||||
numSent = 0;
|
||||
for (int i = 0 ; i < SLEEPY_TESTS ; i++) {
|
||||
if (q.send((void *)msg1, 4) == 0) {
|
||||
numSent++;
|
||||
}
|
||||
epicsThreadSleep(delay);
|
||||
}
|
||||
epicsThreadSleep(1.0);
|
||||
testOk(numSent == SLEEPY_TESTS, "Sent %d (should be %d)",
|
||||
numSent, SLEEPY_TESTS);
|
||||
testOk(numReceived == SLEEPY_TESTS, "Received %d (should be %d)",
|
||||
numReceived, SLEEPY_TESTS);
|
||||
|
||||
recvExit = 1;
|
||||
while (q.send((void *)msg1, 4) != 0)
|
||||
epicsThreadSleep(0.01);
|
||||
epicsEventMustWait(complete);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
fastSender(void *arg)
|
||||
{
|
||||
epicsMessageQueue *q = (epicsMessageQueue *)arg;
|
||||
numSent = 0;
|
||||
|
||||
// Send first withough timeout
|
||||
q->send((void *)msg1, 4);
|
||||
numSent++;
|
||||
|
||||
// The rest have a timeout
|
||||
while (!sendExit) {
|
||||
if (q->send((void *)msg1, 4, 0.010) == 0) {
|
||||
numSent++;
|
||||
}
|
||||
}
|
||||
sendExit = 0;
|
||||
epicsEventSignal(complete);
|
||||
}
|
||||
|
||||
void sleepyReceiver(double delay)
|
||||
{
|
||||
testDiag("sleepyReceiver: acquiring every %.3f seconds", delay);
|
||||
epicsMessageQueue q(4, 20);
|
||||
|
||||
// Fill the queue
|
||||
for (int i = q.pending(); i < 4 ;i++) {
|
||||
q.send((void *)msg1, 4);
|
||||
}
|
||||
|
||||
epicsThreadCreate("Fast Sender", epicsThreadPriorityMedium,
|
||||
mediumStack, fastSender, &q);
|
||||
epicsThreadSleep(0.5);
|
||||
|
||||
char cbuf[80];
|
||||
int len;
|
||||
numReceived = 0;
|
||||
|
||||
for (int i = 0 ; i < SLEEPY_TESTS ; i++) {
|
||||
len = q.receive(cbuf, sizeof cbuf);
|
||||
if (len > 0) {
|
||||
numReceived++;
|
||||
}
|
||||
epicsThreadSleep(delay);
|
||||
}
|
||||
|
||||
#ifdef __rtems__
|
||||
testTodoBegin("RTEMS failure expected");
|
||||
#endif
|
||||
testOk(numSent == SLEEPY_TESTS, "Sent %d (should be %d)",
|
||||
numSent, SLEEPY_TESTS);
|
||||
#ifdef __rtems__
|
||||
testTodoEnd();
|
||||
#endif
|
||||
testOk(numReceived == SLEEPY_TESTS, "Received %d (should be %d)",
|
||||
numReceived, SLEEPY_TESTS);
|
||||
|
||||
sendExit = 1;
|
||||
while (q.receive(cbuf, sizeof cbuf) <= 0)
|
||||
epicsThreadSleep(0.01);
|
||||
epicsEventMustWait(complete);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
sender(void *arg)
|
||||
{
|
||||
@@ -251,6 +361,18 @@ extern "C" void messageQueueTest(void *parm)
|
||||
testOk(q1->send((void *)msg1, 10) == 0, "Send with no receiver");
|
||||
epicsThreadSleep(2.0);
|
||||
|
||||
testDiag("6 Single receiver single sender 'Sleepy timeout' tests,");
|
||||
testDiag(" these should take about %.2f seconds each:",
|
||||
SLEEPY_TESTS * 0.010);
|
||||
|
||||
complete = epicsEventMustCreate(epicsEventEmpty);
|
||||
sleepySender(0.009);
|
||||
sleepySender(0.010);
|
||||
sleepySender(0.011);
|
||||
sleepyReceiver(0.009);
|
||||
sleepyReceiver(0.010);
|
||||
sleepyReceiver(0.011);
|
||||
|
||||
testDiag("Single receiver, single sender tests:");
|
||||
epicsThreadSetPriority(myThreadId, epicsThreadPriorityHigh);
|
||||
epicsThreadCreate("Receiver one", epicsThreadPriorityMedium,
|
||||
@@ -285,7 +407,7 @@ extern "C" void messageQueueTest(void *parm)
|
||||
* Single receiver, multiple sender tests
|
||||
*/
|
||||
testDiag("Single receiver, multiple sender tests:");
|
||||
testDiag("This test lasts 60 seconds...");
|
||||
testDiag("This test lasts 30 seconds...");
|
||||
testOk(!!epicsThreadCreate("Sender 1", epicsThreadPriorityLow,
|
||||
mediumStack, sender, q1),
|
||||
"Created Sender 1");
|
||||
@@ -299,9 +421,9 @@ extern "C" void messageQueueTest(void *parm)
|
||||
mediumStack, sender, q1),
|
||||
"Created Sender 4");
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
testDiag("... %2d", 10 - i);
|
||||
epicsThreadSleep(6.0);
|
||||
for (i = 0; i < 6; i++) {
|
||||
testDiag("... %2d", 6 - i);
|
||||
epicsThreadSleep(5.0);
|
||||
}
|
||||
|
||||
sendExit = 1;
|
||||
@@ -312,7 +434,7 @@ extern "C" void messageQueueTest(void *parm)
|
||||
|
||||
MAIN(epicsMessageQueueTest)
|
||||
{
|
||||
testPlan(62);
|
||||
testPlan(74);
|
||||
|
||||
finished = epicsEventMustCreate(epicsEventEmpty);
|
||||
mediumStack = epicsThreadGetStackSize(epicsThreadStackMedium);
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
\*************************************************************************/
|
||||
/* epicsMutexTest.c */
|
||||
|
||||
/*
|
||||
* Author: Marty Kraimer Date: 26JAN2000
|
||||
/*
|
||||
* Author: Marty Kraimer Date: 26JAN2000
|
||||
* Jeff Hill (added mutex performance test )
|
||||
*/
|
||||
|
||||
@@ -165,7 +165,7 @@ inline void tenQuadRecursiveLockPairsSquared ( epicsMutex & mutex )
|
||||
void epicsMutexPerformance ()
|
||||
{
|
||||
epicsMutex mutex;
|
||||
unsigned i;
|
||||
unsigned i;
|
||||
|
||||
// test a single lock pair
|
||||
epicsTime begin = epicsTime::getMonotonic ();
|
||||
@@ -206,7 +206,7 @@ struct verifyTryLock {
|
||||
|
||||
extern "C" void verifyTryLockThread ( void *pArg )
|
||||
{
|
||||
struct verifyTryLock *pVerify =
|
||||
struct verifyTryLock *pVerify =
|
||||
( struct verifyTryLock * ) pArg;
|
||||
|
||||
testOk1(epicsMutexTryLock(pVerify->mutex) == epicsMutexLockTimeout);
|
||||
@@ -222,7 +222,7 @@ void verifyTryLock ()
|
||||
|
||||
testOk1(epicsMutexTryLock(verify.mutex) == epicsMutexLockOK);
|
||||
|
||||
epicsThreadCreate ( "verifyTryLockThread", 40,
|
||||
epicsThreadCreate ( "verifyTryLockThread", 40,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
verifyTryLockThread, &verify );
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright: Stanford University / SLAC National Laboratory.
|
||||
*
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* Author: Till Straumann <strauman@slac.stanford.edu>, 2014
|
||||
*/
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check stack trace functionality
|
||||
@@ -132,14 +132,14 @@ findNumOcc(const char *buf)
|
||||
}
|
||||
/* We should find an address close to epicsStackTraceRecurseGbl twice */
|
||||
for (i=0; i<n_ptrs-1; i++) {
|
||||
/* I got a (unjustified) index-out-of-bound warning
|
||||
/* I got a (unjustified) index-out-of-bound warning
|
||||
* when setting j=i+1 here. Thus the weird j!= i check...
|
||||
*/
|
||||
j = i;
|
||||
while ( j < n_ptrs ) {
|
||||
if ( j != i && ptrs[j] == ptrs[i] ) {
|
||||
if ( (char*)ptrs[i] >= (char*)epicsStackTraceRecurseGbl && (char*)ptrs[i] < (char*)epicsStackTraceRecurseGbl + WINDOW_SZ ) {
|
||||
rval ++;
|
||||
rval ++;
|
||||
testDiag("found address %p again\n", ptrs[i]);
|
||||
}
|
||||
}
|
||||
@@ -160,7 +160,7 @@ MAIN(epicsStackTraceTest)
|
||||
|
||||
testPlan(5);
|
||||
|
||||
features = epicsStackTraceGetFeatures();
|
||||
features = epicsStackTraceGetFeatures();
|
||||
|
||||
all_features = EPICS_STACKTRACE_LCL_SYMBOLS
|
||||
| EPICS_STACKTRACE_GBL_SYMBOLS
|
||||
|
||||
@@ -47,9 +47,9 @@ static void testEpicsSnprintf(void) {
|
||||
|
||||
sprintf(exbuffer, format, ivalue, fvalue, svalue);
|
||||
rlen = strlen(expected)+1;
|
||||
|
||||
|
||||
strcpy(buffer, "AAAA");
|
||||
|
||||
|
||||
for (size = 1; size < strlen(expected) + 5; ++size) {
|
||||
rtn = epicsSnprintf(buffer, size, format, ivalue, fvalue, svalue);
|
||||
testOk(rtn <= rlen-1, "epicsSnprintf(size=%d) = %d", size, rtn);
|
||||
@@ -69,7 +69,7 @@ void testStdoutRedir (const char *report)
|
||||
FILE *stream = 0;
|
||||
char linebuf[80];
|
||||
size_t buflen = sizeof linebuf;
|
||||
|
||||
|
||||
testOk1(epicsGetStdout() == stdout);
|
||||
|
||||
errno = 0;
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2020 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsThreadClassTest.cpp */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
/* Key to the char's that define the test case actions:
|
||||
*
|
||||
* Upper case letters are for parent thread actions
|
||||
* B - Parent calls thread->start() and waits for child to start
|
||||
* D - Parent deletes thread. This waits for child to return if it hasn't yet
|
||||
* E - Parent calls thread->exitWait(), this may wait for child to return
|
||||
* S - Parent sleeps for SLEEP_TIME seconds
|
||||
* T - Parent sends sync trigger to child (w)
|
||||
* W - Parent waits for sync trigger from child (t)
|
||||
* X - Parent calls thread->exitWait(0)
|
||||
*
|
||||
* Lower case letters are for child thread actions
|
||||
* d - Child deletes thread
|
||||
* e - Child calls thread->exitWait()
|
||||
* r - Child returns
|
||||
* s - Child sleeps for SLEEP_TIME seconds
|
||||
* t - Child sends sync trigger to parent (W)
|
||||
* w - Child waits for sync trigger from child (T)
|
||||
*
|
||||
* Note that it is possible to write test cases that can hang,
|
||||
* segfault, or that trigger errors from thread APIs.
|
||||
*/
|
||||
|
||||
// The test cases
|
||||
|
||||
const char * const cases[] = {
|
||||
// These cases don't start the thread:
|
||||
"D", // Parent deletes thread
|
||||
"ED", // Parent does exitWait(), deletes thread
|
||||
|
||||
// In these cases the parent deletes the thread
|
||||
"BrSD", // Child returns; parent deletes thread
|
||||
"BsDr", // Parent deletes thread; child returns
|
||||
"BrSED", // Child returns; parent does exitWait(), deletes thread
|
||||
"BsErD", // Parent does exitWait(); child returns; parent deletes thread
|
||||
"BsXDr", // Parent does exitWait(0); parent deletes thread; child returns
|
||||
"BwXTDsr", // Parent does exitWait(0); parent deletes thread; child returns
|
||||
// These are currently broken
|
||||
// "BetWSrD", // Child does exitWait(); sync; child returns; parent deletes thread
|
||||
// "BetWsDr", // Child does exitWait(); sync; parent deletes thread; child returns
|
||||
|
||||
// In these cases the child deletes the thread
|
||||
"BdrS", // Child deletes thread, returns
|
||||
"BedrS", // Child does exitWait(), deletes thread, returns
|
||||
"BwXTSdr", // Parent does exitWait(0); sync; child deletes thread, returns
|
||||
|
||||
NULL // Terminator
|
||||
};
|
||||
|
||||
// How long to sleep for while the other thread works
|
||||
#define SLEEP_TIME 1.0
|
||||
|
||||
class threadCase: public epicsThreadRunable {
|
||||
public:
|
||||
threadCase(const char * const tcase);
|
||||
virtual ~threadCase();
|
||||
virtual void run();
|
||||
epicsThread *pthread;
|
||||
epicsEvent startEvt;
|
||||
epicsEvent childEvt;
|
||||
epicsEvent parentEvt;
|
||||
private:
|
||||
const char * const name;
|
||||
};
|
||||
|
||||
threadCase::threadCase(const char * const tcase) :
|
||||
pthread(new epicsThread(*this, tcase,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall))),
|
||||
name(tcase)
|
||||
{
|
||||
testDiag("Constructing test case '%s'", name);
|
||||
}
|
||||
|
||||
threadCase::~threadCase()
|
||||
{
|
||||
testDiag("Destroying test case '%s'", name);
|
||||
}
|
||||
|
||||
void threadCase::run()
|
||||
{
|
||||
testDiag("Child running for '%s'", name);
|
||||
startEvt.signal();
|
||||
|
||||
for (const char * pdo = name;
|
||||
const char tdo = *pdo;
|
||||
pdo++)
|
||||
{
|
||||
switch (tdo)
|
||||
{
|
||||
case 'd':
|
||||
testDiag("'%c': Child deleting epicsThread", tdo);
|
||||
delete pthread;
|
||||
pthread = NULL;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
testDiag("'%c': Child calling exitWait()", tdo);
|
||||
assert(pthread);
|
||||
pthread->exitWait();
|
||||
break;
|
||||
|
||||
case 's':
|
||||
testDiag("'%c': Child sleeping", tdo);
|
||||
epicsThreadSleep(SLEEP_TIME);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
testDiag("'%c': Child sending trigger", tdo);
|
||||
parentEvt.signal();
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
testDiag("'%c': Child awaiting trigger", tdo);
|
||||
childEvt.wait();
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
testDiag("'%c': Child returning", tdo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
testFail("Test case '%s' is missing 'r'", name);
|
||||
}
|
||||
|
||||
MAIN(epicsThreadClassTest)
|
||||
{
|
||||
const int ntests = NELEMENTS(cases);
|
||||
testPlan(ntests - 1); // The last element is the NULL terminator
|
||||
|
||||
for (const char * const * pcase = cases;
|
||||
const char * const tcase = *pcase;
|
||||
pcase++)
|
||||
{
|
||||
testDiag("======= Test case '%s' =======", tcase);
|
||||
threadCase thrCase(tcase);
|
||||
|
||||
for (const char * pdo = tcase;
|
||||
const char tdo = *pdo;
|
||||
pdo++)
|
||||
{
|
||||
switch (tdo)
|
||||
{
|
||||
case 'B':
|
||||
testDiag("'%c': Parent starting child", tdo);
|
||||
assert(thrCase.pthread);
|
||||
thrCase.pthread->start();
|
||||
thrCase.startEvt.wait();
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
testDiag("'%c': Parent deleting epicsThread", tdo);
|
||||
assert(thrCase.pthread);
|
||||
delete thrCase.pthread;
|
||||
thrCase.pthread = NULL;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
testDiag("'%c': Parent calling exitWait()", tdo);
|
||||
assert(thrCase.pthread);
|
||||
thrCase.pthread->exitWait();
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
testDiag("'%c': Parent calling exitWait(0)", tdo);
|
||||
assert(thrCase.pthread);
|
||||
thrCase.pthread->exitWait(0);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
testDiag("'%c': Parent sleeping", tdo);
|
||||
epicsThreadSleep(SLEEP_TIME);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
testDiag("'%c': Parent sending trigger", tdo);
|
||||
thrCase.childEvt.signal();
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
testDiag("'%c': Parent awaiting trigger", tdo);
|
||||
thrCase.parentEvt.wait();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
testPass("Test case '%s' passed", tcase);
|
||||
}
|
||||
|
||||
return testDone();
|
||||
}
|
||||
@@ -34,8 +34,8 @@ MAIN(epicsThreadPrivateTest)
|
||||
priv.set ( &var );
|
||||
testOk1 ( &var == priv.get() );
|
||||
|
||||
epicsThreadCreate ( "epicsThreadPrivateTest", epicsThreadPriorityMax,
|
||||
epicsThreadGetStackSize ( epicsThreadStackSmall ),
|
||||
epicsThreadCreate ( "epicsThreadPrivateTest", epicsThreadPriorityMax,
|
||||
epicsThreadGetStackSize ( epicsThreadStackSmall ),
|
||||
epicsThreadPrivateTestThread, 0 );
|
||||
epicsThreadSleep ( 1.0 );
|
||||
testOk1 ( &var == priv.get() );
|
||||
|
||||
@@ -62,7 +62,7 @@ void testRefCount()
|
||||
Q1->release();
|
||||
}
|
||||
|
||||
static const double delayVerifyOffset = 1.0; // sec
|
||||
static const double delayVerifyOffset = 1.0; // sec
|
||||
|
||||
class delayVerify : public epicsTimerNotify {
|
||||
public:
|
||||
@@ -112,9 +112,13 @@ double delayVerify::checkError () const
|
||||
double actualDelay = this->expireStamp - this->beginStamp;
|
||||
double measuredError = actualDelay - this->expectedDelay;
|
||||
double percentError = 100.0 * fabs ( measuredError ) / this->expectedDelay;
|
||||
if(testImpreciseTiming())
|
||||
testTodoBegin("imprecise");
|
||||
testOk ( percentError < messageThresh, "%f < %f, delay = %f s, error = %f s (%.1f %%)",
|
||||
percentError, messageThresh,
|
||||
this->expectedDelay, measuredError, percentError );
|
||||
if(testImpreciseTiming())
|
||||
testTodoEnd();
|
||||
return measuredError;
|
||||
}
|
||||
|
||||
@@ -144,7 +148,7 @@ void testAccuracy ()
|
||||
|
||||
testDiag ( "Testing timer accuracy" );
|
||||
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMax );
|
||||
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
@@ -155,7 +159,7 @@ void testAccuracy ()
|
||||
|
||||
expireCount = nTimers;
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
epicsTime cur = epicsTime::getMonotonic ();
|
||||
epicsTime cur = epicsTime::getCurrent ();
|
||||
pTimers[i]->setBegin ( cur );
|
||||
pTimers[i]->start ( cur + pTimers[i]->delay () );
|
||||
}
|
||||
@@ -167,7 +171,7 @@ void testAccuracy ()
|
||||
averageMeasuredError += pTimers[i]->checkError ();
|
||||
}
|
||||
averageMeasuredError /= nTimers;
|
||||
testDiag ("average timer delay error %f ms",
|
||||
testDiag ("average timer delay error %f ms",
|
||||
averageMeasuredError * 1000 );
|
||||
queue.release ();
|
||||
}
|
||||
@@ -238,7 +242,7 @@ void testCancel ()
|
||||
|
||||
testDiag ( "Testing timer cancellation" );
|
||||
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin );
|
||||
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
@@ -252,7 +256,7 @@ void testCancel ()
|
||||
testDiag ( "cancelCount = %u", cancelVerify::cancelCount );
|
||||
|
||||
testDiag ( "starting %d timers", nTimers );
|
||||
epicsTime exp = epicsTime::getMonotonic () + 4.0;
|
||||
epicsTime exp = epicsTime::getCurrent () + 4.0;
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i]->start ( exp );
|
||||
}
|
||||
@@ -327,7 +331,7 @@ void testExpireDestroy ()
|
||||
|
||||
testDiag ( "Testing timer destruction in expire()" );
|
||||
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin );
|
||||
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
@@ -338,7 +342,7 @@ void testExpireDestroy ()
|
||||
testOk1 ( expireDestroyVerify::destroyCount == 0 );
|
||||
|
||||
testDiag ( "starting %d timers", nTimers );
|
||||
epicsTime cur = epicsTime::getMonotonic ();
|
||||
epicsTime cur = epicsTime::getCurrent ();
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i]->start ( cur );
|
||||
}
|
||||
@@ -369,7 +373,7 @@ private:
|
||||
};
|
||||
|
||||
periodicVerify::periodicVerify ( epicsTimerQueue & queueIn ) :
|
||||
timer ( queueIn.createTimer () ), nExpire ( 0u ),
|
||||
timer ( queueIn.createTimer () ), nExpire ( 0u ),
|
||||
cancelCalled ( false )
|
||||
{
|
||||
}
|
||||
@@ -421,7 +425,7 @@ void testPeriodic ()
|
||||
|
||||
testDiag ( "Testing periodic timers" );
|
||||
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin );
|
||||
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
@@ -431,7 +435,7 @@ void testPeriodic ()
|
||||
testOk1 ( timerCount == nTimers );
|
||||
|
||||
testDiag ( "starting %d timers", nTimers );
|
||||
epicsTime cur = epicsTime::getMonotonic ();
|
||||
epicsTime cur = epicsTime::getCurrent ();
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i]->start ( cur );
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ void testTimer (fdctx *pfdm, double delay)
|
||||
|
||||
measuredDelay = epicsTimeDiffInSeconds (&cbs.time, &begin);
|
||||
measuredError = fabs (measuredDelay-delay);
|
||||
printf ("measured delay for %lf sec was off by %lf sec (%lf %%)\n",
|
||||
printf ("measured delay for %lf sec was off by %lf sec (%lf %%)\n",
|
||||
delay, measuredError, 100.0*measuredError/delay);
|
||||
}
|
||||
|
||||
@@ -130,9 +130,9 @@ int main (int argc, char **argv)
|
||||
|
||||
status = fdmgr_delete (pfdm);
|
||||
verify (status==0);
|
||||
|
||||
|
||||
printf ( "Test Complete\n" );
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -120,11 +120,11 @@ static void check(const char *str, const char *macros, const char *expect)
|
||||
static const char *pairs[] = { "", "environ", NULL, NULL };
|
||||
char *got;
|
||||
int pass = 1;
|
||||
|
||||
|
||||
macCreateHandle(&handle, pairs);
|
||||
macParseDefns(NULL, macros, &defines);
|
||||
macInstallMacros(handle, defines);
|
||||
|
||||
|
||||
got = macDefExpand(str, handle);
|
||||
|
||||
if (expect && !got) {
|
||||
@@ -140,7 +140,7 @@ static void check(const char *str, const char *macros, const char *expect)
|
||||
pass = 0;
|
||||
}
|
||||
testOk(pass, "%s", str);
|
||||
|
||||
|
||||
macDeleteHandle(handle);
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ MAIN(macDefExpandTest)
|
||||
check("${FOO,BAR=x}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP");
|
||||
check("${BAZ=BLETCH,BAR}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP");
|
||||
check("${BAZ=BLETCH,BAR=x}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP");
|
||||
|
||||
|
||||
check("${${FOO}}", "BAR=GLEEP,BLETCH=BAR", "BAR");
|
||||
check("x${${FOO}}y", "BAR=GLEEP,BLETCH=BAR", "xBARy");
|
||||
check("${${FOO}=GRIBBLE}", "BAR=GLEEP,BLETCH=BAR", "BAR");
|
||||
@@ -247,7 +247,7 @@ MAIN(macDefExpandTest)
|
||||
check("${FOO=$(BAR),BAR=$(FOO)}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL);
|
||||
|
||||
macEnvScope();
|
||||
|
||||
|
||||
errlogFlush();
|
||||
eltc(1);
|
||||
return testDone();
|
||||
|
||||
@@ -70,8 +70,9 @@ void udpSockTest(void)
|
||||
multiCastLoop(s, 1);
|
||||
multiCastLoop(s, 0);
|
||||
|
||||
/* Defaults to 1, setting to 0 makes no sense */
|
||||
multiCastTTL(s, 2);
|
||||
multiCastTTL(s, 1);
|
||||
multiCastTTL(s, 0);
|
||||
|
||||
epicsSocketDestroy(s);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
typedef struct info {
|
||||
epicsEventId consumerEvent;
|
||||
epicsRingBytesId ring;
|
||||
epicsRingBytesId ring;
|
||||
}info;
|
||||
|
||||
static void check(epicsRingBytesId ring, int expectedFree,
|
||||
@@ -41,7 +41,7 @@ static void check(epicsRingBytesId ring, int expectedFree,
|
||||
int isEmpty = epicsRingBytesIsEmpty(ring);
|
||||
int isFull = epicsRingBytesIsFull(ring);
|
||||
int highWaterMark = epicsRingBytesHighWaterMark(ring);
|
||||
|
||||
|
||||
testOk(nFree == expectedFree, "Free: %d == %d", nFree, expectedFree);
|
||||
testOk(nUsed == expectedUsed, "Used: %d == %d", nUsed, expectedUsed);
|
||||
testOk(isEmpty == expectedEmpty, "Empty: %d == %d", isEmpty, expectedEmpty);
|
||||
@@ -49,7 +49,7 @@ static void check(epicsRingBytesId ring, int expectedFree,
|
||||
testOk(highWaterMark == expectedHighWaterMark, "HighWaterMark: %d == %d",
|
||||
highWaterMark, expectedHighWaterMark);
|
||||
}
|
||||
|
||||
|
||||
MAIN(ringBytesTest)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
Reference in New Issue
Block a user