Major reorganization:
Removed all Main.cpp files, use the macro in testMain.h instead and defaulted all argc/argv parameters. Converted all real test programs to use epicsUnitTest.h. Moved performance measurements from epicsThreadTest to epicsThreadPerform. Moved epicsOkToBlockTest tests into epicsThreadTest. On a host arch, make test inside the O.arch directory runs all tests.
This commit is contained in:
@@ -1,152 +1,153 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# Copyright (c) 2006 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
TOP=../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
INC += testMain.h
|
||||
|
||||
PROD_LIBS += Com
|
||||
|
||||
TESTPROD_HOST += epicsUnitTestTest
|
||||
epicsUnitTestTest_SRCS += epicsUnitTestTest.c
|
||||
PROD_HOST += epicsUnitTestTest
|
||||
# Not much point running this on vxWorks or RTEMS...
|
||||
TESTS += epicsUnitTestTest
|
||||
|
||||
TESTPROD_HOST += epicsCalcTest
|
||||
epicsCalcTest_SRCS += epicsCalcTest.cpp
|
||||
PROD_HOST += epicsCalcTest
|
||||
OBJS_IOC_vxWorks += epicsCalcTest
|
||||
testHarness_SRCS += epicsCalcTest.cpp
|
||||
TESTS += epicsCalcTest
|
||||
|
||||
TESTPROD_HOST += epicsAlgorithmTest
|
||||
epicsAlgorithmTest_SRCS += epicsAlgorithmTest.cpp
|
||||
PROD_HOST += epicsAlgorithmTest
|
||||
OBJS_IOC_vxWorks += epicsAlgorithmTest
|
||||
testHarness_SRCS += epicsAlgorithmTest.cpp
|
||||
TESTS += epicsAlgorithmTest
|
||||
|
||||
epicsMathTestHost_SRCS += epicsMathTestMain.cpp epicsMathTest.c
|
||||
PROD_HOST += epicsMathTestHost
|
||||
OBJS_IOC_vxWorks += epicsMathTest
|
||||
TESTS += epicsMathTestHost
|
||||
TESTPROD_HOST += epicsMathTest
|
||||
epicsMathTest_SRCS += epicsMathTest.c
|
||||
testHarness_SRCS += epicsMathTest.c
|
||||
TESTS += epicsMathTest
|
||||
|
||||
epicsStdioTestHost_SRCS += epicsStdioTestMain.cpp epicsStdioTest.c
|
||||
PROD_HOST += epicsStdioTestHost
|
||||
OBJS_IOC_vxWorks += epicsStdioTest
|
||||
TESTS += epicsStdioTestHost
|
||||
TESTPROD_HOST += epicsStdioTest
|
||||
epicsStdioTest_SRCS += epicsStdioTest.c
|
||||
testHarness_SRCS += epicsStdioTest.c
|
||||
TESTS += epicsStdioTest
|
||||
|
||||
epicsStringTestHost_SRCS += epicsStringTestMain.cpp epicsStringTest.c
|
||||
PROD_HOST += epicsStringTestHost
|
||||
OBJS_IOC_vxWorks += epicsStringTest
|
||||
TESTS += epicsStringTestHost
|
||||
TESTPROD_HOST += epicsStringTest
|
||||
epicsStringTest_SRCS += epicsStringTest.c
|
||||
testHarness_SRCS += epicsStringTest.c
|
||||
TESTS += epicsStringTest
|
||||
|
||||
epicsTimeTestHost_SRCS += epicsTimeTestMain.cpp epicsTimeTest.cpp
|
||||
PROD_HOST += epicsTimeTestHost
|
||||
OBJS_IOC_vxWorks += epicsTimeTest
|
||||
TESTS += epicsTimeTestHost
|
||||
TESTPROD_HOST += epicsTimeTest
|
||||
epicsTimeTest_SRCS += epicsTimeTest.cpp
|
||||
testHarness_SRCS += epicsTimeTest.cpp
|
||||
TESTS += epicsTimeTest
|
||||
|
||||
epicsThreadTestHost_SRCS += epicsThreadTestMain.cpp epicsThreadTest.cpp
|
||||
PROD_HOST += epicsThreadTestHost
|
||||
OBJS_IOC_vxWorks += epicsThreadTest
|
||||
TESTPROD_HOST += epicsThreadTest
|
||||
epicsThreadTest_SRCS += epicsThreadTest.cpp
|
||||
testHarness_SRCS += epicsThreadTest.cpp
|
||||
TESTS += epicsThreadTest
|
||||
|
||||
epicsThreadPriorityTestHost_SRCS += epicsThreadPriorityTestMain.cpp epicsThreadPriorityTest.cpp
|
||||
PROD_HOST += epicsThreadPriorityTestHost
|
||||
OBJS_IOC_vxWorks += epicsThreadPriorityTest
|
||||
TESTPROD_HOST += epicsThreadPriorityTest
|
||||
epicsThreadPriorityTest_SRCS += epicsThreadPriorityTest.cpp
|
||||
testHarness_SRCS += epicsThreadPriorityTest.cpp
|
||||
TESTS += epicsThreadPriorityTest
|
||||
|
||||
epicsThreadPrivateTestHost_SRCS += epicsThreadPrivateTestMain.cpp epicsThreadPrivateTest.cpp
|
||||
PROD_HOST += epicsThreadPrivateTestHost
|
||||
OBJS_IOC_vxWorks += epicsThreadPrivateTest
|
||||
TESTPROD_HOST += epicsThreadPrivateTest
|
||||
epicsThreadPrivateTest_SRCS += epicsThreadPrivateTest.cpp
|
||||
testHarness_SRCS += epicsThreadPrivateTest.cpp
|
||||
TESTS += epicsThreadPrivateTest
|
||||
|
||||
epicsMaxThreadsHost_SRCS += epicsMaxThreadsMain.cpp epicsMaxThreads.c
|
||||
PROD_HOST += epicsMaxThreadsHost
|
||||
OBJS_IOC_vxWorks += epicsMaxThreads
|
||||
TESTPROD_HOST += epicsExitTest
|
||||
epicsExitTest_SRCS += epicsExitTest.c
|
||||
testHarness_SRCS += epicsExitTest.c
|
||||
TESTS += epicsExitTest
|
||||
|
||||
epicsOkToBlockTestHost_SRCS += epicsOkToBlockTestMain.cpp epicsOkToBlockTest.cpp
|
||||
PROD_HOST += epicsOkToBlockTestHost
|
||||
OBJS_IOC_vxWorks += epicsOkToBlockTest
|
||||
TESTPROD_HOST += epicsTimerTest
|
||||
epicsTimerTest_SRCS += epicsTimerTest.cpp
|
||||
testHarness_SRCS += epicsTimerTest.cpp
|
||||
# Some of this is doing measurement, tests fail...
|
||||
TESTS += epicsTimerTest
|
||||
|
||||
epicsExitTestHost_SRCS += epicsExitTestMain.c epicsExitTest.c
|
||||
PROD_HOST += epicsExitTestHost
|
||||
OBJS_IOC_vxWorks += epicsExitTest
|
||||
TESTPROD_HOST += ringPointerTest
|
||||
ringPointerTest_SRCS += ringPointerTest.c
|
||||
testHarness_SRCS += ringPointerTest.c
|
||||
TESTS += ringPointerTest
|
||||
|
||||
TESTPROD_HOST += epicsEventTest
|
||||
epicsEventTest_SRCS += epicsEventTest.cpp
|
||||
testHarness_SRCS += epicsEventTest.cpp
|
||||
TESTS += epicsEventTest
|
||||
|
||||
TESTPROD_HOST += epicsMutexTest
|
||||
epicsMutexTest_SRCS += epicsMutexTest.cpp
|
||||
testHarness_SRCS += epicsMutexTest.cpp
|
||||
TESTS += epicsMutexTest
|
||||
|
||||
TESTPROD_HOST += epicsExceptionTest
|
||||
epicsExceptionTest_SRCS += epicsExceptionTest.cpp
|
||||
testHarness_SRCS += epicsExceptionTest.cpp
|
||||
TESTS += epicsExceptionTest
|
||||
|
||||
TESTPROD_HOST += epicsMessageQueueTest
|
||||
epicsMessageQueueTest_SRCS += epicsMessageQueueTest.cpp
|
||||
testHarness_SRCS += epicsMessageQueueTest.cpp
|
||||
TESTS += epicsMessageQueueTest
|
||||
|
||||
TESTPROD_HOST += macEnvExpandTest
|
||||
macEnvExpandTest_SRCS += macEnvExpandTest.c
|
||||
testHarness_SRCS += macEnvExpandTest.c
|
||||
TESTS += macEnvExpandTest
|
||||
|
||||
|
||||
epicsTimerTestHost_SRCS += epicsTimerTestMain.cpp epicsTimerTest.cpp
|
||||
PROD_HOST += epicsTimerTestHost
|
||||
OBJS_IOC_vxWorks += epicsTimerTest
|
||||
# The testHarness runs all the test programs in a known working order.
|
||||
testHarness_SRCS += epicsRunLibComTests.c
|
||||
|
||||
epicsTimerExampleHost_SRCS += epicsTimerExampleMain.cpp epicsTimerExample.cpp
|
||||
PROD_HOST += epicsTimerExampleHost
|
||||
OBJS_IOC_vxWorks += epicsTimerExample
|
||||
|
||||
ringPointerTestHost_SRCS += ringPointerTestMain.cpp ringPointerTest.c
|
||||
PROD_HOST += ringPointerTestHost
|
||||
OBJS_IOC_vxWorks += ringPointerTest
|
||||
|
||||
epicsEventTestHost_SRCS += epicsEventTestMain.cpp epicsEventTest.cpp
|
||||
PROD_HOST += epicsEventTestHost
|
||||
OBJS_IOC_vxWorks += epicsEventTest
|
||||
|
||||
epicsMutexTestHost_SRCS += epicsMutexTestMain.cpp epicsMutexTest.cpp
|
||||
PROD_HOST += epicsMutexTestHost
|
||||
OBJS_IOC_vxWorks += epicsMutexTest
|
||||
|
||||
epicsExceptionTestHost_SRCS += epicsExceptionTestMain.cpp epicsExceptionTest.cpp
|
||||
PROD_HOST += epicsExceptionTestHost
|
||||
OBJS_IOC_vxWorks += epicsExceptionTest
|
||||
TESTS += epicsExceptionTestHost
|
||||
|
||||
epicsMessageQueueTestHost_SRCS += epicsMessageQueueTestMain.cpp epicsMessageQueueTest.cpp
|
||||
PROD_HOST += epicsMessageQueueTestHost
|
||||
OBJS_IOC_vxWorks += epicsMessageQueueTest
|
||||
|
||||
macEnvExpandTestHost_SRCS += macEnvExpandTestMain.cpp macEnvExpandTest.c
|
||||
PROD_HOST += macEnvExpandTestHost
|
||||
OBJS_IOC_vxWorks += macEnvExpandTest
|
||||
TESTS += macEnvExpandTestHost
|
||||
|
||||
blockingSockTestHost_SRCS += blockingSockTestMain.cpp blockingSockTest.cpp
|
||||
PROD_HOST += blockingSockTestHost
|
||||
OBJS_IOC_vxWorks += blockingSockTest
|
||||
# needed when its an object library build
|
||||
blockingSockTestHost_SYS_LIBS_WIN32 = ws2_32 advapi32 user32
|
||||
blockingSockTestHost_SYS_LIBS_solaris = socket
|
||||
|
||||
|
||||
#buckTest_SRCS += buckTest.c
|
||||
#PROD_HOST += buckTest
|
||||
|
||||
#fdmgrTest_SRCS += fdmgrTest.c
|
||||
#PROD_HOST += fdmgrTest
|
||||
PROD_vxWorks = vxTestHarness
|
||||
vxTestHarness_SRCS += $(testHarness_SRCS)
|
||||
vxTestHarness_OBJS += $(INSTALL_BIN)/vxComLibrary
|
||||
|
||||
PROD_RTEMS += rtemsTestHarness
|
||||
rtemsTestHarness_SRCS += rtemsTestHarness.c
|
||||
rtemsTestHarness_SRCS += epicsRunLibComTests.c
|
||||
rtemsTestHarness_SRCS += blockingSockTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsAlgorithmTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsCalcTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsEventTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsExceptionTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsExitTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsMathTest.c
|
||||
rtemsTestHarness_SRCS += epicsMessageQueueTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsMutexTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsOkToBlockTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsStdioTest.c
|
||||
rtemsTestHarness_SRCS += epicsStringTest.c
|
||||
rtemsTestHarness_SRCS += epicsThreadPriorityTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsThreadPrivateTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsThreadTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsTimeTest.cpp
|
||||
rtemsTestHarness_SRCS += epicsTimerTest.cpp
|
||||
rtemsTestHarness_SRCS += macEnvExpandTest.c
|
||||
rtemsTestHarness_SRCS += ringPointerTest.c
|
||||
rtemsTestHarness_SRCS += $(testHarness_SRCS)
|
||||
|
||||
|
||||
TEST_SCRIPTS += $(TESTS:%=%.t)
|
||||
|
||||
|
||||
# The following are not test programs, they measure performance
|
||||
|
||||
TESTPROD_HOST += epicsThreadPerform
|
||||
epicsThreadPerform_SRCS += epicsThreadPerform.cpp
|
||||
testHarness_SRCS += epicsThreadPerform.cpp
|
||||
|
||||
TESTPROD_HOST += epicsMaxThreads
|
||||
epicsMaxThreads_SRCS += epicsMaxThreads.c
|
||||
testHarness_SRCS += epicsMaxThreads.c
|
||||
|
||||
TESTPROD_HOST += blockingSockTest
|
||||
blockingSockTest_SRCS += blockingSockTest.cpp
|
||||
testHarness_SRCS += blockingSockTest.cpp
|
||||
# needed when its an object library build
|
||||
blockingSockTest_SYS_LIBS_WIN32 = ws2_32 advapi32 user32
|
||||
blockingSockTest_SYS_LIBS_solaris = socket
|
||||
|
||||
TESTPROD_HOST += buckTest
|
||||
buckTest_SRCS += buckTest.c
|
||||
testHarness_SRCS += buckTest.c
|
||||
|
||||
#TESTPROD_HOST += fdmgrTest
|
||||
fdmgrTest_SRCS += fdmgrTest.c
|
||||
fdmgrTest_LIBS += ca
|
||||
# FIXME: program never exits.
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
test: $(TEST_SCRIPTS)
|
||||
@@ -157,7 +158,7 @@ test: $(TEST_SCRIPTS)
|
||||
@$(RM) $@
|
||||
@$(CP) $< $@
|
||||
|
||||
# Early versions of Test::Harness expect test programs in perl only.
|
||||
# Some versions of Test::Harness expect test programs in perl only.
|
||||
# Generate a 1-line test program to run the real test binary
|
||||
%.t: %$(EXE)
|
||||
@$(RM) $@
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@@ -7,6 +15,7 @@
|
||||
#include "osiWireFormat.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsSignal.h"
|
||||
#include "testMain.h"
|
||||
|
||||
union address {
|
||||
struct sockaddr_in ia;
|
||||
@@ -47,6 +56,7 @@ private:
|
||||
class server {
|
||||
public:
|
||||
server ( const address & );
|
||||
void start ();
|
||||
void daemon ();
|
||||
protected:
|
||||
SOCKET sock;
|
||||
@@ -164,7 +174,10 @@ server::server ( const address & addrIn ) :
|
||||
assert ( status == 0 );
|
||||
status = listen ( this->sock, 10 );
|
||||
assert ( status == 0 );
|
||||
}
|
||||
|
||||
void server::start ()
|
||||
{
|
||||
this->id = epicsThreadCreate (
|
||||
"server daemon", epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
@@ -181,7 +194,8 @@ void server::daemon ()
|
||||
SOCKET ns = accept ( this->sock,
|
||||
& addr.sa, & addressSize );
|
||||
assert ( ns != INVALID_SOCKET );
|
||||
new serverCircuit ( ns );
|
||||
circuit * pCir = new serverCircuit ( ns );
|
||||
assert ( pCir );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +215,7 @@ const char * serverCircuit::pName ()
|
||||
return "server circuit";
|
||||
}
|
||||
|
||||
extern "C" void blockingSockTest (void)
|
||||
MAIN(blockingSockTest)
|
||||
{
|
||||
address addr;
|
||||
memset ( (char *) & addr, 0, sizeof ( addr ) );
|
||||
@@ -210,6 +224,7 @@ extern "C" void blockingSockTest (void)
|
||||
addr.ia.sin_port = epicsHTON16 ( 5064 ); // CA
|
||||
|
||||
server srv ( addr );
|
||||
srv.start ();
|
||||
clientCircuit client ( addr );
|
||||
|
||||
epicsThreadSleep ( 1.0 );
|
||||
@@ -254,5 +269,6 @@ extern "C" void blockingSockTest (void)
|
||||
}
|
||||
printf ( "The epicsSocketSystemCallInterruptMechanismQuery() function returns\n\"%s\".\n",
|
||||
pStr );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
extern "C" void blockingSockTest (void);
|
||||
|
||||
int main ()
|
||||
{
|
||||
blockingSockTest ();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <time.h>
|
||||
@@ -13,8 +12,9 @@
|
||||
|
||||
#include "epicsAssert.h"
|
||||
#include "bucketLib.h"
|
||||
#include "testMain.h"
|
||||
|
||||
int main()
|
||||
MAIN(buckTest)
|
||||
{
|
||||
unsigned id1;
|
||||
unsigned id2;
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
// epicsAlgorithmTest.cpp
|
||||
// Authors: Jeff Hill & Andrew Johnson
|
||||
|
||||
#include "epicsUnitTest.h"
|
||||
#include "epicsAlgorithm.h"
|
||||
#include "testMain.h"
|
||||
|
||||
#if defined(vxWorks) || defined(__rtems__)
|
||||
#define MAIN(prog) extern "C" int prog
|
||||
#else
|
||||
#define MAIN(prog) int main
|
||||
#endif
|
||||
|
||||
MAIN(epicsAlgorithm) (int /*argc*/, char* /*argv[]*/)
|
||||
MAIN(epicsAlgorithm)
|
||||
{
|
||||
testPlan(22);
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
// $Id$
|
||||
// Author: Andrew Johnson
|
||||
@@ -14,13 +11,7 @@
|
||||
#include "epicsMath.h"
|
||||
#include "epicsAlgorithm.h"
|
||||
#include "postfix.h"
|
||||
|
||||
#if defined(vxWorks) || defined(__rtems__)
|
||||
#define MAIN(prog) extern "C" int prog
|
||||
#else
|
||||
#define MAIN(prog) int main
|
||||
#endif
|
||||
|
||||
#include "testMain.h"
|
||||
|
||||
/* Infrastructure for running tests */
|
||||
|
||||
@@ -100,7 +91,7 @@ void testCalc(const char *expr, double expected) {
|
||||
#define XOR ^
|
||||
|
||||
|
||||
MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
MAIN(epicsCalcTest)
|
||||
{
|
||||
int repeat;
|
||||
const double a=1.0, b=2.0, c=3.0, d=4.0, e=5.0, f=6.0,
|
||||
@@ -110,7 +101,7 @@ MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
Inf /= NaN;
|
||||
NaN /= NaN;
|
||||
|
||||
testPlan(240);
|
||||
testPlan(392);
|
||||
|
||||
/* LITERAL_OPERAND elements */
|
||||
testExpr(0);
|
||||
@@ -193,13 +184,13 @@ MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
testExpr(MAX(1,2));
|
||||
testExpr(MAX(1.,Inf));
|
||||
testExpr(MAX(1.,-Inf));
|
||||
testCalc("MAX(1,NaN)", NaN);
|
||||
testCalc("MAX(NaN,1)", NaN);
|
||||
testExpr(MAX(1.,NaN));
|
||||
testExpr(MAX(NaN,1.));
|
||||
testExpr(MIN(1,2));
|
||||
testExpr(MIN(1.,Inf));
|
||||
testExpr(MIN(1.,-Inf));
|
||||
testCalc("MIN(1,NaN)", NaN);
|
||||
testCalc("MIN(NaN,1)", NaN);
|
||||
testExpr(MIN(1.,NaN));
|
||||
testExpr(MIN(NaN,1.));
|
||||
testExpr(NINT(0.6));
|
||||
testExpr(NINT(-0.6));
|
||||
testExpr(sin(0.5));
|
||||
@@ -216,6 +207,21 @@ MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
testExpr(0 != 0);
|
||||
testExpr(1 != 0);
|
||||
testExpr(1 != 0 != 2);
|
||||
testExpr(0.0 != Inf);
|
||||
testExpr(0.0 != -Inf);
|
||||
testExpr(0.0 != NaN);
|
||||
testExpr(Inf != 0.0);
|
||||
testExpr(Inf != Inf);
|
||||
testExpr(Inf != -Inf);
|
||||
testExpr(Inf != NaN);
|
||||
testExpr(-Inf != 0.0);
|
||||
testExpr(-Inf != Inf);
|
||||
testExpr(-Inf != -Inf);
|
||||
testExpr(-Inf != NaN);
|
||||
testExpr(NaN != 0.0);
|
||||
testExpr(NaN != Inf);
|
||||
testExpr(NaN != -Inf);
|
||||
testExpr(NaN != NaN);
|
||||
|
||||
testCalc("0 # 1", 0 != 1);
|
||||
testCalc("0 # 0", 0 != 0);
|
||||
@@ -234,6 +240,21 @@ MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
testExpr(1 && 1);
|
||||
|
||||
testExpr(2 * 2);
|
||||
testExpr(0.0 * Inf);
|
||||
testExpr(0.0 * -Inf);
|
||||
testExpr(0.0 * NaN);
|
||||
testExpr(Inf * 0.0);
|
||||
testExpr(Inf * Inf);
|
||||
testExpr(Inf * -Inf);
|
||||
testExpr(Inf * NaN);
|
||||
testExpr(-Inf * 0.0);
|
||||
testExpr(-Inf * Inf);
|
||||
testExpr(-Inf * -Inf);
|
||||
testExpr(-Inf * NaN);
|
||||
testExpr(NaN * 0.0);
|
||||
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));
|
||||
@@ -242,17 +263,77 @@ MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
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);
|
||||
testExpr(Inf + -Inf);
|
||||
testExpr(Inf + NaN);
|
||||
testExpr(-Inf + 0.0);
|
||||
testExpr(-Inf + Inf);
|
||||
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);
|
||||
testExpr(0.0 - -Inf);
|
||||
testExpr(0.0 - NaN);
|
||||
testExpr(Inf - 0.0);
|
||||
testExpr(Inf - Inf);
|
||||
testExpr(Inf - -Inf);
|
||||
testExpr(Inf - NaN);
|
||||
testExpr(-Inf - 0.0);
|
||||
testExpr(-Inf - Inf);
|
||||
testExpr(-Inf - -Inf);
|
||||
testExpr(-Inf - NaN);
|
||||
testExpr(NaN - 0.0);
|
||||
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);
|
||||
testExpr(0.0 / -Inf);
|
||||
testExpr(0.0 / NaN);
|
||||
testExpr(Inf / 1.0);
|
||||
testExpr(Inf / Inf);
|
||||
testExpr(Inf / -Inf);
|
||||
testExpr(Inf / NaN);
|
||||
testExpr(-Inf / 1.0);
|
||||
testExpr(-Inf / Inf);
|
||||
testExpr(-Inf / -Inf);
|
||||
testExpr(-Inf / NaN);
|
||||
testExpr(NaN / 1.0);
|
||||
testExpr(NaN / Inf);
|
||||
testExpr(NaN / -Inf);
|
||||
testExpr(NaN / NaN);
|
||||
|
||||
testExpr(0 < 1);
|
||||
testExpr(0 < 0);
|
||||
testExpr(1 < 0);
|
||||
testExpr(2 < 0 < 2)
|
||||
testExpr(0.0 < Inf);
|
||||
testExpr(0.0 < -Inf);
|
||||
testExpr(0.0 < NaN);
|
||||
testExpr(Inf < 0.0);
|
||||
testExpr(Inf < Inf);
|
||||
testExpr(Inf < -Inf);
|
||||
testExpr(Inf < NaN);
|
||||
testExpr(-Inf < 0.0);
|
||||
testExpr(-Inf < Inf);
|
||||
testExpr(-Inf < -Inf);
|
||||
testExpr(-Inf < NaN);
|
||||
testExpr(NaN < 0.0);
|
||||
testExpr(NaN < Inf);
|
||||
testExpr(NaN < -Inf);
|
||||
testExpr(NaN < NaN);
|
||||
|
||||
testExpr(1 << 2);
|
||||
testExpr(1 << 3 << 2)
|
||||
@@ -261,6 +342,21 @@ MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
testExpr(0 <= 0);
|
||||
testExpr(1 <= 0);
|
||||
testExpr(3 <= 2 <= 3)
|
||||
testExpr(0.0 <= Inf);
|
||||
testExpr(0.0 <= -Inf);
|
||||
testExpr(0.0 <= NaN);
|
||||
testExpr(Inf <= 0.0);
|
||||
testExpr(Inf <= Inf);
|
||||
testExpr(Inf <= -Inf);
|
||||
testExpr(Inf <= NaN);
|
||||
testExpr(-Inf <= 0.0);
|
||||
testExpr(-Inf <= Inf);
|
||||
testExpr(-Inf <= -Inf);
|
||||
testExpr(-Inf <= NaN);
|
||||
testExpr(NaN <= 0.0);
|
||||
testExpr(NaN <= Inf);
|
||||
testExpr(NaN <= -Inf);
|
||||
testExpr(NaN <= NaN);
|
||||
|
||||
testCalc("0 = 1", 0 == 1);
|
||||
testCalc("0 = 0", 0 == 0);
|
||||
@@ -271,16 +367,61 @@ MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
testExpr(0 == 0);
|
||||
testExpr(1 == 0);
|
||||
testExpr(2 == 2 == 1);
|
||||
testExpr(0.0 == Inf);
|
||||
testExpr(0.0 == -Inf);
|
||||
testExpr(0.0 == NaN);
|
||||
testExpr(Inf == 0.0);
|
||||
testExpr(Inf == Inf);
|
||||
testExpr(Inf == -Inf);
|
||||
testExpr(Inf == NaN);
|
||||
testExpr(-Inf == 0.0);
|
||||
testExpr(-Inf == Inf);
|
||||
testExpr(-Inf == -Inf);
|
||||
testExpr(-Inf == NaN);
|
||||
testExpr(NaN == 0.0);
|
||||
testExpr(NaN == Inf);
|
||||
testExpr(NaN == -Inf);
|
||||
testExpr(NaN == NaN);
|
||||
|
||||
testExpr(0 > 1);
|
||||
testExpr(0 > 0);
|
||||
testExpr(1 > 0);
|
||||
testExpr(2 > 0 > 2);
|
||||
testExpr(0.0 > Inf);
|
||||
testExpr(0.0 > -Inf);
|
||||
testExpr(0.0 > NaN);
|
||||
testExpr(Inf > 0.0);
|
||||
testExpr(Inf > Inf);
|
||||
testExpr(Inf > -Inf);
|
||||
testExpr(Inf > NaN);
|
||||
testExpr(-Inf > 0.0);
|
||||
testExpr(-Inf > Inf);
|
||||
testExpr(-Inf > -Inf);
|
||||
testExpr(-Inf > NaN);
|
||||
testExpr(NaN > 0.0);
|
||||
testExpr(NaN > Inf);
|
||||
testExpr(NaN > -Inf);
|
||||
testExpr(NaN > NaN);
|
||||
|
||||
testExpr(0 >= 1);
|
||||
testExpr(0 >= 0);
|
||||
testExpr(1 >= 0);
|
||||
testExpr(3 >= 2 >= 3);
|
||||
testExpr(0.0 >= Inf);
|
||||
testExpr(0.0 >= -Inf);
|
||||
testExpr(0.0 >= NaN);
|
||||
testExpr(Inf >= 0.0);
|
||||
testExpr(Inf >= Inf);
|
||||
testExpr(Inf >= -Inf);
|
||||
testExpr(Inf >= NaN);
|
||||
testExpr(-Inf >= 0.0);
|
||||
testExpr(-Inf >= Inf);
|
||||
testExpr(-Inf >= -Inf);
|
||||
testExpr(-Inf >= NaN);
|
||||
testExpr(NaN >= 0.0);
|
||||
testExpr(NaN >= Inf);
|
||||
testExpr(NaN >= -Inf);
|
||||
testExpr(NaN >= NaN);
|
||||
|
||||
testExpr(8 >> 1);
|
||||
testExpr(64 >> 2 >> 1);
|
||||
@@ -307,6 +448,8 @@ MAIN(epicsCalcTest) (int /*argc*/, char* /*argv[]*/)
|
||||
/* CONDITIONAL elements */
|
||||
testExpr(0 ? 1 : 2);
|
||||
testExpr(1 ? 1 : 2);
|
||||
testExpr(Inf ? 1 : 2);
|
||||
testExpr(NaN ? 1 : 2);
|
||||
testExpr(0 ? 0 ? 2 : 3 : 4);
|
||||
testExpr(0 ? 1 ? 2 : 3 : 4);
|
||||
testExpr(1 ? 0 ? 2 : 3 : 4);
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsEventTest.cpp */
|
||||
|
||||
@@ -27,6 +26,8 @@
|
||||
#include "epicsRingPointer.h"
|
||||
#include "epicsTime.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
|
||||
typedef struct info {
|
||||
@@ -34,84 +35,74 @@ typedef struct info {
|
||||
epicsMutexId lockRing;
|
||||
int quit;
|
||||
epicsRingPointerId ring;
|
||||
}info;
|
||||
|
||||
} info;
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void consumer(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
time_t tp;
|
||||
epicsThreadId idSelf = epicsThreadGetIdSelf();
|
||||
int errors = 0;
|
||||
|
||||
printf("consumer %p starting time %ld\n",idSelf,time(&tp));
|
||||
while(1) {
|
||||
epicsEventWaitStatus status;
|
||||
if(pinfo->quit) {
|
||||
printf("consumer %p returning time %ld\n",
|
||||
idSelf,time(&tp));
|
||||
return;
|
||||
testDiag("consumer: starting");
|
||||
while (!pinfo->quit) {
|
||||
epicsEventWaitStatus status = epicsEventWait(pinfo->event);
|
||||
if (status != epicsEventWaitOK) {
|
||||
testDiag("consumer: epicsEventWait returned %d", status);
|
||||
errors++;
|
||||
}
|
||||
status = epicsEventWait(pinfo->event);
|
||||
if(status!=epicsEventWaitOK) {
|
||||
printf("task %p epicsEventWait returned %d time %ld\n",
|
||||
idSelf,(int)status,time(&tp));
|
||||
}
|
||||
while(epicsRingPointerGetUsed(pinfo->ring)>=2) {
|
||||
while (epicsRingPointerGetUsed(pinfo->ring) >= 2) {
|
||||
epicsRingPointerId message[2];
|
||||
int i;
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
if(!(message[i]=epicsRingPointerPop(pinfo->ring)))
|
||||
printf("consumer error\n");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
message[i] = epicsRingPointerPop(pinfo->ring);
|
||||
if (message[i] == 0) {
|
||||
testDiag("consumer: epicsRingPointerPop returned 0");
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if(message[0]!=message[1]) {
|
||||
printf("consumer error message %p %p\n",message[0],message[1]);
|
||||
} else {
|
||||
printf("consumer message from %p\n",message[0]);
|
||||
if (message[0] != message[1]) {
|
||||
testDiag("consumer: message %p %p\n", message[0], message[1]);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
testOk(errors == 0, "consumer: errors = %d", errors);
|
||||
}
|
||||
|
||||
|
||||
static void producer(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
time_t tp;
|
||||
epicsThreadId idSelf = epicsThreadGetIdSelf();
|
||||
int ntimes=0;
|
||||
|
||||
printf("producer %p starting time %ld\n",idSelf,time(&tp));
|
||||
while(1) {
|
||||
epicsMutexLockStatus status;
|
||||
const char *name = epicsThreadGetNameSelf();
|
||||
epicsThreadId myId = epicsThreadGetIdSelf();
|
||||
int errors = 0;
|
||||
int ntimes = 0;
|
||||
|
||||
testDiag("%s: starting", name);
|
||||
while(!pinfo->quit) {
|
||||
++ntimes;
|
||||
if(pinfo->quit) {
|
||||
printf("producer %p returning time %ld\n",
|
||||
idSelf,time(&tp));
|
||||
return;
|
||||
epicsMutexLockStatus status = epicsMutexLock(pinfo->lockRing);
|
||||
if (status != epicsMutexLockOK) {
|
||||
testDiag("%s: epicsMutexLock returned %d", name, status);
|
||||
errors++;
|
||||
}
|
||||
status = epicsMutexLock(pinfo->lockRing);
|
||||
if(status!=epicsMutexLockOK) {
|
||||
printf("producer %p epicsMutexLock returned %d time %ld\n",
|
||||
idSelf,(int)status,time(&tp));
|
||||
}
|
||||
if(epicsRingPointerGetFree(pinfo->ring)>=2) {
|
||||
int i;
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
if(!epicsRingPointerPush(pinfo->ring,idSelf))
|
||||
printf("producer %p error\n",idSelf);
|
||||
if(i==0 && (ntimes%4==0)) epicsThreadSleep(.1);
|
||||
if (epicsRingPointerGetFree(pinfo->ring) >= 2) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (!epicsRingPointerPush(pinfo->ring, myId)) {
|
||||
testDiag("%s: epicsRingPointerPush fail", name);
|
||||
errors++;
|
||||
}
|
||||
if (i == 0 && (ntimes % 4 == 0))
|
||||
epicsThreadSleep(0.1);
|
||||
}
|
||||
printf("producer %p sending\n",idSelf);
|
||||
} else {
|
||||
printf("producer %p ring buffer is full\n",idSelf);
|
||||
testFail("%s: ring buffer full", name);
|
||||
errors++;
|
||||
}
|
||||
epicsMutexUnlock(pinfo->lockRing);
|
||||
epicsThreadSleep(1.0);
|
||||
epicsEventSignal(pinfo->event);
|
||||
}
|
||||
testOk(errors == 0, "%s: errors = %d", name, errors);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
@@ -123,7 +114,7 @@ static double eventWaitMeasureDelayError( const epicsEventId &id, const double &
|
||||
epicsTime end = epicsTime::getCurrent();
|
||||
double meas = end - beg;
|
||||
double error = fabs ( delay - meas );
|
||||
printf ( "epicsEventWaitWithTimeout ( %10f ) tmo delay err %10f sec\n",
|
||||
testDiag("epicsEventWaitWithTimeout(%.6f) delay error %.6f sec",
|
||||
delay, error );
|
||||
return error;
|
||||
}
|
||||
@@ -139,68 +130,66 @@ static void eventWaitTest()
|
||||
}
|
||||
errorSum += eventWaitMeasureDelayError ( event, 0.0 );
|
||||
epicsEventDestroy ( event );
|
||||
printf ( "Average error %f sec\n", errorSum / ( i + 1 ) );
|
||||
double meanError = errorSum / ( i + 1 );
|
||||
testOk(meanError < 0.05, "Average error %.6f sec", meanError);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void epicsEventTest(int nthreads,int verbose)
|
||||
|
||||
MAIN(epicsEventTest)
|
||||
{
|
||||
unsigned int stackSize;
|
||||
const int nthreads = 3;
|
||||
epicsThreadId *id;
|
||||
char **name;
|
||||
int i;
|
||||
info *pinfo;
|
||||
epicsEventId event;
|
||||
int status;
|
||||
time_t tp;
|
||||
int errVerboseSave = errVerbose;
|
||||
|
||||
eventWaitTest();
|
||||
testPlan(9);
|
||||
|
||||
errVerbose = verbose;
|
||||
event = epicsEventMustCreate(epicsEventEmpty);
|
||||
printf("calling epicsEventWaitWithTimeout(event,2.0) time %ld\n",time(&tp));
|
||||
status = epicsEventWaitWithTimeout(event,2.0);
|
||||
if(status!=epicsEventWaitTimeout) printf("status %d\n",status);
|
||||
printf("calling epicsEventTryWait(event) time %ld\n",time(&tp));
|
||||
status = epicsEventTryWait(event);
|
||||
if(status!=epicsEventWaitTimeout) printf("status %d\n",status);
|
||||
printf("calling epicsEventSignal() time %ld\n",time(&tp));
|
||||
epicsEventSignal(event);
|
||||
printf("calling epicsEventWaitWithTimeout(event,2.0) time %ld\n",time(&tp));
|
||||
status = epicsEventWaitWithTimeout(event,2.0);
|
||||
if(status) printf("status %d\n",status);
|
||||
printf("calling epicsEventSignal() time %ld\n",time(&tp));
|
||||
epicsEventSignal(event);
|
||||
printf("calling epicsEventTryWait(event) time %ld\n",time(&tp));
|
||||
status = epicsEventTryWait(event);
|
||||
if(status) printf("status %d\n",status);
|
||||
|
||||
if(nthreads<=0) {
|
||||
errVerbose = errVerboseSave;
|
||||
return;
|
||||
}
|
||||
pinfo = (info *)calloc(1,sizeof(info));
|
||||
status = epicsEventWaitWithTimeout(event, 2.0);
|
||||
testOk(status == epicsEventWaitTimeout,
|
||||
"epicsEventWaitWithTimeout(event, 2.0) = %d", status);
|
||||
|
||||
status = epicsEventTryWait(event);
|
||||
testOk(status == epicsEventWaitTimeout,
|
||||
"epicsEventTryWait(event) = %d", status);
|
||||
|
||||
epicsEventSignal(event);
|
||||
status = epicsEventWaitWithTimeout(event,2.0);
|
||||
testOk(status == 0,
|
||||
"epicsEventWaitWithTimeout(event, 2.0) = %d", status);
|
||||
|
||||
epicsEventSignal(event);
|
||||
status = epicsEventTryWait(event);
|
||||
testOk(status == 0,
|
||||
"epicsEventTryWait(event) = %d", status);
|
||||
|
||||
info *pinfo = (info *)calloc(1,sizeof(info));
|
||||
pinfo->event = event;
|
||||
pinfo->lockRing = epicsMutexCreate();
|
||||
pinfo->ring = epicsRingPointerCreate(1024*2);
|
||||
stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
epicsThreadCreate("consumer",50,stackSize,consumer,pinfo);
|
||||
id = (epicsThreadId *)calloc(nthreads,sizeof(epicsThreadId));
|
||||
name = (char **)calloc(nthreads,sizeof(char *));
|
||||
for(i=0; i<nthreads; i++) {
|
||||
name[i] = (char *)calloc(10,sizeof(char));
|
||||
sprintf(name[i],"producer%d",i);
|
||||
id[i] = epicsThreadCreate(name[i],40,stackSize,producer,pinfo);
|
||||
printf("created producer %d id %p time %ld\n",
|
||||
i, id[i],time(&tp));
|
||||
unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
|
||||
epicsThreadCreate("consumer", 50, stackSize, consumer, pinfo);
|
||||
id = (epicsThreadId *)calloc(nthreads, sizeof(epicsThreadId));
|
||||
name = (char **)calloc(nthreads, sizeof(char *));
|
||||
for(int i = 0; i < nthreads; i++) {
|
||||
name[i] = (char *)calloc(10, sizeof(char));
|
||||
sprintf(name[i],"producer %d",i);
|
||||
id[i] = epicsThreadCreate(name[i], 40, stackSize, producer, pinfo);
|
||||
epicsThreadSleep(0.1);
|
||||
}
|
||||
epicsThreadSleep(5.0);
|
||||
printf("semTest setting quit time %ld\n",time(&tp));
|
||||
|
||||
testDiag("setting quit");
|
||||
pinfo->quit = 1;
|
||||
epicsThreadSleep(2.0);
|
||||
|
||||
epicsEventSignal(pinfo->event);
|
||||
epicsThreadSleep(1.0);
|
||||
printf("semTest returning time %ld\n",time(&tp));
|
||||
errVerbose = errVerboseSave;
|
||||
|
||||
eventWaitTest();
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsEventTestMain.cpp */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "epicsThread.h"
|
||||
extern "C" void epicsEventTest(int nthreads,int errVerbose);
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int nthreads = 2;
|
||||
int errVerboseIn = 0;
|
||||
|
||||
if(argc>1) {
|
||||
if(isdigit(*argv[1])) {
|
||||
sscanf(argv[1],"%d",&nthreads);
|
||||
printf("nthreads %d\n",nthreads);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
if(argc>2) {
|
||||
if(isdigit(*argv[2])) {
|
||||
sscanf(argv[2],"%d",&errVerboseIn);
|
||||
printf("errVerbose %d\n",errVerboseIn);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
epicsEventTest(nthreads,errVerboseIn);
|
||||
printf("main terminating\n");
|
||||
return(0);
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
//
|
||||
@@ -25,6 +24,7 @@
|
||||
|
||||
#include "epicsUnitTest.h"
|
||||
#include "epicsThread.h"
|
||||
#include "testMain.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -42,8 +42,8 @@ const nothrow_t nothrow ;
|
||||
static const size_t unsuccessfulNewSize = numeric_limits<size_t>::max()-100;
|
||||
# endif
|
||||
#elif defined(__GNUC__) && (__GNUC__<2 || (__GNUC__==2 && __GNUC_MINOR__<=96))
|
||||
// tornado does not supply ansi c++
|
||||
static const size_t unsuccessfulNewSize = UINT_MAX;
|
||||
// tornado does not supply ansi c++, and malloc(-15) succeeds...
|
||||
static const size_t unsuccessfulNewSize = UINT_MAX - 15u;
|
||||
#else
|
||||
static const size_t unsuccessfulNewSize = numeric_limits<size_t>::max();
|
||||
#endif
|
||||
@@ -61,11 +61,11 @@ private:
|
||||
static void epicsExceptionTestPrivate ()
|
||||
{
|
||||
try {
|
||||
new char [unsuccessfulNewSize];
|
||||
testFail("new: didn't throw at all");
|
||||
char * p = new char [unsuccessfulNewSize];
|
||||
testFail("new char[%u] returned %p", unsuccessfulNewSize, p);
|
||||
}
|
||||
catch ( const bad_alloc & ) {
|
||||
testPass("new");
|
||||
testPass("new char[%u] threw", unsuccessfulNewSize);
|
||||
}
|
||||
catch ( ... ) {
|
||||
testFail("new: threw wrong type");
|
||||
@@ -100,7 +100,7 @@ void exThread::waitForCompletion ()
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int epicsExceptionTest ()
|
||||
MAIN(epicsExceptionTest)
|
||||
{
|
||||
testPlan(4);
|
||||
epicsExceptionTestPrivate ();
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
extern "C" int epicsExceptionTest ();
|
||||
|
||||
int main ()
|
||||
{
|
||||
return epicsExceptionTest ();
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsExitTest.cpp */
|
||||
|
||||
@@ -22,9 +21,12 @@
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsExit.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
|
||||
typedef struct info {
|
||||
const char *name;
|
||||
epicsEventId terminate;
|
||||
epicsEventId terminated;
|
||||
}info;
|
||||
@@ -32,9 +34,11 @@ typedef struct info {
|
||||
static void atExit(void *pvt)
|
||||
{
|
||||
info *pinfo = (info *)pvt;
|
||||
testPass("%s reached atExit", pinfo->name);
|
||||
epicsEventSignal(pinfo->terminate);
|
||||
/*Now wait for thread to terminate*/
|
||||
epicsEventMustWait(pinfo->terminated);
|
||||
testPass("%s destroying pinfo", pinfo->name);
|
||||
epicsEventDestroy(pinfo->terminate);
|
||||
epicsEventDestroy(pinfo->terminated);
|
||||
free(pinfo);
|
||||
@@ -44,25 +48,39 @@ static void thread(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
|
||||
printf("thread %s starting\n", epicsThreadGetNameSelf());
|
||||
pinfo->name = epicsThreadGetNameSelf();
|
||||
testDiag("%s starting", pinfo->name);
|
||||
pinfo->terminate = epicsEventMustCreate(epicsEventEmpty);
|
||||
pinfo->terminated = epicsEventMustCreate(epicsEventEmpty);
|
||||
epicsAtExit(atExit,pinfo);
|
||||
printf("thread %s waiting for atExit\n", epicsThreadGetNameSelf());
|
||||
epicsAtExit(atExit, pinfo);
|
||||
testDiag("%s waiting for atExit", pinfo->name);
|
||||
epicsEventMustWait(pinfo->terminate);
|
||||
printf("thread %s terminating\n", epicsThreadGetNameSelf());
|
||||
testPass("%s terminating", pinfo->name);
|
||||
epicsEventSignal(pinfo->terminated);
|
||||
}
|
||||
void epicsExitTest(void)
|
||||
{
|
||||
unsigned int stackSize;
|
||||
info *pinfoA;
|
||||
info *pinfoB;
|
||||
|
||||
stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
pinfoA = (info *)calloc(1,sizeof(info));
|
||||
epicsThreadCreate("threadA",50,stackSize,thread,pinfoA);
|
||||
pinfoB = (info *)calloc(1,sizeof(info));
|
||||
epicsThreadCreate("threadB",50,stackSize,thread,pinfoB);
|
||||
epicsThreadSleep(1.0);
|
||||
static void mainExit(void *pvt)
|
||||
{
|
||||
testPass("Reached mainExit");
|
||||
testDone();
|
||||
}
|
||||
|
||||
MAIN(epicsExitTest)
|
||||
{
|
||||
unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
info *pinfoA = (info *)calloc(1, sizeof(info));
|
||||
info *pinfoB = (info *)calloc(1, sizeof(info));
|
||||
|
||||
testPlan(7);
|
||||
|
||||
epicsAtExit(mainExit, NULL);
|
||||
|
||||
epicsThreadCreate("threadA", 50, stackSize, thread, pinfoA);
|
||||
epicsThreadSleep(0.1);
|
||||
epicsThreadCreate("threadB", 50, stackSize, thread, pinfoB);
|
||||
epicsThreadSleep(1.0);
|
||||
|
||||
testDiag("Calling epicsExit\n");
|
||||
epicsExit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsExitTestMain.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 24AUG2004 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "epicsExit.h"
|
||||
#include "epicsThread.h"
|
||||
|
||||
void epicsExitTest(void);
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
epicsExitTest();
|
||||
epicsThreadSleep(1.0);
|
||||
printf("main calling epicsExit\n");
|
||||
epicsExit(0);
|
||||
return(0);
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsMathTest.c
|
||||
*
|
||||
@@ -14,8 +13,9 @@
|
||||
|
||||
#include "epicsUnitTest.h"
|
||||
#include "epicsMath.h"
|
||||
#include "testMain.h"
|
||||
|
||||
int epicsMathTest ()
|
||||
MAIN(epicsMathTest)
|
||||
{
|
||||
double a,b,c;
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsMathTestMain.cpp
|
||||
*
|
||||
* Author Marty Kraimer
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
int epicsMathTest ( void );
|
||||
}
|
||||
|
||||
int main ( int , char *[] )
|
||||
{
|
||||
epicsMathTest ();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsMaxThreads.cpp */
|
||||
|
||||
@@ -22,6 +21,7 @@
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsExit.h"
|
||||
#include "errlog.h"
|
||||
#include "testMain.h"
|
||||
|
||||
static epicsEventId started;
|
||||
|
||||
@@ -31,15 +31,15 @@ static void thread(void *arg)
|
||||
epicsThreadSuspendSelf();
|
||||
}
|
||||
|
||||
void epicsMaxThreads(void)
|
||||
MAIN(epicsMaxThreads)
|
||||
{
|
||||
unsigned int stackSize;
|
||||
epicsThreadId id;
|
||||
int i = 0;
|
||||
|
||||
stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
errlogPrintf("stackSize %d\n",stackSize);
|
||||
errlogFlush();
|
||||
printf("stackSize %d\n",stackSize);
|
||||
|
||||
started = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
while(1) {
|
||||
@@ -47,9 +47,10 @@ void epicsMaxThreads(void)
|
||||
if(!id) break;
|
||||
i++;
|
||||
if ((i % 100) == 0)
|
||||
printf ("%d\n", i);
|
||||
printf ("Reached %d...\n", i);
|
||||
epicsEventMustWait(started);
|
||||
}
|
||||
fprintf(stdout,"number threads %d\n",i);
|
||||
epicsExitCallAtExits();
|
||||
|
||||
printf("Max number of \"Small\" threads on this OS is %d\n", i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsMaxThreadsMain.cpp */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
extern "C" void epicsMaxThreads(void);
|
||||
|
||||
|
||||
int main(int /*argc*/, char * /*argv[]*/ )
|
||||
{
|
||||
epicsMaxThreads();
|
||||
printf("main terminating\n");
|
||||
return(0);
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* $Id$
|
||||
@@ -18,12 +17,17 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <epicsMessageQueue.h>
|
||||
#include <epicsThread.h>
|
||||
#include <epicsExit.h>
|
||||
#include <epicsAssert.h>
|
||||
|
||||
const char *msg1 = "1234567890This is a very long message.";
|
||||
#include "epicsMessageQueue.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsExit.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
static const char *msg1 = "1234567890This is a very long message.";
|
||||
static int testExit = 0;
|
||||
|
||||
/*
|
||||
* In Numerical Recipes in C: The Art of Scientific Computing (William H.
|
||||
@@ -47,11 +51,27 @@ badReceiver(void *arg)
|
||||
{
|
||||
epicsMessageQueue *q = (epicsMessageQueue *)arg;
|
||||
char cbuf[80];
|
||||
int len;
|
||||
|
||||
cbuf[0] = '\0';
|
||||
assert((q->receive(cbuf, 1) == -1) && (cbuf[0] == '\0'));
|
||||
epicsThreadSleep(5.0);
|
||||
assert((q->receive(cbuf, 1) == -1) && (cbuf[0] == '\0'));
|
||||
len = q->receive(cbuf, 1);
|
||||
if (len < 0 && cbuf[0] == '\0')
|
||||
testPass("receive into undersized buffer returned error (%d)", len);
|
||||
else if (len == 1 && cbuf[0] == *msg1)
|
||||
testPass("receive into undersized buffer truncated message");
|
||||
else
|
||||
testFail("receive into undersized buffer returned %d", len);
|
||||
|
||||
epicsThreadSleep(3.0);
|
||||
|
||||
cbuf[0] = '\0';
|
||||
len = q->receive(cbuf, 1);
|
||||
if (len < 0 && cbuf[0] == '\0')
|
||||
testPass("receive into undersized buffer returned error (%d)", len);
|
||||
else if (len == 1 && cbuf[0] == *msg1)
|
||||
testPass("receive into undersized buffer truncated message");
|
||||
else
|
||||
testFail("receive into undersized buffer returned %d", len);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
@@ -62,27 +82,29 @@ receiver(void *arg)
|
||||
int expectmsg[4];
|
||||
int len;
|
||||
int sender, msgNum;
|
||||
int errors = 0;
|
||||
|
||||
for (sender = 1 ; sender <= 4 ; sender++)
|
||||
expectmsg[sender-1] = 1;
|
||||
for (;;) {
|
||||
while (!testExit) {
|
||||
cbuf[0] = '\0';
|
||||
len = q->receive(cbuf, sizeof cbuf);
|
||||
if ((sscanf(cbuf, "Sender %d -- %d", &sender, &msgNum) == 2)
|
||||
&& (sender >= 1)
|
||||
&& (sender <= 4)) {
|
||||
if (expectmsg[sender-1] != msgNum)
|
||||
printf("%s received %d '%.*s' -- expected %d\n", epicsThreadGetNameSelf(), len, len, cbuf, expectmsg[sender-1]);
|
||||
if (expectmsg[sender-1] != msgNum) {
|
||||
++errors;
|
||||
testDiag("%s received %d '%.*s' -- expected %d", epicsThreadGetNameSelf(), len, len, cbuf, expectmsg[sender-1]);
|
||||
}
|
||||
expectmsg[sender-1] = msgNum + 1;
|
||||
epicsThreadSleep(0.001 * (randBelow(20)));
|
||||
}
|
||||
else {
|
||||
for (sender = 1 ; sender <= 4 ; sender++) {
|
||||
if (expectmsg[sender-1] > 1)
|
||||
printf("Sender %d -- %d messages\n", sender, expectmsg[sender-1]-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (sender = 1 ; sender <= 4 ; sender++) {
|
||||
if (expectmsg[sender-1] > 1)
|
||||
testDiag("Sender %d -- %d messages", sender, expectmsg[sender-1]-1);
|
||||
}
|
||||
testOk1(errors == 0);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
@@ -93,7 +115,7 @@ sender(void *arg)
|
||||
int len;
|
||||
int i = 0;
|
||||
|
||||
for (;;) {
|
||||
while (!testExit) {
|
||||
len = sprintf(cbuf, "%s -- %d.", epicsThreadGetNameSelf(), ++i);
|
||||
while (q->trySend((void *)cbuf, len) < 0)
|
||||
epicsThreadSleep(0.005 * (randBelow(5)));
|
||||
@@ -101,8 +123,9 @@ sender(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void epicsMessageQueueTest(void *parm)
|
||||
extern "C" void messageQueueTest(void *parm)
|
||||
{
|
||||
epicsEventId *pfinished = (epicsEventId *) parm;
|
||||
unsigned int i;
|
||||
char cbuf[80];
|
||||
int len;
|
||||
@@ -112,143 +135,141 @@ extern "C" void epicsMessageQueueTest(void *parm)
|
||||
|
||||
epicsMessageQueue *q1 = new epicsMessageQueue(4, 20);
|
||||
|
||||
printf ("Simple single-thread tests.\n");
|
||||
testDiag("Simple single-thread tests:");
|
||||
i = 0;
|
||||
used = 0;
|
||||
assert(q1->pending() == 0);
|
||||
testOk1(q1->pending() == 0);
|
||||
while (q1->trySend((void *)msg1, i ) == 0) {
|
||||
i++;
|
||||
assert(q1->pending() == i);
|
||||
printf("Should have %d pending -- ", ++used);
|
||||
q1->show();
|
||||
testOk(q1->pending() == i, "q1->pending() == %d", i);
|
||||
}
|
||||
assert(q1->pending() == 4);
|
||||
testOk1(q1->pending() == 4);
|
||||
|
||||
want = 0;
|
||||
len = q1->receive(cbuf, sizeof cbuf);
|
||||
assert(q1->pending() == 3);
|
||||
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
|
||||
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
|
||||
testOk1(q1->pending() == 3);
|
||||
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
|
||||
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
|
||||
|
||||
want++;
|
||||
len = q1->receive(cbuf, sizeof cbuf);
|
||||
assert(q1->pending() == 2);
|
||||
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
|
||||
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
|
||||
testOk1(q1->pending() == 2);
|
||||
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
|
||||
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
|
||||
q1->trySend((void *)msg1, i++);
|
||||
|
||||
want++;
|
||||
len = q1->receive(cbuf, sizeof cbuf);
|
||||
assert(q1->pending() == 2);
|
||||
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
|
||||
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
|
||||
testOk1(q1->pending() == 2);
|
||||
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
|
||||
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
|
||||
q1->trySend((void *)msg1, i++);
|
||||
assert(q1->pending() == 3);
|
||||
testOk1(q1->pending() == 3);
|
||||
|
||||
i = 3;
|
||||
while ((len = q1->receive(cbuf, sizeof cbuf, 1.0)) >= 0) {
|
||||
assert(q1->pending() == --i);
|
||||
--i;
|
||||
testOk(q1->pending() == i, "q1->pending() == %d", i);
|
||||
want++;
|
||||
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
|
||||
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
|
||||
if (!testOk1((len == want) & (strncmp(msg1, cbuf, len) == 0)))
|
||||
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
|
||||
}
|
||||
assert(q1->pending() == 0);
|
||||
testOk1(q1->pending() == 0);
|
||||
|
||||
printf ("Test sender timeout.\n");
|
||||
testDiag("Test sender timeout:");
|
||||
i = 0;
|
||||
used = 0;
|
||||
assert(q1->pending() == 0);
|
||||
testOk1(q1->pending() == 0);
|
||||
while (q1->send((void *)msg1, i, 1.0 ) == 0) {
|
||||
i++;
|
||||
assert(q1->pending() == i);
|
||||
printf("Should have %d pending -- ", ++used);
|
||||
q1->show();
|
||||
testOk(q1->pending() == i, "q1->pending() == %d", i);
|
||||
}
|
||||
assert(q1->pending() == 4);
|
||||
testOk1(q1->pending() == 4);
|
||||
|
||||
want = 0;
|
||||
len = q1->receive(cbuf, sizeof cbuf);
|
||||
assert(q1->pending() == 3);
|
||||
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
|
||||
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
|
||||
testOk1(q1->pending() == 3);
|
||||
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
|
||||
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
|
||||
|
||||
want++;
|
||||
len = q1->receive(cbuf, sizeof cbuf);
|
||||
assert(q1->pending() == 2);
|
||||
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
|
||||
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
|
||||
testOk1(q1->pending() == 2);
|
||||
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
|
||||
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
|
||||
q1->send((void *)msg1, i++, 1.0);
|
||||
|
||||
want++;
|
||||
len = q1->receive(cbuf, sizeof cbuf);
|
||||
assert(q1->pending() == 2);
|
||||
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
|
||||
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
|
||||
testOk1(q1->pending() == 2);
|
||||
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
|
||||
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
|
||||
q1->send((void *)msg1, i++, 1.0);
|
||||
assert(q1->pending() == 3);
|
||||
testOk1(q1->pending() == 3);
|
||||
|
||||
i = 3;
|
||||
while ((len = q1->receive(cbuf, sizeof cbuf, 1.0)) >= 0) {
|
||||
assert(q1->pending() == --i);
|
||||
--i;
|
||||
testOk(q1->pending() == i, "q1->pending() == %d", i);
|
||||
want++;
|
||||
if ((len != want) || (strncmp(msg1, cbuf, len) != 0))
|
||||
printf("wanted:%d '%.*s' got:%d '%.*s'\n", want, want, msg1, len, len, cbuf);
|
||||
if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0)))
|
||||
testDiag("wanted:%d '%.*s' got:%d '%.*s'", want, want, msg1, len, len, cbuf);
|
||||
}
|
||||
assert(q1->pending() == 0);
|
||||
testOk1(q1->pending() == 0);
|
||||
|
||||
printf ("Test receiver with timeout.\n");
|
||||
testDiag("Test receiver with timeout:");
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
assert (q1->send((void *)msg1, i, 1.0) == 0);
|
||||
assert(q1->pending() == 4);
|
||||
testOk1 (q1->send((void *)msg1, i, 1.0) == 0);
|
||||
testOk1(q1->pending() == 4);
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
assert (q1->receive((void *)cbuf, sizeof cbuf, 1.0) == (int)i);
|
||||
assert(q1->pending() == 0);
|
||||
assert (q1->receive((void *)cbuf, sizeof cbuf, 1.0) < 0);
|
||||
assert(q1->pending() == 0);
|
||||
testOk(q1->receive((void *)cbuf, sizeof cbuf, 1.0) == (int)i,
|
||||
"q1->receive(...) == %d", i);
|
||||
testOk1(q1->pending() == 0);
|
||||
testOk1(q1->receive((void *)cbuf, sizeof cbuf, 1.0) < 0);
|
||||
testOk1(q1->pending() == 0);
|
||||
|
||||
printf("Single receiver with invalid size, single sender tests.\n");
|
||||
testDiag("Single receiver with invalid size, single sender tests:");
|
||||
epicsThreadCreate("Bad Receiver", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), badReceiver, q1);
|
||||
epicsThreadSleep(5.0);
|
||||
assert (q1->send((void *)msg1, 10) == 0); /* Send with waiting receiver */
|
||||
epicsThreadSleep(1.0);
|
||||
testOk(q1->send((void *)msg1, 10) == 0, "Send with waiting receiver");
|
||||
epicsThreadSleep(2.0);
|
||||
testOk(q1->send((void *)msg1, 10) == 0, "Send with no receiver");
|
||||
epicsThreadSleep(2.0);
|
||||
assert (q1->send((void *)msg1, 10) == 0); /* Send with no receiver */
|
||||
epicsThreadSleep(10.0);
|
||||
|
||||
printf("Single receiver, single sender tests.\n");
|
||||
testDiag("Single receiver, single sender tests:");
|
||||
epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityHigh);
|
||||
epicsThreadCreate("Receiver one", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), receiver, q1);
|
||||
for (pass = 1 ; pass <= 3 ; pass++) {
|
||||
switch (pass) {
|
||||
case 1:
|
||||
printf ("Systems with priority-based scheduler should send only\n"
|
||||
"4 or 5 messages (sender priority > receiver priority).\n");
|
||||
break;
|
||||
case 2:
|
||||
printf ("Systems with strict priority-based scheduler should send\n"
|
||||
"10 messages (sender priority < receiver priority).\n");
|
||||
break;
|
||||
case 3:
|
||||
printf ("All systems should send 10 messages (sender pauses\n"
|
||||
"after sending each message).\n");
|
||||
break;
|
||||
}
|
||||
epicsThreadSleep(1.0);
|
||||
for (i = 0 ; i < 10 ; i++) {
|
||||
if (q1->trySend((void *)msg1, i) < 0)
|
||||
break;
|
||||
if (pass >= 3)
|
||||
epicsThreadSleep(0.5);
|
||||
}
|
||||
printf ("Sent %d messages.\n", i);
|
||||
epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityLow);
|
||||
switch (pass) {
|
||||
case 1:
|
||||
if (i<6)
|
||||
testDiag(" priority-based scheduler, sent %d messages", i);
|
||||
epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityLow);
|
||||
break;
|
||||
case 2:
|
||||
if (i<10)
|
||||
testDiag(" scheduler not strict priority, sent %d messages", i);
|
||||
else
|
||||
testDiag(" strict priority scheduler, sent 10 messages");
|
||||
break;
|
||||
case 3:
|
||||
testOk(i == 10, "%d of 10 messages sent with sender pauses", i);
|
||||
break;
|
||||
}
|
||||
epicsThreadSleep(1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Single receiver, multiple sender tests
|
||||
*/
|
||||
printf("Single receiver, multiple sender tests.\n");
|
||||
printf("The following test takes 5 minutes to run and has succeeded\nif nothing appears between here....\n");
|
||||
testDiag("Single receiver, multiple sender tests:");
|
||||
testDiag("This test takes 5 minutes...");
|
||||
epicsThreadCreate("Sender 1", epicsThreadPriorityLow, epicsThreadGetStackSize(epicsThreadStackMedium), sender, q1);
|
||||
epicsThreadCreate("Sender 2", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), sender, q1);
|
||||
epicsThreadCreate("Sender 3", epicsThreadPriorityHigh, epicsThreadGetStackSize(epicsThreadStackMedium), sender, q1);
|
||||
@@ -256,10 +277,22 @@ extern "C" void epicsMessageQueueTest(void *parm)
|
||||
|
||||
epicsThreadSleep(300.0);
|
||||
|
||||
/*
|
||||
* Force out summaries
|
||||
*/
|
||||
printf("......and here.\n");
|
||||
q1->trySend((void *)msg1, 0);
|
||||
testExit = 1;
|
||||
epicsThreadSleep(1.0);
|
||||
epicsEventSignal(*pfinished);
|
||||
}
|
||||
|
||||
MAIN(epicsMessageQueueTest)
|
||||
{
|
||||
testPlan(58);
|
||||
|
||||
epicsEventId finished = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
epicsThreadCreate("messageQueueTest", epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
messageQueueTest, (void *) &finished);
|
||||
|
||||
epicsEventWait(finished);
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Author W. Eric Norum
|
||||
* norume@aps.anl.gov
|
||||
* 630 252 4793
|
||||
*/
|
||||
|
||||
#include "epicsThread.h"
|
||||
|
||||
extern "C" void epicsMessageQueueTest ( void *);
|
||||
|
||||
int main ( int /* argc */, char /* *argv[] */ )
|
||||
{
|
||||
epicsThreadCreate("messageQueueTest",epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
epicsMessageQueueTest,0);
|
||||
epicsThreadExitMain();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsMutexTest.c */
|
||||
|
||||
@@ -27,6 +26,8 @@
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
typedef struct info {
|
||||
int threadnum;
|
||||
@@ -34,29 +35,21 @@ typedef struct info {
|
||||
int quit;
|
||||
}info;
|
||||
|
||||
extern "C" void mutexThread ( void * arg )
|
||||
extern "C" void mutexThread(void * arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
time_t tp;
|
||||
printf("mutexThread %d starting time %ld\n",pinfo->threadnum,time(&tp));
|
||||
while(1) {
|
||||
epicsMutexLockStatus status;
|
||||
if(pinfo->quit) {
|
||||
printf("mutexThread %d returning time %ld\n",
|
||||
pinfo->threadnum,time(&tp));
|
||||
return;
|
||||
}
|
||||
status = epicsMutexLock(pinfo->mutex);
|
||||
if(status!=epicsMutexLockOK) {
|
||||
printf("task %d epicsMutexLock returned %d time %ld\n",
|
||||
pinfo->threadnum,(int)status,time(&tp));
|
||||
}
|
||||
printf("mutexThread %d epicsMutexLock time %ld\n",
|
||||
pinfo->threadnum,time(&tp));
|
||||
testDiag("mutexThread %d starting", pinfo->threadnum);
|
||||
while (!pinfo->quit) {
|
||||
epicsMutexLockStatus status = epicsMutexLock(pinfo->mutex);
|
||||
testOk(status == epicsMutexLockOK,
|
||||
"mutexThread %d epicsMutexLock returned %d",
|
||||
pinfo->threadnum, (int)status);
|
||||
epicsThreadSleep(.1);
|
||||
epicsMutexUnlock(pinfo->mutex);
|
||||
epicsThreadSleep(.9);
|
||||
}
|
||||
testDiag("mutexThread %d exiting", pinfo->threadnum);
|
||||
return;
|
||||
}
|
||||
|
||||
inline void lockPair ( epicsMutex & mutex )
|
||||
@@ -183,7 +176,7 @@ void epicsMutexPerformance ()
|
||||
double delay = epicsTime::getCurrent () - begin;
|
||||
delay /= N * 100u; // convert to delay per lock pair
|
||||
delay *= 1e6; // convert to micro seconds
|
||||
printf ( "One lock pair completes in %f micro sec\n", delay );
|
||||
testDiag("lock()*1/unlock()*1 takes %f microseconds", delay);
|
||||
|
||||
// test a two times recursive lock pair
|
||||
begin = epicsTime::getCurrent ();
|
||||
@@ -193,7 +186,7 @@ void epicsMutexPerformance ()
|
||||
delay = epicsTime::getCurrent () - begin;
|
||||
delay /= N * 100u; // convert to delay per lock pair
|
||||
delay *= 1e6; // convert to micro seconds
|
||||
printf ( "One double recursive lock pair completes in %f micro sec\n", delay );
|
||||
testDiag("lock()*2/unlock()*2 takes %f microseconds", delay);
|
||||
|
||||
// test a four times recursive lock pair
|
||||
begin = epicsTime::getCurrent ();
|
||||
@@ -203,7 +196,7 @@ void epicsMutexPerformance ()
|
||||
delay = epicsTime::getCurrent () - begin;
|
||||
delay /= N * 100u; // convert to delay per lock pair
|
||||
delay *= 1e6; // convert to micro seconds
|
||||
printf ( "One quad recursive lock pair completes in %f micro sec\n", delay );
|
||||
testDiag("lock()*4/unlock()*4 takes %f microseconds", delay);
|
||||
}
|
||||
|
||||
struct verifyTryLock {
|
||||
@@ -215,23 +208,19 @@ extern "C" void verifyTryLockThread ( void *pArg )
|
||||
{
|
||||
struct verifyTryLock *pVerify =
|
||||
( struct verifyTryLock * ) pArg;
|
||||
epicsMutexLockStatus status;
|
||||
|
||||
status = epicsMutexTryLock ( pVerify->mutex );
|
||||
assert ( status == epicsMutexLockTimeout );
|
||||
testOk1(epicsMutexTryLock(pVerify->mutex) == epicsMutexLockTimeout);
|
||||
epicsEventSignal ( pVerify->done );
|
||||
}
|
||||
|
||||
void verifyTryLock ()
|
||||
{
|
||||
struct verifyTryLock verify;
|
||||
epicsMutexLockStatus status;
|
||||
|
||||
verify.mutex = epicsMutexMustCreate ();
|
||||
verify.done = epicsEventMustCreate ( epicsEventEmpty );
|
||||
|
||||
status = epicsMutexTryLock ( verify.mutex );
|
||||
assert ( status == epicsMutexLockOK );
|
||||
testOk1(epicsMutexTryLock(verify.mutex) == epicsMutexLockOK);
|
||||
|
||||
epicsThreadCreate ( "verifyTryLockThread", 40,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
@@ -244,8 +233,9 @@ void verifyTryLock ()
|
||||
epicsEventDestroy ( verify.done );
|
||||
}
|
||||
|
||||
extern "C" void epicsMutexTest(int nthreads,int verbose)
|
||||
MAIN(epicsMutexTest)
|
||||
{
|
||||
const int nthreads = 3;
|
||||
unsigned int stackSize;
|
||||
epicsThreadId *id;
|
||||
int i;
|
||||
@@ -254,31 +244,19 @@ extern "C" void epicsMutexTest(int nthreads,int verbose)
|
||||
info **pinfo;
|
||||
epicsMutexId mutex;
|
||||
int status;
|
||||
time_t tp;
|
||||
int errVerboseSave = errVerbose;
|
||||
|
||||
epicsMutexPerformance ();
|
||||
testPlan(19);
|
||||
|
||||
verifyTryLock ();
|
||||
|
||||
errVerbose = verbose;
|
||||
mutex = epicsMutexMustCreate();
|
||||
printf("calling epicsMutexLock(mutex) time %ld\n",time(&tp));
|
||||
status = epicsMutexLock(mutex);
|
||||
if(status) printf("status %d\n",status);
|
||||
printf("calling epicsMutexTryLock(mutex) time %ld\n",time(&tp));
|
||||
testOk(status == 0, "epicsMutexLock returned %d", status);
|
||||
status = epicsMutexTryLock(mutex);
|
||||
if(status) printf("status %d\n",status);
|
||||
epicsMutexShow(mutex,1);
|
||||
printf("calling epicsMutexUnlock() time %ld\n",time(&tp));
|
||||
testOk(status == 0, "epicsMutexTryLock returned %d", status);
|
||||
epicsMutexUnlock(mutex);
|
||||
printf("calling epicsMutexUnlock() time %ld\n",time(&tp));
|
||||
epicsMutexUnlock(mutex);
|
||||
epicsMutexShow(mutex,1);
|
||||
|
||||
if(nthreads<=0) {
|
||||
errVerbose = errVerboseSave;
|
||||
return;
|
||||
}
|
||||
id = (epicsThreadId *)calloc(nthreads,sizeof(epicsThreadId));
|
||||
name = (char **)calloc(nthreads,sizeof(char *));
|
||||
arg = (void **)calloc(nthreads,sizeof(void *));
|
||||
@@ -294,14 +272,14 @@ extern "C" void epicsMutexTest(int nthreads,int verbose)
|
||||
id[i] = epicsThreadCreate(name[i],40,stackSize,
|
||||
mutexThread,
|
||||
arg[i]);
|
||||
printf("semTest created mutexThread %d id %p time %ld\n",
|
||||
i, id[i],time(&tp));
|
||||
}
|
||||
epicsThreadSleep(5.0);
|
||||
printf("semTest setting quit time %ld\n",time(&tp));
|
||||
for(i=0; i<nthreads; i++) {
|
||||
pinfo[i]->quit = 1;
|
||||
}
|
||||
epicsThreadSleep(2.0);
|
||||
errVerbose = errVerboseSave;
|
||||
|
||||
epicsMutexPerformance ();
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsMutexTestMain.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "epicsThread.h"
|
||||
extern "C" void epicsMutexTest(int nthreads,int errVerbose);
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int nthreads = 2;
|
||||
int errVerboseIn = 0;
|
||||
|
||||
if(argc>1) {
|
||||
if(isdigit(*argv[1])) {
|
||||
sscanf(argv[1],"%d",&nthreads);
|
||||
printf("nthreads %d\n",nthreads);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
if(argc>2) {
|
||||
if(isdigit(*argv[2])) {
|
||||
sscanf(argv[2],"%d",&errVerboseIn);
|
||||
printf("errVerbose %d\n",errVerboseIn);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
epicsMutexTest(nthreads,errVerboseIn);
|
||||
printf("main terminating\n");
|
||||
return(0);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsOkToBlockTest.cpp */
|
||||
|
||||
/* Author: Marty Kraimer Date: 09JUL2004*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "epicsThread.h"
|
||||
|
||||
|
||||
typedef struct info {
|
||||
int isOkToBlock;
|
||||
}info;
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void thread(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
int isOkToBlock;
|
||||
|
||||
printf("thread %s isOkToBlock %d\n",
|
||||
epicsThreadGetNameSelf(),pinfo->isOkToBlock);
|
||||
epicsThreadSetOkToBlock(pinfo->isOkToBlock);
|
||||
epicsThreadSleep(1.0);
|
||||
isOkToBlock = epicsThreadIsOkToBlock();
|
||||
printf("thread %s epicsThreadIsOkToBlock %d\n",
|
||||
epicsThreadGetNameSelf(),isOkToBlock);
|
||||
epicsThreadSleep(.1);
|
||||
free(pinfo);
|
||||
}
|
||||
void epicsOkToBlockTest(void)
|
||||
{
|
||||
unsigned int stackSize;
|
||||
info *pinfoA;
|
||||
info *pinfoB;
|
||||
|
||||
stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
pinfoA = (info *)calloc(1,sizeof(info));
|
||||
pinfoA->isOkToBlock = 0;
|
||||
epicsThreadCreate("threadA",50,stackSize,thread,pinfoA);
|
||||
pinfoB = (info *)calloc(1,sizeof(info));
|
||||
pinfoB->isOkToBlock = 1;
|
||||
epicsThreadCreate("threadB",50,stackSize,thread,pinfoB);
|
||||
epicsThreadSleep(2.0);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsOkToBlockTestMain.cpp */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
extern "C" void epicsOkToBlockTest(void);
|
||||
|
||||
|
||||
int main(int /*argc*/, char * /*argv[]*/ )
|
||||
{
|
||||
epicsOkToBlockTest();
|
||||
printf("main terminating\n");
|
||||
return(0);
|
||||
}
|
||||
@@ -15,110 +15,105 @@
|
||||
#include <epicsThread.h>
|
||||
#include <epicsExit.h>
|
||||
|
||||
void threadTest(int ntasks,int verbose);
|
||||
void epicsTimerTest();
|
||||
int epicsAlgorithm(int /*argc*/, char* /*argv[]*/);
|
||||
int epicsCalcTest(int /*argc*/, char* /*argv[]*/);
|
||||
void epicsEventTest(int nthreads,int verbose);
|
||||
int epicsExceptionTest();
|
||||
int epicsMathTest();
|
||||
void epicsMessageQueueTest(void *parm);
|
||||
void epicsMutexTest(int nthreads,int verbose);
|
||||
void epicsOkToBlockTest(void);
|
||||
int epicsStdioTest (const char *report);
|
||||
int epicsStringTest();
|
||||
void epicsThreadPriorityTest(void *);
|
||||
void epicsThreadPrivateTest();
|
||||
int epicsThreadTest(void);
|
||||
int epicsTimerTest(void);
|
||||
int epicsAlgorithm(void);
|
||||
int epicsCalcTest(void);
|
||||
int epicsEventTest(void);
|
||||
int epicsExceptionTest(void);
|
||||
int epicsMathTest(void);
|
||||
int epicsMessageQueueTest(void);
|
||||
int epicsMutexTest(void);
|
||||
int epicsStdioTest(void);
|
||||
int epicsStringTest(void);
|
||||
int epicsThreadPriorityTest(void);
|
||||
int epicsThreadPrivateTest(void);
|
||||
int epicsTimeTest(void);
|
||||
int macEnvExpandTest(void);
|
||||
void ringPointerTest();
|
||||
void blockingSockTest (void);
|
||||
void epicsExitTest(void);
|
||||
int ringPointerTest(void);
|
||||
int blockingSockTest(void);
|
||||
int epicsExitTest(void);
|
||||
|
||||
void
|
||||
epicsRunLibComTests(void)
|
||||
{
|
||||
/*
|
||||
* Thread startup sets some internal variables so do it first
|
||||
*/
|
||||
/*
|
||||
* Thread startup sets some internal variables so do it first
|
||||
*/
|
||||
printf("\n****** Thread Test *****\n");
|
||||
threadTest (2, 0);
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
/*
|
||||
* Timer tests get confused if run after some of the other tests
|
||||
*/
|
||||
/*
|
||||
* Timer tests get confused if run after some of the other tests
|
||||
*/
|
||||
printf("\n****** Timer Test *****\n");
|
||||
epicsTimerTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Algorithm Test *****\n");
|
||||
epicsAlgorithm (0, NULL);
|
||||
epicsThreadSleep (1.0);
|
||||
epicsAlgorithm ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Calculation Test *****\n");
|
||||
epicsCalcTest(0, NULL);
|
||||
epicsThreadSleep (1.0);
|
||||
epicsCalcTest();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Event Test *****\n");
|
||||
epicsEventTest (2,0);
|
||||
epicsThreadSleep (1.0);
|
||||
epicsEventTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Exception Test *****\n");
|
||||
epicsExceptionTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
epicsExceptionTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Math Test *****\n");
|
||||
epicsMathTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Message Queue Test *****\n");
|
||||
epicsMessageQueueTest (NULL);
|
||||
epicsThreadSleep (1.0);
|
||||
epicsMessageQueueTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Mutex Test *****\n");
|
||||
epicsMutexTest (2, 0);
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** OK to Block Test *****\n");
|
||||
epicsOkToBlockTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
epicsMutexTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Stdio Test *****\n");
|
||||
epicsStdioTest ("report");
|
||||
epicsThreadSleep (1.0);
|
||||
epicsStdioTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** String Test *****\n");
|
||||
epicsStringTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Thread Priority Test *****\n");
|
||||
epicsThreadPriorityTest (NULL);
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadPriorityTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Thread Private Test *****\n");
|
||||
epicsThreadPrivateTest (NULL);
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadPrivateTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Time Test *****\n");
|
||||
epicsTimeTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Macro Environment Variable Expansion Test *****\n");
|
||||
macEnvExpandTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Ring Pointer Test *****\n");
|
||||
ringPointerTest ();
|
||||
epicsThreadSleep (1.0);
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
printf("\n****** Check socket behaviour *****\n");
|
||||
blockingSockTest();
|
||||
epicsThreadSleep (1.0);
|
||||
blockingSockTest();
|
||||
epicsThreadSleep (1.0);
|
||||
|
||||
/*
|
||||
* Must come last
|
||||
*/
|
||||
/*
|
||||
* Must come last
|
||||
*/
|
||||
printf("\n****** EpicsExit Test *****\n");
|
||||
epicsExitTest();
|
||||
epicsExitTest(); /* Never returns */
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsStdioTest.c
|
||||
*
|
||||
@@ -24,6 +23,8 @@
|
||||
#include "epicsStdio.h"
|
||||
#include "epicsStdioRedirect.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
|
||||
#define LINE_1 "# This is first line of sample report\n"
|
||||
#define LINE_2 "# This is second and last line of sample report\n"
|
||||
@@ -33,20 +34,21 @@ static void testEpicsSnprintf() {
|
||||
const float fvalue = 1.23e4;
|
||||
const char *svalue = "OneTwoThreeFour";
|
||||
const char *format = "int %d float %8.2e string %s";
|
||||
const char *result = "int 1234 float 1.23e+04 string OneTwoThreeFour";
|
||||
const char *expected = "int 1234 float 1.23e+04 string OneTwoThreeFour";
|
||||
char buffer[80];
|
||||
int size, rtn;
|
||||
int rlen = strlen(result)+1;
|
||||
int rlen = strlen(expected)+1;
|
||||
|
||||
strcpy(buffer, "AAAA");
|
||||
|
||||
for (size = 1; size < strlen(result) + 5; ++size) {
|
||||
for (size = 1; size < strlen(expected) + 5; ++size) {
|
||||
rtn = epicsSnprintf(buffer, size, format, ivalue, fvalue, svalue);
|
||||
testOk1(rtn == rlen-1);
|
||||
if (size) {
|
||||
testOk(strncmp(buffer, result, size-1) == 0, buffer);
|
||||
testOk(strlen(buffer) == (size < rlen ? size : rlen) -1, "length");
|
||||
}
|
||||
testOk(rtn == rlen-1, "epicsSnprintf(size=%d) = %d", size, rtn);
|
||||
testOk(strncmp(buffer, expected, size - 1) == 0,
|
||||
"buffer = '%s'", buffer);
|
||||
rtn = strlen(buffer);
|
||||
testOk(rtn == (size < rlen ? size : rlen) - 1,
|
||||
"length = %d", rtn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,67 +56,63 @@ void testStdoutRedir (const char *report)
|
||||
{
|
||||
FILE *realStdout = stdout;
|
||||
FILE *stream = 0;
|
||||
char linebuf[80];
|
||||
size_t buflen = sizeof linebuf;
|
||||
|
||||
testOk1(epicsGetStdout() == stdout);
|
||||
if(report && strlen(report)>0) {
|
||||
int fd;
|
||||
|
||||
errno = 0;
|
||||
fd = open(report, O_CREAT | O_WRONLY | O_TRUNC, 0644 );
|
||||
if(fd<0) {
|
||||
fprintf(stderr,"%s could not be created %s\n",
|
||||
report,strerror(errno));
|
||||
} else {
|
||||
stream = fdopen(fd,"w");
|
||||
if(!stream) {
|
||||
fprintf(stderr,"%s could not be opened for output %s\n",
|
||||
report,strerror(errno));
|
||||
} else {
|
||||
epicsSetThreadStdout(stream);
|
||||
testOk1(stdout == stream);
|
||||
}
|
||||
}
|
||||
errno = 0;
|
||||
if (!testOk1((stream = fopen(report, "w")) != NULL)) {
|
||||
testDiag("'%s' could not be opened for writing: %s",
|
||||
report, strerror(errno));
|
||||
testSkip(11, "Can't create stream file");
|
||||
return;
|
||||
}
|
||||
|
||||
epicsSetThreadStdout(stream);
|
||||
testOk1(stdout == stream);
|
||||
|
||||
printf(LINE_1);
|
||||
printf(LINE_2);
|
||||
errno = 0;
|
||||
if(stream) {
|
||||
epicsSetThreadStdout(0);
|
||||
if(fclose(stream)) {
|
||||
fprintf(stderr,"fclose failed %s\n",strerror(errno));
|
||||
}
|
||||
} else {
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
epicsSetThreadStdout(0);
|
||||
testOk1(epicsGetStdout() == realStdout);
|
||||
testOk1(stdout == realStdout);
|
||||
if ((stream = fopen(report, "r")) == NULL) {
|
||||
fprintf(stderr, "Can't reopen report file: %s\n", strerror(errno));
|
||||
|
||||
errno = 0;
|
||||
if (!testOk1(!fclose(stream)))
|
||||
testDiag("fclose error: %s\n", strerror(errno));
|
||||
|
||||
if (!testOk1((stream = fopen(report, "r")) != NULL)) {
|
||||
testDiag("'%s' could not be opened for reading: %s",
|
||||
report, strerror(errno));
|
||||
testSkip(6, "Can't reopen stream file.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
char linebuf[80];
|
||||
if (fgets(linebuf, sizeof linebuf, stream) == NULL) {
|
||||
fprintf(stderr, "Can't read first line of report file: %s\n", strerror(errno));
|
||||
}
|
||||
else if (!testOk(strcmp(linebuf, LINE_1) == 0, "First line")) { }
|
||||
else if (fgets(linebuf, sizeof linebuf, stream) == NULL) {
|
||||
fprintf(stderr, "Can't read second line of report file: %s\n", strerror(errno));
|
||||
}
|
||||
else if (!testOk(strcmp(linebuf, LINE_2) == 0, "Second line")) { }
|
||||
else if (fgets(linebuf, sizeof linebuf, stream) != NULL) {
|
||||
fprintf(stderr, "Read too much from report file.\n");
|
||||
}
|
||||
else {
|
||||
}
|
||||
if(fclose(stream)) {
|
||||
fprintf(stderr,"fclose failed %s\n",strerror(errno));
|
||||
}
|
||||
|
||||
if (!testOk1(fgets(linebuf, buflen, stream) != NULL)) {
|
||||
testDiag("File read error: %s", strerror(errno));
|
||||
testSkip(5, "Read failed.");
|
||||
fclose(stream);
|
||||
return;
|
||||
}
|
||||
testOk(strcmp(linebuf, LINE_1) == 0, "First line correct");
|
||||
|
||||
if (!testOk1(fgets(linebuf, buflen, stream) != NULL)) {
|
||||
testDiag("File read error: %s", strerror(errno));
|
||||
testSkip(1, "No line to compare.");
|
||||
} else
|
||||
testOk(strcmp(linebuf, LINE_2) == 0, "Second line");
|
||||
|
||||
testOk(!fgets(linebuf, buflen, stream), "File ends");
|
||||
|
||||
if (!testOk1(!fclose(stream)))
|
||||
testDiag("fclose error: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
int epicsStdioTest (const char *report)
|
||||
MAIN(epicsStdioTest)
|
||||
{
|
||||
testPlan(0);
|
||||
testPlan(163);
|
||||
testEpicsSnprintf();
|
||||
testStdoutRedir("report");
|
||||
return testDone();
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsStdioTestMain.cpp
|
||||
*
|
||||
* Author Marty Kraimer
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
int epicsStdioTest (const char *report);
|
||||
}
|
||||
|
||||
int main ( int argc, char *argv[] )
|
||||
{
|
||||
const char *report = "";
|
||||
if(argc>1) report = argv[1];
|
||||
|
||||
epicsStdioTest (report);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Id$
|
||||
*
|
||||
@@ -16,8 +15,9 @@
|
||||
|
||||
#include "epicsUnitTest.h"
|
||||
#include "epicsString.h"
|
||||
#include "testMain.h"
|
||||
|
||||
int epicsStringTest()
|
||||
MAIN(epicsStringTest)
|
||||
{
|
||||
testPlan(21);
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsStringTestMain.cpp
|
||||
*
|
||||
* Author Marty Kraimer
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
int epicsStringTest ( void );
|
||||
}
|
||||
|
||||
int main ( int , char *[] )
|
||||
{
|
||||
epicsStringTest ();
|
||||
return 0;
|
||||
}
|
||||
180
src/libCom/test/epicsThreadPerform.cpp
Normal file
180
src/libCom/test/epicsThreadPerform.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/* epicsThreadPerform.cpp */
|
||||
|
||||
/* sleep accuracy and sleep quantum tests by Jeff Hill */
|
||||
/* epicsThreadGetIdSelf performance by Jeff Hill */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "epicsThread.h"
|
||||
#include "epicsTime.h"
|
||||
#include "errlog.h"
|
||||
#include "testMain.h"
|
||||
|
||||
static void testPriority(const char *who)
|
||||
{
|
||||
epicsThreadId id;
|
||||
unsigned int oldPriority,newPriority;
|
||||
|
||||
id = epicsThreadGetIdSelf();
|
||||
oldPriority = epicsThreadGetPriority(id);
|
||||
epicsThreadSetPriority(id,epicsThreadPriorityMax);
|
||||
newPriority = epicsThreadGetPriority(id);
|
||||
epicsThreadSetPriority(id,oldPriority);
|
||||
printf("testPriority %s\n id %p old %u new %u\n",
|
||||
who,id,oldPriority,newPriority);
|
||||
}
|
||||
|
||||
extern "C" void testPriorityThread(void *arg)
|
||||
{
|
||||
testPriority("thread");
|
||||
}
|
||||
|
||||
static void epicsThreadPriorityTest()
|
||||
{
|
||||
testPriority("main error expected from epicsThreadSetPriority");
|
||||
epicsThreadCreate("testPriorityThread",epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),testPriorityThread,0);
|
||||
epicsThreadSleep(0.5);
|
||||
}
|
||||
|
||||
|
||||
static double threadSleepMeasureDelayError ( const double & delay )
|
||||
{
|
||||
epicsTime beg = epicsTime::getCurrent();
|
||||
epicsThreadSleep ( delay );
|
||||
epicsTime end = epicsTime::getCurrent();
|
||||
double meas = end - beg;
|
||||
double error = fabs ( delay - meas );
|
||||
return error;
|
||||
}
|
||||
|
||||
static double measureSleepQuantum (
|
||||
const unsigned iterations, const double testInterval )
|
||||
{
|
||||
double errorSum = 0.0;
|
||||
printf ( "Estimating sleep quantum" );
|
||||
fflush ( stdout );
|
||||
for ( unsigned i = 0u; i < iterations; i++ ) {
|
||||
// try to guarantee a uniform probability density function
|
||||
// by intentionally burning some CPU until we are less
|
||||
// likely to be aligned with the schedualing clock
|
||||
double interval = rand ();
|
||||
interval /= RAND_MAX;
|
||||
interval *= testInterval;
|
||||
epicsTime start = epicsTime::getCurrent ();
|
||||
epicsTime current = start;
|
||||
while ( current - start < interval ) {
|
||||
current = epicsTime::getCurrent ();
|
||||
}
|
||||
errorSum += threadSleepMeasureDelayError ( testInterval );
|
||||
if ( i % ( iterations / 10 ) == 0 ) {
|
||||
printf ( "." );
|
||||
fflush ( stdout );
|
||||
}
|
||||
}
|
||||
printf ( "done\n" );
|
||||
|
||||
// with a uniform probability density function the
|
||||
// sleep delay error mean is one half of the quantum
|
||||
double quantumEstimate = 2 * errorSum / iterations;
|
||||
return quantumEstimate;
|
||||
}
|
||||
|
||||
static void threadSleepQuantumTest ()
|
||||
{
|
||||
const double quantum = epicsThreadSleepQuantum ();
|
||||
|
||||
double quantumEstimate = measureSleepQuantum ( 10, 10 * quantum );
|
||||
quantumEstimate = measureSleepQuantum ( 100, 2 * quantumEstimate );
|
||||
|
||||
double quantumError = fabs ( quantumEstimate - quantum ) / quantum;
|
||||
const char * pTol = 0;
|
||||
if ( quantumError > 0.1 ) {
|
||||
pTol = "10%";
|
||||
}
|
||||
else if ( quantumError > 0.01 ) {
|
||||
pTol = "1%";
|
||||
}
|
||||
else if ( quantumError > 0.001 ) {
|
||||
pTol = "0.1%";
|
||||
}
|
||||
if ( pTol ) {
|
||||
printf (
|
||||
"The epicsThreadSleepQuantum() call returns %f sec.\n",
|
||||
quantum );
|
||||
printf (
|
||||
"This doesnt match the quantum estimate "
|
||||
"of %f sec within %s.\n",
|
||||
quantumEstimate, pTol );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void threadSleepTest ()
|
||||
{
|
||||
static const int iterations = 20;
|
||||
const double quantum = epicsThreadSleepQuantum ();
|
||||
double errorSum = threadSleepMeasureDelayError ( 0.0 );
|
||||
for ( int i = 0u; i < iterations; i++ ) {
|
||||
double delay = ldexp ( 1.0 , -i );
|
||||
double error =
|
||||
threadSleepMeasureDelayError ( delay );
|
||||
errorSum += error;
|
||||
if ( error > quantum + quantum / 8.0 ) {
|
||||
printf ( "epicsThreadSleep ( %10f ) delay err %10f sec\n",
|
||||
delay, error );
|
||||
}
|
||||
}
|
||||
double averageError = errorSum / ( iterations + 1 );
|
||||
if ( averageError > quantum ) {
|
||||
printf ( "Average sleep delay error was %f sec\n", averageError );
|
||||
}
|
||||
}
|
||||
|
||||
static void epicsThreadGetIdSelfPerfTest ()
|
||||
{
|
||||
static const unsigned N = 10000;
|
||||
static const double microSecPerSec = 1e6;
|
||||
epicsTime begin = epicsTime::getCurrent ();
|
||||
for ( unsigned i = 0u; i < N; i++ ) {
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
};
|
||||
epicsTime end = epicsTime::getCurrent ();
|
||||
printf ( "It takes %f micro sec to call epicsThreadGetIdSelf ()\n",
|
||||
microSecPerSec * ( end - begin ) / (10 * N) );
|
||||
}
|
||||
|
||||
|
||||
MAIN(epicsThreadPerform)
|
||||
{
|
||||
epicsThreadPriorityTest ();
|
||||
threadSleepQuantumTest ();
|
||||
threadSleepTest ();
|
||||
epicsThreadGetIdSelfPerfTest ();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsdThreadPriorityTest.cpp */
|
||||
|
||||
@@ -22,6 +21,8 @@
|
||||
#include "epicsThread.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsExit.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
|
||||
typedef struct info {
|
||||
@@ -37,65 +38,84 @@ static void client(void *arg)
|
||||
epicsThreadId idSelf = epicsThreadGetIdSelf();
|
||||
int pass;
|
||||
|
||||
for(pass = 0 ; pass < 3 ; pass++) {
|
||||
for (pass = 0 ; pass < 3 ; pass++) {
|
||||
epicsEventWaitStatus status;
|
||||
status = epicsEventWait(pinfo->waitForMaster);
|
||||
if(status!=epicsEventWaitOK) {
|
||||
printf("task %p epicsEventWait returned %d\n", idSelf,(int)status);
|
||||
}
|
||||
testOk(status == epicsEventWaitOK,
|
||||
"task %p epicsEventWait returned %d", idSelf, status);
|
||||
epicsThreadSleep(0.01);
|
||||
epicsEventSignal(pinfo->waitForClient);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void epicsThreadPriorityTest(void *)
|
||||
static void runThreadPriorityTest(void *arg)
|
||||
{
|
||||
unsigned int stackSize;
|
||||
info *pinfo;
|
||||
epicsThreadId clientId;
|
||||
epicsThreadId myId;
|
||||
epicsEventWaitStatus status;
|
||||
epicsEventId testComplete = (epicsEventId) arg;
|
||||
unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
|
||||
myId = epicsThreadGetIdSelf();
|
||||
epicsThreadSetPriority(myId,50);
|
||||
pinfo = (info *)calloc(1,sizeof(info));
|
||||
epicsThreadId myId = epicsThreadGetIdSelf();
|
||||
epicsThreadSetPriority(myId, 50);
|
||||
|
||||
info *pinfo = (info *)calloc(1, sizeof(info));
|
||||
pinfo->waitForMaster = epicsEventMustCreate(epicsEventEmpty);
|
||||
pinfo->waitForClient = epicsEventMustCreate(epicsEventEmpty);
|
||||
stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
clientId = epicsThreadCreate("client",50,stackSize,client,pinfo);
|
||||
|
||||
epicsThreadId clientId = epicsThreadCreate("client",
|
||||
50, stackSize, client, pinfo);
|
||||
epicsEventSignal(pinfo->waitForMaster);
|
||||
status = epicsEventWaitWithTimeout(pinfo->waitForClient,.1);
|
||||
if(status!=epicsEventWaitOK) {
|
||||
printf("epicsEventWaitWithTimeout failed. Why????\n");
|
||||
|
||||
epicsEventWaitStatus status;
|
||||
status = epicsEventWaitWithTimeout(pinfo->waitForClient, 0.1);
|
||||
if (!testOk(status == epicsEventWaitOK,
|
||||
"epicsEventWaitWithTimeout returned %d", status)) {
|
||||
testSkip(2, "epicsEventWaitWithTimeout failed");
|
||||
goto done;
|
||||
}
|
||||
epicsThreadSetPriority(clientId,20);
|
||||
|
||||
epicsThreadSetPriority(clientId, 20);
|
||||
/* expect that client will not be able to run */
|
||||
epicsEventSignal(pinfo->waitForMaster);
|
||||
|
||||
status = epicsEventTryWait(pinfo->waitForClient);
|
||||
if(status!=epicsEventWaitTimeout) {
|
||||
printf("epicsEventTryWait did not return epicsEventWaitTimeout\n");
|
||||
if (status != epicsEventWaitTimeout) {
|
||||
testFail("epicsEventTryWait returned %d", status);
|
||||
} else {
|
||||
status = epicsEventWaitWithTimeout(pinfo->waitForClient,.1);
|
||||
if(status!=epicsEventWaitOK) {
|
||||
printf("epicsEventWaitWithTimeout failed. Why????\n");
|
||||
status = epicsEventWaitWithTimeout(pinfo->waitForClient, 0.1);
|
||||
if (!testOk(status == epicsEventWaitOK,
|
||||
"epicsEventWaitWithTimeout returned %d", status)) {
|
||||
testSkip(1, "epicsEventWaitWithTimeout failed");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
epicsThreadSetPriority(clientId,80);
|
||||
epicsThreadSetPriority(clientId, 80);
|
||||
/* expect that client will be able to run */
|
||||
epicsEventSignal(pinfo->waitForMaster);
|
||||
status = epicsEventTryWait(pinfo->waitForClient);
|
||||
if(status==epicsEventWaitOK) {
|
||||
printf("Seems to support strict priority scheduling\n");
|
||||
if (status==epicsEventWaitOK) {
|
||||
testPass("Strict priority scheduler");
|
||||
} else {
|
||||
printf("Does not appear to support strict priority scheduling\n");
|
||||
testDiag("No strict priority scheduler");
|
||||
status = epicsEventWaitWithTimeout(pinfo->waitForClient,.1);
|
||||
if(status!=epicsEventWaitOK) {
|
||||
printf("epicsEventWaitWithTimeout failed. Why????\n");
|
||||
goto done;
|
||||
}
|
||||
testOk(status == epicsEventWaitOK,
|
||||
"epicsEventWaitWithTimeout returned %d", status);
|
||||
}
|
||||
done:
|
||||
epicsThreadSleep(1.0);
|
||||
epicsEventSignal(testComplete);
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
||||
|
||||
|
||||
MAIN(epicsThreadPriorityTest)
|
||||
{
|
||||
testPlan(7);
|
||||
epicsEventId testComplete = epicsEventMustCreate(epicsEventEmpty);
|
||||
epicsThreadMustCreate("threadPriorityTest", epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
runThreadPriorityTest, testComplete);
|
||||
epicsEventWaitStatus status = epicsEventWait(testComplete);
|
||||
testOk(status == epicsEventWaitOK,
|
||||
"epicsEventWait returned %d", status);
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Author Marty Kraimer
|
||||
*/
|
||||
|
||||
#include "epicsThread.h"
|
||||
|
||||
extern "C" void epicsThreadPriorityTest(void *arg);
|
||||
|
||||
int main ( int argc , char *argv[] )
|
||||
{
|
||||
epicsThreadMustCreate("threadPriorityTest",epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
epicsThreadPriorityTest,0);
|
||||
epicsThreadExitMain();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Id$ */
|
||||
|
||||
@@ -15,7 +14,8 @@
|
||||
|
||||
#include "epicsTime.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
static epicsThreadPrivate < bool > priv;
|
||||
|
||||
@@ -23,10 +23,10 @@ static bool doneFlag = false;
|
||||
|
||||
extern "C" void epicsThreadPrivateTestThread ( void * )
|
||||
{
|
||||
assert ( 0 == priv.get () );
|
||||
testOk1 ( 0 == priv.get () );
|
||||
static bool var;
|
||||
priv.set ( &var );
|
||||
assert ( &var == priv.get () );
|
||||
testOk1 ( &var == priv.get () );
|
||||
doneFlag = true;
|
||||
}
|
||||
|
||||
@@ -59,20 +59,24 @@ inline void callItTenTimesSquared ()
|
||||
callItTenTimes ();
|
||||
}
|
||||
|
||||
extern "C" void epicsThreadPrivateTest ()
|
||||
MAIN(epicsThreadPrivateTest)
|
||||
{
|
||||
testPlan(5);
|
||||
|
||||
static bool var;
|
||||
priv.set ( &var );
|
||||
assert ( &var == priv.get() );
|
||||
testOk1 ( &var == priv.get() );
|
||||
|
||||
epicsThreadCreate ( "epicsThreadPrivateTest", epicsThreadPriorityMax,
|
||||
epicsThreadGetStackSize ( epicsThreadStackSmall ),
|
||||
epicsThreadPrivateTestThread, 0 );
|
||||
while ( ! doneFlag ) {
|
||||
epicsThreadSleep ( 0.1 );
|
||||
}
|
||||
assert ( &var == priv.get() );
|
||||
testOk1 ( &var == priv.get() );
|
||||
|
||||
priv.set ( 0 );
|
||||
assert ( 0 == priv.get() );
|
||||
testOk1 ( 0 == priv.get() );
|
||||
|
||||
epicsTime begin = epicsTime::getCurrent ();
|
||||
static const unsigned N = 1000u;
|
||||
@@ -82,6 +86,8 @@ extern "C" void epicsThreadPrivateTest ()
|
||||
double delay = epicsTime::getCurrent() - begin;
|
||||
delay /= N * 100u; // convert to sec per call
|
||||
delay *= 1e6; // convert to micro sec
|
||||
printf ( "It takes %f micro sec to call epicsThreadPrivateGet()\n", delay );
|
||||
testDiag("epicsThreadPrivateGet() takes %f microseconds", delay);
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* Author: Jeff Hill Date: March 28 2001 */
|
||||
|
||||
extern "C" void epicsThreadPrivateTest ();
|
||||
|
||||
int main ()
|
||||
{
|
||||
epicsThreadPrivateTest ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsThreadTest.cpp */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
/* sleep accuracy and sleep quantum tests by Jeff Hill */
|
||||
/* epicsThreadGetIdSelf performance by Jeff Hill */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -25,33 +20,8 @@
|
||||
#include "epicsThread.h"
|
||||
#include "epicsTime.h"
|
||||
#include "errlog.h"
|
||||
|
||||
static void testPriority(const char *who)
|
||||
{
|
||||
epicsThreadId id;
|
||||
unsigned int oldPriority,newPriority;
|
||||
|
||||
id = epicsThreadGetIdSelf();
|
||||
oldPriority = epicsThreadGetPriority(id);
|
||||
epicsThreadSetPriority(id,epicsThreadPriorityMax);
|
||||
newPriority = epicsThreadGetPriority(id);
|
||||
epicsThreadSetPriority(id,oldPriority);
|
||||
printf("testPriority %s\n id %p old %u new %u\n",
|
||||
who,id,oldPriority,newPriority);
|
||||
}
|
||||
|
||||
extern "C" void testPriorityThread(void *arg)
|
||||
{
|
||||
testPriority("thread");
|
||||
}
|
||||
|
||||
static void epicsThreadPriorityTest()
|
||||
{
|
||||
testPriority("main error expected from epicsThreadSetPriority");
|
||||
epicsThreadCreate("testPriorityThread",epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),testPriorityThread,0);
|
||||
epicsThreadSleep(0.5);
|
||||
}
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
static epicsThreadPrivate<int> privateKey;
|
||||
|
||||
@@ -78,166 +48,64 @@ myThread::~myThread() {delete argvalue;}
|
||||
|
||||
void myThread::run()
|
||||
{
|
||||
int myPrivate = *argvalue;
|
||||
int *pset = argvalue;
|
||||
privateKey.set(argvalue);
|
||||
errlogPrintf("threadFunc %d starting argvalue %p\n",myPrivate,argvalue);
|
||||
epicsThreadSleep(2.0);
|
||||
argvalue = privateKey.get();
|
||||
errlogPrintf("threadFunc %d stopping argvalue %p\n",myPrivate,argvalue);
|
||||
int *pget = privateKey.get();
|
||||
testOk1(pget == pset);
|
||||
|
||||
epicsThreadId self = epicsThreadGetIdSelf();
|
||||
testOk1(thread.getPriority() == epicsThreadGetPriority(self));
|
||||
}
|
||||
|
||||
static double threadSleepMeasureDelayError ( const double & delay )
|
||||
|
||||
typedef struct info {
|
||||
int isOkToBlock;
|
||||
} info;
|
||||
|
||||
extern "C" {
|
||||
static void thread(void *arg)
|
||||
{
|
||||
epicsTime beg = epicsTime::getCurrent();
|
||||
epicsThreadSleep ( delay );
|
||||
epicsTime end = epicsTime::getCurrent();
|
||||
double meas = end - beg;
|
||||
double error = fabs ( delay - meas );
|
||||
return error;
|
||||
info *pinfo = (info *)arg;
|
||||
|
||||
epicsThreadSetOkToBlock(pinfo->isOkToBlock);
|
||||
epicsThreadSleep(1.0);
|
||||
|
||||
testOk(epicsThreadIsOkToBlock() == pinfo->isOkToBlock,
|
||||
"%s epicsThreadIsOkToBlock() = %d",
|
||||
epicsThreadGetNameSelf(), pinfo->isOkToBlock);
|
||||
epicsThreadSleep(0.1);
|
||||
}
|
||||
}
|
||||
|
||||
static double measureSleepQuantum (
|
||||
const unsigned iterations, const double testInterval )
|
||||
|
||||
MAIN(epicsThreadTest)
|
||||
{
|
||||
double errorSum = 0.0;
|
||||
printf ( "Estimating sleep quantum" );
|
||||
fflush ( stdout );
|
||||
for ( unsigned i = 0u; i < iterations; i++ ) {
|
||||
// try to guarantee a uniform probability density function
|
||||
// by intentionally burning some CPU until we are less
|
||||
// likely to be aligned with the schedualing clock
|
||||
double interval = rand ();
|
||||
interval /= RAND_MAX;
|
||||
interval *= testInterval;
|
||||
epicsTime start = epicsTime::getCurrent ();
|
||||
epicsTime current = start;
|
||||
while ( current - start < interval ) {
|
||||
current = epicsTime::getCurrent ();
|
||||
}
|
||||
errorSum += threadSleepMeasureDelayError ( testInterval );
|
||||
if ( i % ( iterations / 10 ) == 0 ) {
|
||||
printf ( "." );
|
||||
fflush ( stdout );
|
||||
}
|
||||
}
|
||||
printf ( "done\n" );
|
||||
testPlan(8);
|
||||
|
||||
// with a uniform probability density function the
|
||||
// sleep delay error mean is one half of the quantum
|
||||
double quantumEstimate = 2 * errorSum / iterations;
|
||||
return quantumEstimate;
|
||||
}
|
||||
|
||||
static void threadSleepQuantumTest ()
|
||||
{
|
||||
const double quantum = epicsThreadSleepQuantum ();
|
||||
|
||||
double quantumEstimate = measureSleepQuantum ( 10, 10 * quantum );
|
||||
quantumEstimate = measureSleepQuantum ( 100, 2 * quantumEstimate );
|
||||
|
||||
double quantumError = fabs ( quantumEstimate - quantum ) / quantum;
|
||||
const char * pTol = 0;
|
||||
if ( quantumError > 0.1 ) {
|
||||
pTol = "10%";
|
||||
}
|
||||
else if ( quantumError > 0.01 ) {
|
||||
pTol = "1%";
|
||||
}
|
||||
else if ( quantumError > 0.001 ) {
|
||||
pTol = "0.1%";
|
||||
}
|
||||
if ( pTol ) {
|
||||
printf (
|
||||
"The epicsThreadSleepQuantum() call returns %f sec.\n",
|
||||
quantum );
|
||||
printf (
|
||||
"This doesnt match the quantum estimate "
|
||||
"of %f sec within %s.\n",
|
||||
quantumEstimate, pTol );
|
||||
}
|
||||
}
|
||||
|
||||
static void threadSleepTest ()
|
||||
{
|
||||
static const int iterations = 20;
|
||||
const double quantum = epicsThreadSleepQuantum ();
|
||||
double errorSum = threadSleepMeasureDelayError ( 0.0 );
|
||||
for ( int i = 0u; i < iterations; i++ ) {
|
||||
double delay = ldexp ( 1.0 , -i );
|
||||
double error =
|
||||
threadSleepMeasureDelayError ( delay );
|
||||
errorSum += error;
|
||||
if ( error > quantum + quantum / 8.0 ) {
|
||||
printf ( "epicsThreadSleep ( %10f ) delay err %10f sec\n",
|
||||
delay, error );
|
||||
}
|
||||
}
|
||||
double averageError = errorSum / ( iterations + 1 );
|
||||
if ( averageError > quantum ) {
|
||||
printf ( "Average sleep delay error was %f sec\n", averageError );
|
||||
}
|
||||
}
|
||||
|
||||
static void epicsThreadGetIdSelfPerfTest ()
|
||||
{
|
||||
static const unsigned N = 10000;
|
||||
static const double microSecPerSec = 1e6;
|
||||
epicsTime begin = epicsTime::getCurrent ();
|
||||
for ( unsigned i = 0u; i < N; i++ ) {
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
epicsThreadGetIdSelf ();
|
||||
};
|
||||
epicsTime end = epicsTime::getCurrent ();
|
||||
printf ( "It takes %f micro sec to call epicsThreadGetIdSelf ()\n",
|
||||
microSecPerSec * ( end - begin ) / (10 * N) );
|
||||
}
|
||||
|
||||
extern "C" void threadTest(int ntasks,int verbose)
|
||||
{
|
||||
myThread **papmyThread;
|
||||
int i;
|
||||
char **name;
|
||||
int startPriority,minPriority,maxPriority;
|
||||
int errVerboseSave = errVerbose;
|
||||
|
||||
epicsThreadPriorityTest();
|
||||
epicsThreadGetIdSelfPerfTest ();
|
||||
|
||||
threadSleepTest();
|
||||
threadSleepQuantumTest();
|
||||
|
||||
errVerbose = verbose;
|
||||
errlogInit(4096);
|
||||
papmyThread = (myThread **)calloc(ntasks,sizeof(myThread *));
|
||||
name = (char **)calloc(ntasks,sizeof(char **));
|
||||
errlogPrintf("threadTest starting\n");
|
||||
for(i=0; i<ntasks; i++) {
|
||||
name[i] = (char *)calloc(10,sizeof(char));
|
||||
sprintf(name[i],"task%d",i);
|
||||
papmyThread[i] = new myThread(i,name[i]);
|
||||
errlogPrintf("threadTest created %d myThread %p\n",i,papmyThread[i]);
|
||||
startPriority = papmyThread[i]->thread.getPriority();
|
||||
papmyThread[i]->thread.setPriority(epicsThreadPriorityMin);
|
||||
minPriority = papmyThread[i]->thread.getPriority();
|
||||
papmyThread[i]->thread.setPriority(epicsThreadPriorityMax);
|
||||
maxPriority = papmyThread[i]->thread.getPriority();
|
||||
papmyThread[i]->thread.setPriority(50+i);
|
||||
if(i==0)errlogPrintf("startPriority %d minPriority %d maxPriority %d\n",
|
||||
startPriority,minPriority,maxPriority);
|
||||
}
|
||||
epicsThreadSleep(.1);
|
||||
epicsThreadShowAll(0);
|
||||
epicsThreadSleep(5.0);
|
||||
errlogPrintf("epicsThreadTest returning\n");
|
||||
epicsThreadSleep(.5);
|
||||
errVerbose = errVerboseSave;
|
||||
const int ntasks = 3;
|
||||
myThread *myThreads[ntasks];
|
||||
|
||||
int startPriority = 0;
|
||||
for (int i = 0; i < ntasks; i++) {
|
||||
char name[10];
|
||||
sprintf(name, "t%d", i);
|
||||
myThreads[i] = new myThread(i, name);
|
||||
if (i == 0)
|
||||
startPriority = myThreads[i]->thread.getPriority();
|
||||
myThreads[i]->thread.setPriority(startPriority + i);
|
||||
}
|
||||
epicsThreadSleep(3.0);
|
||||
|
||||
unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
|
||||
|
||||
info infoA = {0};
|
||||
epicsThreadCreate("threadA", 50, stackSize, thread, &infoA);
|
||||
|
||||
info infoB = {1};
|
||||
epicsThreadCreate("threadB", 50, stackSize, thread, &infoB);
|
||||
|
||||
epicsThreadSleep(2.0);
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* threadTestMain.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "epicsThread.h"
|
||||
extern "C" void threadTest(int nthreads,int errVerbose);
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int nthreads = 2;
|
||||
int errVerboseIn = 0;
|
||||
|
||||
if(argc>1) {
|
||||
if(isdigit(*argv[1])) {
|
||||
sscanf(argv[1],"%d",&nthreads);
|
||||
printf("nthreads %d\n",nthreads);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
if(argc>2) {
|
||||
if(isdigit(*argv[2])) {
|
||||
sscanf(argv[2],"%d",&errVerboseIn);
|
||||
printf("errVerbose %d\n",errVerboseIn);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
if(nthreads>0) threadTest(nthreads,errVerboseIn);
|
||||
printf("main terminating\n");
|
||||
return(0);
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Authors: Jeff HIll and Marty Kraimer
|
||||
@@ -20,6 +19,7 @@
|
||||
#include "epicsThread.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -39,8 +39,7 @@ static const unsigned uSecPerSec = 1000u * mSecPerSec;
|
||||
static const unsigned nSecPerSec = 1000u * uSecPerSec;
|
||||
|
||||
|
||||
extern "C"
|
||||
int epicsTimeTest (void)
|
||||
MAIN(epicsTimeTest)
|
||||
{
|
||||
const unsigned wasteTime = 100000u;
|
||||
const int nTimes = 10;
|
||||
@@ -66,8 +65,7 @@ int epicsTimeTest (void)
|
||||
epicsTime ts(badTS);
|
||||
char buf [32];
|
||||
ts.strftime(buf, sizeof(buf), pFormat);
|
||||
testFail("nanosecond overflow throws");
|
||||
testDiag("nanosecond overflow result is \"%s\"", buf);
|
||||
testFail("nanosecond overflow returned \"%s\"", buf);
|
||||
}
|
||||
catch ( ... ) {
|
||||
testPass("nanosecond overflow throws");
|
||||
@@ -75,31 +73,27 @@ int epicsTimeTest (void)
|
||||
}
|
||||
|
||||
{
|
||||
char buf[64];
|
||||
char buf[80];
|
||||
epicsTime et;
|
||||
|
||||
const char * pFormat = "%Y-%m-%d %H:%M:%S.%f";
|
||||
et.strftime(buf, sizeof(buf), pFormat);
|
||||
if (!testOk(strcmp(buf, "<undefined>") == 0, "undefined strftime"))
|
||||
testDiag("undefined.strftime(\"%s\") = \"%s\"", pFormat, buf);
|
||||
testOk(strcmp(buf, "<undefined>") == 0, "undefined => '%s'", buf);
|
||||
|
||||
// This is Noon GMT, when all timezones have the same date
|
||||
const epicsTimeStamp tTS = {12*60*60, 98765432};
|
||||
et = tTS;
|
||||
pFormat = "%Y-%m-%d %S.%09f"; // %H and %M change with timezone
|
||||
et.strftime(buf, sizeof(buf), pFormat);
|
||||
if (!testOk(strcmp(buf, "1990-01-01 00.098765432") == 0, pFormat))
|
||||
testDiag("t.strftime(\"%s\") = \"%s\"", pFormat, buf);
|
||||
testOk(strcmp(buf, "1990-01-01 00.098765432") == 0, "'%s' => '%s'", pFormat, buf);
|
||||
|
||||
pFormat = "%S.%04f";
|
||||
et.strftime(buf, sizeof(buf), pFormat);
|
||||
if (!testOk(strcmp(buf, "00.0988") == 0, pFormat))
|
||||
testDiag("t.strftime(\"%s\") = \"%s\"", pFormat, buf);
|
||||
testOk(strcmp(buf, "00.0988") == 0, "'%s' => '%s'", pFormat, buf);
|
||||
|
||||
pFormat = "%S.%05f";
|
||||
et.strftime(buf, sizeof(buf), pFormat);
|
||||
if (!testOk(strcmp(buf, "00.09877") == 0, pFormat))
|
||||
testDiag("t.strftime(\"%s\") = \"%s\"", pFormat, buf);
|
||||
testOk(strcmp(buf, "00.09877") == 0, "'%s' => '%s'", pFormat, buf);
|
||||
}
|
||||
|
||||
{ // invalidFormatTest
|
||||
@@ -108,8 +102,7 @@ int epicsTimeTest (void)
|
||||
memset(bigBuf, '\a', sizeof(bigBuf ));
|
||||
bigBuf[ sizeof(bigBuf) - 1] = '\0';
|
||||
begin.strftime(buf, sizeof(buf), bigBuf);
|
||||
if (!testOk(strcmp(buf, "<invalid format>") == 0, "strftime(huge)"))
|
||||
testDiag("strftime(huge) = \"%s\"", buf);
|
||||
testOk(strcmp(buf, "<invalid format>") == 0, "bad format => '%s'", buf);
|
||||
}
|
||||
|
||||
testDiag("Running %d loops", nTimes);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" int epicsTimeTest (void);
|
||||
|
||||
int main (int , char **)
|
||||
{
|
||||
return epicsTimeTest ();
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#include "epicsTimer.h"
|
||||
|
||||
class something : public epicsTimerNotify {
|
||||
public:
|
||||
something(const char* nm,epicsTimerQueueActive &queue)
|
||||
: name(nm), timer(queue.createTimer()) {}
|
||||
virtual ~something() { timer.destroy();}
|
||||
void start(double delay) {timer.start(*this,delay);}
|
||||
virtual expireStatus expire(const epicsTime & currentTime) {
|
||||
printf("%s\n",name);
|
||||
currentTime.show(1);
|
||||
return(noRestart);
|
||||
}
|
||||
private:
|
||||
const char* name;
|
||||
epicsTimer &timer;
|
||||
};
|
||||
|
||||
void epicsTimerExample()
|
||||
{
|
||||
epicsTimerQueueActive &queue = epicsTimerQueueActive::allocate(true);
|
||||
{
|
||||
something first("first",queue);
|
||||
something second("second",queue);
|
||||
|
||||
first.start(1.0);
|
||||
second.start(1.5);
|
||||
epicsThreadSleep(2.0);
|
||||
}
|
||||
queue.release();
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
void epicsTimerExample ( void );
|
||||
|
||||
int main ( int /* argc */, char /* *argv[] */ )
|
||||
{
|
||||
epicsTimerExample ();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* $Id$
|
||||
@@ -25,6 +24,9 @@
|
||||
#include "epicsGuard.h"
|
||||
#include "tsFreeList.h"
|
||||
#include "epicsSingleton.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
|
||||
static const double delayVerifyOffset = 1.0; // sec
|
||||
|
||||
@@ -66,19 +68,18 @@ inline void delayVerify::setBegin ( const epicsTime &beginIn )
|
||||
|
||||
inline double delayVerify::delay () const
|
||||
{
|
||||
return delayVerifyOffset + this->expectedDelay;
|
||||
return this->expectedDelay;
|
||||
}
|
||||
|
||||
double delayVerify::checkError () const
|
||||
{
|
||||
const double messageThresh = 0.5; // percent
|
||||
double actualDelay = this->expireStamp - this->beginStamp;
|
||||
double measuredError = actualDelay - delayVerifyOffset - this->expectedDelay;
|
||||
double percentError = fabs ( measuredError ) / this->expectedDelay;
|
||||
percentError *= 100.0;
|
||||
if ( percentError > messageThresh ) {
|
||||
printf ( "delay error > %g %%, delay = %g s, error = %g ms (%f %%)\n",
|
||||
messageThresh, this->expectedDelay, measuredError * 1000.0, percentError );
|
||||
double measuredError = actualDelay - this->expectedDelay;
|
||||
double percentError = 100.0 * fabs ( measuredError ) / this->expectedDelay;
|
||||
if ( ! testOk1 ( percentError < messageThresh ) ) {
|
||||
testDiag ( "delay = %f s, error = %f s (%.1f %%)",
|
||||
this->expectedDelay, measuredError, percentError );
|
||||
}
|
||||
return measuredError;
|
||||
}
|
||||
@@ -106,13 +107,16 @@ void testAccuracy ()
|
||||
delayVerify *pTimers[nTimers];
|
||||
unsigned i;
|
||||
|
||||
testDiag ( "Testing timer accuracy" );
|
||||
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMax );
|
||||
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i] = new delayVerify ( ( nTimers - i ) * 0.1, queue );
|
||||
pTimers[i] = new delayVerify ( i * 0.1 + delayVerifyOffset, queue );
|
||||
assert ( pTimers[i] );
|
||||
}
|
||||
|
||||
expireCount = nTimers;
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
epicsTime cur = epicsTime::getCurrent ();
|
||||
@@ -127,27 +131,29 @@ void testAccuracy ()
|
||||
averageMeasuredError += pTimers[i]->checkError ();
|
||||
}
|
||||
averageMeasuredError /= nTimers;
|
||||
printf ("average timer delay error %f ms\n",
|
||||
testDiag ("average timer delay error %f ms",
|
||||
averageMeasuredError * 1000 );
|
||||
queue.release ();
|
||||
}
|
||||
|
||||
|
||||
class cancelVerify : public epicsTimerNotify {
|
||||
public:
|
||||
cancelVerify ( epicsTimerQueue & );
|
||||
void start ( const epicsTime &expireTime );
|
||||
void cancel ();
|
||||
static unsigned cancellCount;
|
||||
static unsigned expireCount;
|
||||
protected:
|
||||
virtual ~cancelVerify ();
|
||||
private:
|
||||
epicsTimer &timer;
|
||||
bool failOutIfExpireIsCalled;
|
||||
expireStatus expire ( const epicsTime & );
|
||||
static epicsSingleton < tsFreeList < class cancelVerify, 0x20 > > pFreeList;
|
||||
};
|
||||
|
||||
cancelVerify::cancelVerify ( epicsTimerQueue &queueIn ) :
|
||||
timer ( queueIn.createTimer () ), failOutIfExpireIsCalled ( false )
|
||||
timer ( queueIn.createTimer () )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -164,21 +170,24 @@ inline void cancelVerify::start ( const epicsTime &expireTime )
|
||||
inline void cancelVerify::cancel ()
|
||||
{
|
||||
this->timer.cancel ();
|
||||
this->failOutIfExpireIsCalled = true;
|
||||
++cancelVerify::cancellCount;
|
||||
}
|
||||
|
||||
epicsTimerNotify::expireStatus cancelVerify::expire ( const epicsTime & )
|
||||
{
|
||||
++cancelVerify::expireCount;
|
||||
double root = 3.14159;
|
||||
for ( unsigned i = 0u; i < 1000; i++ ) {
|
||||
root = sqrt ( root );
|
||||
}
|
||||
assert ( ! this->failOutIfExpireIsCalled );
|
||||
return noRestart;
|
||||
}
|
||||
|
||||
unsigned cancelVerify::cancellCount = 0;
|
||||
unsigned cancelVerify::expireCount = 0;
|
||||
|
||||
//
|
||||
// verify that when cancel() is calle dthe timer never runs again
|
||||
// verify that expire() won't be called after the timer is cancelled
|
||||
//
|
||||
void testCancel ()
|
||||
{
|
||||
@@ -186,6 +195,8 @@ void testCancel ()
|
||||
cancelVerify *pTimers[nTimers];
|
||||
unsigned i;
|
||||
|
||||
testDiag ( "Testing timer cancellation" );
|
||||
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin );
|
||||
|
||||
@@ -193,22 +204,39 @@ void testCancel ()
|
||||
pTimers[i] = new cancelVerify ( queue );
|
||||
assert ( pTimers[i] );
|
||||
}
|
||||
epicsTime cur = epicsTime::getCurrent ();
|
||||
assert ( cancelVerify::expireCount == 0 );
|
||||
assert ( cancelVerify::cancellCount == 0 );
|
||||
|
||||
testDiag ( "starting %d timers", nTimers );
|
||||
epicsTime exp = epicsTime::getCurrent () + 4.0;
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i]->start ( cur + 4.0 );
|
||||
pTimers[i]->start ( exp );
|
||||
}
|
||||
epicsThreadSleep ( 5.0 );
|
||||
testOk1 ( cancelVerify::expireCount == 0 );
|
||||
testOk1 ( cancelVerify::cancellCount == 0 );
|
||||
|
||||
testDiag ( "cancelling timers" );
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i]->cancel ();
|
||||
}
|
||||
testOk1 ( cancelVerify::expireCount == 0 );
|
||||
testOk1 ( cancelVerify::cancellCount == nTimers );
|
||||
|
||||
testDiag ( "waiting until after timers should have expired" );
|
||||
epicsThreadSleep ( 5.0 );
|
||||
testOk1 ( cancelVerify::expireCount == 0 );
|
||||
testOk1 ( cancelVerify::cancellCount == nTimers );
|
||||
|
||||
epicsThreadSleep ( 1.0 );
|
||||
queue.release ();
|
||||
}
|
||||
|
||||
|
||||
class expireDestroVerify : public epicsTimerNotify {
|
||||
public:
|
||||
expireDestroVerify ( epicsTimerQueue & );
|
||||
void start ( const epicsTime &expireTime );
|
||||
static unsigned destroyCount;
|
||||
protected:
|
||||
virtual ~expireDestroVerify ();
|
||||
private:
|
||||
@@ -225,6 +253,7 @@ expireDestroVerify::expireDestroVerify ( epicsTimerQueue & queueIn ) :
|
||||
expireDestroVerify::~expireDestroVerify ()
|
||||
{
|
||||
this->timer.destroy ();
|
||||
++expireDestroVerify::destroyCount;
|
||||
}
|
||||
|
||||
inline void expireDestroVerify::start ( const epicsTime & expireTime )
|
||||
@@ -238,6 +267,8 @@ epicsTimerNotify::expireStatus expireDestroVerify::expire ( const epicsTime & )
|
||||
return noRestart;
|
||||
}
|
||||
|
||||
unsigned expireDestroVerify::destroyCount = 0;
|
||||
|
||||
//
|
||||
// verify that a timer can be destroyed in expire
|
||||
//
|
||||
@@ -247,6 +278,8 @@ void testExpireDestroy ()
|
||||
expireDestroVerify *pTimers[nTimers];
|
||||
unsigned i;
|
||||
|
||||
testDiag ( "Testing timer destruction in expire()" );
|
||||
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin );
|
||||
|
||||
@@ -254,11 +287,18 @@ void testExpireDestroy ()
|
||||
pTimers[i] = new expireDestroVerify ( queue );
|
||||
assert ( pTimers[i] );
|
||||
}
|
||||
assert ( expireDestroVerify::destroyCount == 0 );
|
||||
|
||||
testDiag ( "starting %d timers", nTimers );
|
||||
epicsTime cur = epicsTime::getCurrent ();
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i]->start ( cur );
|
||||
}
|
||||
|
||||
testDiag ( "waiting until all timers should have expired" );
|
||||
epicsThreadSleep ( 5.0 );
|
||||
|
||||
testOk1 ( expireDestroVerify::destroyCount == nTimers );
|
||||
queue.release ();
|
||||
}
|
||||
|
||||
@@ -268,20 +308,20 @@ public:
|
||||
periodicVerify ( epicsTimerQueue & );
|
||||
void start ( const epicsTime &expireTime );
|
||||
void cancel ();
|
||||
void verifyCount ();
|
||||
bool verifyCount ();
|
||||
protected:
|
||||
virtual ~periodicVerify ();
|
||||
private:
|
||||
epicsTimer &timer;
|
||||
unsigned nExpire;
|
||||
bool failOutIfExpireIsCalled;
|
||||
bool cancelCalled;
|
||||
expireStatus expire ( const epicsTime & );
|
||||
static epicsSingleton < tsFreeList < class periodicVerify, 0x20 > > pFreeList;
|
||||
};
|
||||
|
||||
periodicVerify::periodicVerify ( epicsTimerQueue & queueIn ) :
|
||||
timer ( queueIn.createTimer () ), nExpire ( 0u ),
|
||||
failOutIfExpireIsCalled ( false )
|
||||
cancelCalled ( false )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -298,12 +338,12 @@ inline void periodicVerify::start ( const epicsTime &expireTime )
|
||||
inline void periodicVerify::cancel ()
|
||||
{
|
||||
this->timer.cancel ();
|
||||
this->failOutIfExpireIsCalled = true;
|
||||
this->cancelCalled = true;
|
||||
}
|
||||
|
||||
inline void periodicVerify::verifyCount ()
|
||||
inline bool periodicVerify::verifyCount ()
|
||||
{
|
||||
assert ( this->nExpire > 1u );
|
||||
return ( this->nExpire > 1u );
|
||||
}
|
||||
|
||||
epicsTimerNotify::expireStatus periodicVerify::expire ( const epicsTime & )
|
||||
@@ -313,7 +353,7 @@ epicsTimerNotify::expireStatus periodicVerify::expire ( const epicsTime & )
|
||||
for ( unsigned i = 0u; i < 1000; i++ ) {
|
||||
root = sqrt ( root );
|
||||
}
|
||||
assert ( ! this->failOutIfExpireIsCalled );
|
||||
assert ( ! this->cancelCalled );
|
||||
double delay = rand ();
|
||||
delay = delay / RAND_MAX;
|
||||
delay /= 10.0;
|
||||
@@ -329,6 +369,8 @@ void testPeriodic ()
|
||||
periodicVerify *pTimers[nTimers];
|
||||
unsigned i;
|
||||
|
||||
testDiag ( "Testing periodic timers" );
|
||||
|
||||
epicsTimerQueueActive &queue =
|
||||
epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin );
|
||||
|
||||
@@ -336,24 +378,32 @@ void testPeriodic ()
|
||||
pTimers[i] = new periodicVerify ( queue );
|
||||
assert ( pTimers[i] );
|
||||
}
|
||||
|
||||
testDiag ( "starting %d timers", nTimers );
|
||||
epicsTime cur = epicsTime::getCurrent ();
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i]->start ( cur );
|
||||
}
|
||||
|
||||
testDiag ( "waiting until all timers should have expired" );
|
||||
epicsThreadSleep ( 5.0 );
|
||||
|
||||
bool notWorking = false;
|
||||
for ( i = 0u; i < nTimers; i++ ) {
|
||||
pTimers[i]->verifyCount ();
|
||||
notWorking |= ! pTimers[i]->verifyCount ();
|
||||
pTimers[i]->cancel ();
|
||||
}
|
||||
testOk( ! notWorking, "All timers expiring" );
|
||||
epicsThreadSleep ( 1.0 );
|
||||
queue.release ();
|
||||
}
|
||||
|
||||
extern "C" void epicsTimerTest ()
|
||||
MAIN(epicsTimerTest)
|
||||
{
|
||||
testExpireDestroy ();
|
||||
testPlan(33);
|
||||
testAccuracy ();
|
||||
testCancel ();
|
||||
testExpireDestroy ();
|
||||
testPeriodic ();
|
||||
printf ( "test complete\n" );
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*
|
||||
*/
|
||||
|
||||
extern "C" void epicsTimerTest ( void );
|
||||
|
||||
int main ( int /* argc */, char /* *argv[] */ )
|
||||
{
|
||||
epicsTimerTest ();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* $Id$
|
||||
@@ -20,6 +19,7 @@
|
||||
#include "envDefs.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
void check(const char *str, const char *expect)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ void check(const char *str, const char *expect)
|
||||
testOk(pass, str);
|
||||
}
|
||||
|
||||
int macEnvExpandTest(void)
|
||||
MAIN(macEnvExpandTest)
|
||||
{
|
||||
int warn = 0;
|
||||
testPlan(30);
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Id$
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
int macEnvExpandTest ( void );
|
||||
}
|
||||
|
||||
int main ( int , char *[] )
|
||||
{
|
||||
return macEnvExpandTest ();
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* ringPointerTest.c */
|
||||
|
||||
@@ -23,34 +22,37 @@
|
||||
#include "epicsRingPointer.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
#define ringSize 10
|
||||
|
||||
static int testExit = 0;
|
||||
|
||||
typedef struct info {
|
||||
epicsEventId consumerEvent;
|
||||
epicsRingPointerId ring;
|
||||
}info;
|
||||
|
||||
|
||||
static void consumer(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
static int expectedValue=0;
|
||||
int *newvalue;
|
||||
|
||||
printf("consumer starting\n");
|
||||
testDiag("Consumer starting");
|
||||
while(1) {
|
||||
epicsEventMustWait(pinfo->consumerEvent);
|
||||
if (testExit) return;
|
||||
while((newvalue = (int *)epicsRingPointerPop(pinfo->ring))) {
|
||||
if(expectedValue != *newvalue) {
|
||||
printf("consumer expected %d got %d\n",
|
||||
expectedValue,*newvalue);
|
||||
}
|
||||
testOk(expectedValue == *newvalue,
|
||||
"Consumer: %d == %d", expectedValue, *newvalue);
|
||||
expectedValue = *newvalue + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ringPointerTest()
|
||||
|
||||
MAIN(ringPointerTest)
|
||||
{
|
||||
int i;
|
||||
info *pinfo;
|
||||
@@ -59,38 +61,47 @@ void ringPointerTest()
|
||||
int *pgetValue;
|
||||
epicsRingPointerId ring;
|
||||
|
||||
for(i=0; i<ringSize*2; i++) value[i] = i;
|
||||
testPlan(54);
|
||||
|
||||
for (i=0; i<ringSize*2; i++) value[i] = i;
|
||||
pinfo = calloc(1,sizeof(info));
|
||||
pinfo->consumerEvent = consumerEvent = epicsEventMustCreate(epicsEventEmpty);
|
||||
if(!consumerEvent) {printf("epicsEventMustCreate failed\n");exit(1);}
|
||||
if (!consumerEvent) {
|
||||
testAbort("epicsEventMustCreate failed");
|
||||
}
|
||||
|
||||
pinfo->ring = ring = epicsRingPointerCreate(ringSize);
|
||||
if(!ring) {printf("epicsRingPointerCreate failed\n");exit(1);}
|
||||
epicsThreadCreate("consumer",50,epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
consumer,pinfo);
|
||||
if(!epicsRingPointerIsEmpty(ring)) printf("epicsRingPointerIsEmpty failed\n");
|
||||
printf("fill ring\n");
|
||||
i=0;
|
||||
while(1) {
|
||||
if(!epicsRingPointerPush(ring,(void *)&value[i])) break;
|
||||
++i;
|
||||
if (!ring) {
|
||||
testAbort("epicsRingPointerCreate failed");
|
||||
}
|
||||
if(i!=ringSize) printf("fill ring failed i %d ringSize %d\n",i,ringSize);
|
||||
printf("empty ring\n");
|
||||
i=0;
|
||||
while(1) {
|
||||
if(!(pgetValue = (int *)epicsRingPointerPop(ring))) break;
|
||||
if(i!=*pgetValue) printf("main expected %d got %d\n",i,*pgetValue);
|
||||
++i;
|
||||
testOk(epicsRingPointerIsEmpty(ring), "Ring empty");
|
||||
|
||||
for (i=0; epicsRingPointerPush(ring,(void *)&value[i]); ++i) {}
|
||||
testOk(i==ringSize, "ring filled, %d values", i);
|
||||
|
||||
for (i=0; (pgetValue = (int *)epicsRingPointerPop(ring)); ++i) {
|
||||
testOk(i==*pgetValue, "Pop test: %d == %d", i, *pgetValue);
|
||||
}
|
||||
if(!epicsRingPointerIsEmpty(ring)) printf("epicsRingPointerIsEmpty failed\n");
|
||||
for(i=0; i<ringSize*2; i++) {
|
||||
while(epicsRingPointerIsFull(ring)) {
|
||||
testOk(epicsRingPointerIsEmpty(ring), "Ring empty");
|
||||
|
||||
epicsThreadCreate("consumer", 50,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall), consumer, pinfo);
|
||||
epicsThreadSleep(0.1);
|
||||
|
||||
for (i=0; i<ringSize*2; i++) {
|
||||
if (epicsRingPointerIsFull(ring)) {
|
||||
epicsEventSignal(consumerEvent);
|
||||
epicsThreadSleep(2.0);
|
||||
epicsThreadSleep(0.2);
|
||||
}
|
||||
if(!epicsRingPointerPush(ring,(void *)&value[i]))
|
||||
printf("Why is ring full\n");
|
||||
testOk(epicsRingPointerPush(ring, (void *)&value[i]), "Ring not full");
|
||||
}
|
||||
epicsEventSignal(consumerEvent);
|
||||
epicsThreadSleep(2.0);
|
||||
epicsThreadSleep(0.2);
|
||||
testOk(epicsRingPointerIsEmpty(ring), "Ring empty");
|
||||
|
||||
testExit = 1;
|
||||
epicsEventSignal(consumerEvent);
|
||||
epicsThreadSleep(1.0);
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* ringPointerTestMain.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "epicsThread.h"
|
||||
extern "C" {
|
||||
void ringPointerTest(void);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
ringPointerTest();
|
||||
printf("main terminating\n");
|
||||
return(0);
|
||||
}
|
||||
46
src/libCom/test/testMain.h
Normal file
46
src/libCom/test/testMain.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2006 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.
|
||||
\*************************************************************************/
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef INC_testMain_H
|
||||
#define INC_testMain_H
|
||||
|
||||
/* This header defines a convenience macro for use by pure test programs.
|
||||
* A pure test program cannot take any arguments since it must be fully
|
||||
* automatable. If your program needs to use argv/argc, it may be doing
|
||||
* measurements not unit and/or regression testing. On Host architectures
|
||||
* these programs needs to be named main and take dummy argc/argv args,
|
||||
* but on vxWorks and RTEMS they must be named as the test program.
|
||||
*
|
||||
* Use this macro as follows:
|
||||
*
|
||||
* #include "testMain.h"
|
||||
* #include "epicsUnitTest.h"
|
||||
*
|
||||
* MAIN(myProgTest) {
|
||||
* testPlan(...);
|
||||
* testOk(...)
|
||||
* return testDone();
|
||||
* }
|
||||
*/
|
||||
|
||||
#if defined(vxWorks) || defined(__rtems__)
|
||||
#ifdef __cplusplus
|
||||
#define MAIN(prog) extern "C" int prog(void)
|
||||
#else
|
||||
#define MAIN(prog) int prog()
|
||||
#endif
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
#define MAIN(prog) int main(int /*argc*/, char * /*argv*/ [] )
|
||||
#else
|
||||
#define MAIN(prog) int main(int argc, char *argv[] )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* INC_testMain_H */
|
||||
Reference in New Issue
Block a user