158 lines
3.6 KiB
C++
158 lines
3.6 KiB
C++
/**
|
|
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
*/
|
|
/*
|
|
* testThread.cpp
|
|
*
|
|
* Created on: 2010.11
|
|
* Author: Marty Kraimer
|
|
*/
|
|
|
|
#include <cstddef>
|
|
#include <cstdlib>
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <cstdio>
|
|
#include <list>
|
|
|
|
#include <epicsAssert.h>
|
|
#include <epicsExit.h>
|
|
|
|
#include <pv/event.h>
|
|
#include <pv/thread.h>
|
|
#include <pv/executor.h>
|
|
#include <pv/timeFunction.h>
|
|
|
|
using namespace epics::pvData;
|
|
|
|
class Action : public Runnable {
|
|
public:
|
|
FILE *out;
|
|
bool actuallyRan;
|
|
Event begin, end;
|
|
Action(FILE* fp): out(fp), actuallyRan(false) {}
|
|
virtual void run() {
|
|
fprintf(out, "Action waiting\n");
|
|
begin.signal();
|
|
bool waited=end.wait();
|
|
actuallyRan=true;
|
|
fprintf(out, "Action %s\n", waited?"true":"false");
|
|
}
|
|
};
|
|
|
|
static void testThreadRun(FILE *fd) {
|
|
// show that we can control thread start and stop
|
|
Action ax(fd);
|
|
{
|
|
Thread tr("Action", lowPriority, &ax);
|
|
bool w=ax.begin.wait();
|
|
fprintf(fd, "main %s\n", w?"true":"false");
|
|
fprintf(fd, "Action is %s\n", ax.actuallyRan?"true":"false");
|
|
ax.end.signal();
|
|
}
|
|
fprintf(fd, "Action is %s\n", ax.actuallyRan?"true":"false");
|
|
fprintf(fd,"testThreadRun PASSED\n");
|
|
}
|
|
|
|
class Basic :
|
|
public Command,
|
|
public std::tr1::enable_shared_from_this<Basic>
|
|
{
|
|
public:
|
|
POINTER_DEFINITIONS(Basic);
|
|
Basic(ExecutorPtr const &executor);
|
|
~Basic();
|
|
void run();
|
|
virtual void command();
|
|
private:
|
|
Basic::shared_pointer getPtrSelf()
|
|
{
|
|
return shared_from_this();
|
|
}
|
|
ExecutorPtr executor;
|
|
Event wait;
|
|
};
|
|
|
|
typedef std::tr1::shared_ptr<Basic> BasicPtr;
|
|
|
|
Basic::Basic(ExecutorPtr const &executor)
|
|
: executor(executor)
|
|
{
|
|
}
|
|
|
|
Basic::~Basic() {
|
|
}
|
|
|
|
void Basic::run()
|
|
{
|
|
executor->execute(getPtrSelf());
|
|
bool result = wait.wait();
|
|
if(result==false) printf("basic::run wait returned false\n");
|
|
}
|
|
|
|
void Basic::command()
|
|
{
|
|
wait.signal();
|
|
}
|
|
|
|
|
|
static void testBasic(FILE *fd) {
|
|
ExecutorPtr executor( new Executor(String("basic"),middlePriority));
|
|
BasicPtr basic( new Basic(executor));
|
|
basic->run();
|
|
fprintf(fd,"testBasic PASSED\n");
|
|
}
|
|
|
|
class MyFunc : public TimeFunctionRequester {
|
|
public:
|
|
POINTER_DEFINITIONS(MyFunc);
|
|
MyFunc(BasicPtr const &basic);
|
|
virtual void function();
|
|
private:
|
|
BasicPtr basic;
|
|
};
|
|
|
|
MyFunc::MyFunc(BasicPtr const &basic)
|
|
: basic(basic)
|
|
{}
|
|
void MyFunc::function()
|
|
{
|
|
basic->run();
|
|
}
|
|
|
|
|
|
typedef std::tr1::shared_ptr<MyFunc> MyFuncPtr;
|
|
|
|
static void testThreadContext(FILE *fd,FILE *auxFd) {
|
|
ExecutorPtr executor(new Executor(String("basic"),middlePriority));
|
|
BasicPtr basic(new Basic(executor));
|
|
MyFuncPtr myFunc(new MyFunc(basic));
|
|
TimeFunctionPtr timeFunction(new TimeFunction(myFunc));
|
|
double perCall = timeFunction->timeCall();
|
|
perCall *= 1e6;
|
|
fprintf(auxFd,"time per call %f microseconds\n",perCall);
|
|
fprintf(fd,"testThreadContext PASSED\n");
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
char *fileName = 0;
|
|
if(argc>1) fileName = argv[1];
|
|
FILE * fd = stdout;
|
|
if(fileName!=0 && fileName[0]!=0) {
|
|
fd = fopen(fileName,"w+");
|
|
}
|
|
char *auxFileName = 0;
|
|
if(argc>2) auxFileName = argv[2];
|
|
FILE *auxFd = stdout;
|
|
if(auxFileName!=0 && auxFileName[0]!=0) {
|
|
auxFd = fopen(auxFileName,"w+");
|
|
}
|
|
testThreadRun(fd);
|
|
testBasic(fd);
|
|
testThreadContext(fd,auxFd);
|
|
epicsExitCallAtExits();
|
|
return 0;
|
|
}
|