diff --git a/pvDataApp/Makefile b/pvDataApp/Makefile index 6a0d496..d79b6f9 100644 --- a/pvDataApp/Makefile +++ b/pvDataApp/Makefile @@ -16,9 +16,6 @@ INC += serializeHelper.h INC += event.h INC += thread.h INC += executor.h -INC += linkedList.h -INC += linkedListVoid.h -INC += CDRMonitor.h INC += timeFunction.h INC += timer.h INC += queue.h @@ -27,13 +24,11 @@ INC += destroyable.h INC += status.h INC += sharedPtr.h -LIBSRCS += CDRMonitor.cpp LIBSRCS += byteBuffer.cpp LIBSRCS += bitSet.cpp LIBSRCS += epicsException.cpp LIBSRCS += requester.cpp LIBSRCS += serializeHelper.cpp -LIBSRCS += linkedListVoid.cpp LIBSRCS += event.cpp LIBSRCS += executor.cpp LIBSRCS += timeFunction.cpp diff --git a/pvDataApp/factory/Convert.cpp b/pvDataApp/factory/Convert.cpp index f093429..f721278 100644 --- a/pvDataApp/factory/Convert.cpp +++ b/pvDataApp/factory/Convert.cpp @@ -3316,9 +3316,6 @@ size_t copyNumericArray(PVScalarArray *from, size_t offset, PVScalarArray *to, s } return ncopy; } -#ifdef XXXXXXXXX - -#endif ///MARTY REMOVE THIS XXXXXXX ConvertPtr Convert::getConvert() { diff --git a/pvDataApp/misc/CDRMonitor.cpp b/pvDataApp/misc/CDRMonitor.cpp deleted file mode 100644 index 9a14db4..0000000 --- a/pvDataApp/misc/CDRMonitor.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* CDRMonitor.cpp */ -/** - * 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. - */ -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -typedef SSIZE_T ssize_t; -#endif - -namespace epics { namespace pvData { - -static -epicsThreadOnceId monitorInit = EPICS_THREAD_ONCE_INIT; - -// Must use a pointer w/ lazy init due to lack of -// initialization order guarantees -CDRMonitor* CDRMonitor::theone = 0; - -CDRMonitor& -CDRMonitor::get() -{ - epicsThreadOnce(&monitorInit, &CDRMonitor::init, 0); - assert(theone); - return *theone; -} - -void -CDRMonitor::init(void *) -{ - //BUG: No idea how to handle allocation failure at this stage. - theone=new CDRMonitor; -} - -void -CDRMonitor::destroy() -{ - if (theone) - { - CDRNode *node = theone->first(); - while (node) - { - CDRNode* tmp = node; - node = node->next(); - delete tmp; - } - delete theone; - theone = 0; - } -} - -CDRMonitor::CDRMonitor() - :firstNode(0) -{} - -CDRCount -CDRMonitor::current() -{ - CDRCount total; - for(CDRNode *cur=first(); !!cur; cur=cur->next()) - { - total+=cur->get(); - } - return total; -} - -void -CDRMonitor::show(FILE *fd, bool destroy) -{ - for(CDRNode *cur=first(); !!cur; cur=cur->next()) - { - cur->show(fd); - } - if (destroy) - CDRMonitor::destroy(); -} - -void -CDRMonitor::show(std::ostream& out, bool destroy) const -{ - for(CDRNode *cur=first(); !!cur; cur=cur->next()) - { - cur->show(out); - } - if (destroy) - CDRMonitor::destroy(); -} - -void -CDRNode::show(FILE *fd) -{ - Lock x(guard); - if(!current.cons && !current.dtys && !current.refs) - return; - fprintf(fd,"%s: totalConstruct %lu totalDestruct %lu", - nodeName.c_str(), (unsigned long)current.cons, - (unsigned long)current.dtys); - ssize_t alive=current.cons; - alive-=current.dtys; - if(current.refs) - fprintf(fd," totalReference %ld", current.refs); - if(alive) - fprintf(fd," ACTIVE %ld\n", (long)alive); - else - fprintf(fd,"\n"); -} - -void -CDRNode::show(std::ostream& out) const -{ - Lock x(guard); - if(!current.cons && !current.dtys && !current.refs) - return; - out<(raw); - inst->node=new CDRNode(inst->name); -} - -}} // namespace epics::pvData - -std::ostream& operator<<(std::ostream& out,const epics::pvData::CDRMonitor& mon) -{ - mon.show(out); - return out; -} - -std::ostream& operator<<(std::ostream& out,const epics::pvData::CDRNode& node) -{ - node.show(out); - return out; -} diff --git a/pvDataApp/misc/CDRMonitor.h b/pvDataApp/misc/CDRMonitor.h deleted file mode 100644 index dbeb2bf..0000000 --- a/pvDataApp/misc/CDRMonitor.h +++ /dev/null @@ -1,140 +0,0 @@ -/* CDRMonitor.h */ -/** - * 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. - */ -#ifndef CDRMONITOR_H -#define CDRMONITOR_H -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace epics { namespace pvData { - -//! Used to pass around snapshots -struct CDRCount { // default copy and assignment are ok - size_t cons, dtys; - long refs; - CDRCount():cons(0),dtys(0),refs(0){} - CDRCount& operator+=(const CDRCount& o) - {cons+=o.cons; dtys+=o.dtys; refs+=o.refs; return *this;} - CDRCount& operator=(size_t count) // reset counters - {cons=count; dtys=count; refs=count; return *this;} -}; - -class CDRNode; - -//! @brief Global registrar for CDRNodes -class CDRMonitor : private NoDefaultMethods { -public: - static CDRMonitor& get(); - static void destroy(); - - CDRNode* addNode(CDRNode& next) - { - CDRNode *ret=firstNode; - firstNode=&next; - return ret; - } - - CDRCount current(); //!< current global count - - CDRNode* first() const{return firstNode;} - - void show(FILE*, bool destroy = false); - void show(std::ostream&, bool destroy = false) const; -private: - // Private ctor for singleton - CDRMonitor(); - CDRNode *firstNode; - - static CDRMonitor *theone; - static void init(void*); -}; - -//! Counters for Construction, Destruction, and References of one class -class CDRNode : private NoDefaultMethods { -public: - CDRNode(const String& name) - :nodeName(name) - ,current() - ,guard() - ,nextNode(CDRMonitor::get().addNode(*this)) - {} - void construct(){Lock x(guard); current.cons++;} - void destruct(){Lock x(guard); current.dtys++;} - void incRef(){Lock x(guard); current.refs++;} - void decRef(){Lock x(guard); current.refs--;} - - CDRNode* next() const{return nextNode;} - - CDRCount get() const{Lock x(guard); return current;} - - void show(FILE*); - void show(std::ostream&) const; -private: - const String nodeName; - CDRCount current; - mutable Mutex guard; - CDRNode * const nextNode; -}; - -struct CDRNodeInstance -{ - CDRNode *node; - epicsThreadOnceId once; - const char* const name; -}; - -void onceNode(void* raw); - -static inline -CDRNode* -getNode(CDRNodeInstance *inst) -{ - epicsThreadOnce(&inst->once,&onceNode, - static_cast(inst)); - return inst->node; -} - -#ifndef NDEBUG - -#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) \ -static CDRNodeInstance NAME ## _node={0,EPICS_THREAD_ONCE_INIT,#NAME} - -#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) \ - getNode(&NAME ## _node)->destruct() - -#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) \ - getNode(&NAME ## _node)->construct() - -#define PVDATA_REFCOUNT_MONITOR_INCREF(NAME) \ - getNode(&NAME ## _node)->incRef() -#define PVDATA_REFCOUNT_MONITOR_DECREF(NAME) \ - getNode(&NAME ## _node)->decRef() - - -#else - -#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) -#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) -#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) -#define PVDATA_REFCOUNT_MONITOR_INCREF(NAME) -#define PVDATA_REFCOUNT_MONITOR_DECREF(NAME) - -#endif - -}} - -std::ostream& operator<<(std::ostream&,const epics::pvData::CDRMonitor&); -std::ostream& operator<<(std::ostream&,const epics::pvData::CDRNode&); - -#endif /* CDRMONITOR_H */ diff --git a/pvDataApp/misc/bitSet.cpp b/pvDataApp/misc/bitSet.cpp index ce43e78..2c85528 100644 --- a/pvDataApp/misc/bitSet.cpp +++ b/pvDataApp/misc/bitSet.cpp @@ -8,12 +8,10 @@ #include "stdio.h" #include #include -#include #include namespace epics { namespace pvData { - PVDATA_REFCOUNT_MONITOR_DEFINE(bitSet); BitSet::shared_pointer BitSet::create(uint32 nbits) { return BitSet::shared_pointer(new BitSet(nbits)); @@ -22,19 +20,15 @@ namespace epics { namespace pvData { BitSet::BitSet() : words(0), wordsLength(0), wordsInUse(0) { initWords(BITS_PER_WORD); - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(bitSet); } BitSet::BitSet(uint32 nbits) : words(0), wordsLength(0), wordsInUse(0) { initWords(nbits); - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(bitSet); } BitSet::~BitSet() { delete[] words; - - PVDATA_REFCOUNT_MONITOR_DESTRUCT(bitSet); } void BitSet::initWords(uint32 nbits) { diff --git a/pvDataApp/misc/event.cpp b/pvDataApp/misc/event.cpp index c63ed7d..4f2cb28 100644 --- a/pvDataApp/misc/event.cpp +++ b/pvDataApp/misc/event.cpp @@ -20,24 +20,20 @@ #include #include #include -#include namespace epics { namespace pvData { -PVDATA_REFCOUNT_MONITOR_DEFINE(event); static String alreadyOn("already on list"); Event::~Event() { epicsEventDestroy(id); id = 0; - PVDATA_REFCOUNT_MONITOR_DESTRUCT(event); } Event::Event(bool full) : id(epicsEventCreate(full?epicsEventFull : epicsEventEmpty)) { - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(event); } void Event::signal() diff --git a/pvDataApp/misc/event.h b/pvDataApp/misc/event.h index 83faf2a..a0c3b5d 100644 --- a/pvDataApp/misc/event.h +++ b/pvDataApp/misc/event.h @@ -9,13 +9,17 @@ #include #include #include -#include #include +#include namespace epics { namespace pvData { -class Event : private NoDefaultMethods { +class Event; +typedef std::tr1::shared_ptr EventPtr; + +class Event { public: + POINTER_DEFINITIONS(Event); explicit Event(bool = false); ~Event(); void signal(); diff --git a/pvDataApp/misc/executor.cpp b/pvDataApp/misc/executor.cpp index ba0bebf..48054fc 100644 --- a/pvDataApp/misc/executor.cpp +++ b/pvDataApp/misc/executor.cpp @@ -10,109 +10,55 @@ #include #include -#include -#include -#include -#include -#include -#include #include -#include namespace epics { namespace pvData { // special instance to stop the executor thread -static class ExecutorShutdown : public Command { - virtual void command(){}; -} executorShutdown; + virtual void command(); +}; + +void ExecutorShutdown::command() +{ +} static -Command *shutdown=&executorShutdown; +std::tr1::shared_ptr shutdown(new ExecutorShutdown()); -PVDATA_REFCOUNT_MONITOR_DEFINE(executor); -typedef LinkedListNode ExecutorListNode; -typedef LinkedList ExecutorList; - -class ExecutorNode { -public: - ExecutorNode(Command *command); - - Command *command; - ExecutorListNode node; - ExecutorListNode runNode; -}; - -ExecutorNode::ExecutorNode(Command *command) -: command(command), - node(*this), - runNode(*this) -{} - -class ExecutorPvt : public Runnable{ -public: - ExecutorPvt(String threadName,ThreadPriority priority); - ~ExecutorPvt(); - ExecutorNode * createNode(Command *command); - void execute(ExecutorNode *node); - virtual void run(); -private: - ExecutorList executorList; - ExecutorList runList; - Event moreWork; - Event stopped; - Mutex mutex; - Thread thread; -}; - -ExecutorPvt::ExecutorPvt(String threadName,ThreadPriority priority) -: executorList(), - runList(), - moreWork(), - stopped(), - mutex(), - thread(threadName,priority,this) -{} - -ExecutorPvt::~ExecutorPvt() +Executor::Executor(String threadName,ThreadPriority priority) +: thread(threadName,priority,this) { - ExecutorNode shutdownNode(shutdown); +} - execute(&shutdownNode); +Executor::~Executor() +{ + execute(shutdown); stopped.wait(); - // The thread signals 'stopped' while still holding // the lock. By taking it we wait for the run() function // to actually return Lock xx(mutex); - - ExecutorListNode *node; - while((node=executorList.removeHead())!=0) { - delete &node->getObject(); - } + head.reset(); + tail.reset(); } -void ExecutorPvt::run() +void Executor::run() { Lock xx(mutex); while(true) { - ExecutorListNode * executorListNode = 0; - while(runList.isEmpty()) { + while(head.get()==NULL) { xx.unlock(); moreWork.wait(); xx.lock(); } - executorListNode = runList.removeHead(); - - if(!executorListNode) continue; - Command *cmd=executorListNode->getObject().command; - - if(cmd==shutdown) break; - + CommandPtr command = head; + if(command.get()==NULL) continue; + if(command.get()==shutdown.get()) break; xx.unlock(); try { - executorListNode->getObject().command->command(); + command->command(); }catch(std::exception& e){ //TODO: feed into logging mechanism fprintf(stderr, "Executor: Unhandled exception: %s",e.what()); @@ -122,41 +68,20 @@ void ExecutorPvt::run() xx.lock(); } - stopped.signal(); } -ExecutorNode * ExecutorPvt::createNode(Command *command) +void Executor::execute(CommandPtr const & command) { Lock xx(mutex); - ExecutorNode *executorNode = new ExecutorNode(command); - executorList.addTail(executorNode->node); - return executorNode; + command->next.reset(); + if(head.get()==NULL) { + head = command; + moreWork.signal(); + return; + } + if(tail.get()==NULL) return; + tail->next = command; } -void ExecutorPvt::execute(ExecutorNode *node) -{ - Lock xx(mutex); - if(node->runNode.isOnList()) return; - bool isEmpty = runList.isEmpty(); - runList.addTail(node->runNode); - if(isEmpty) moreWork.signal(); -} - -Executor::Executor(String threadName,ThreadPriority priority) -: pImpl(new ExecutorPvt(threadName,priority)) -{ - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(executor); -} - -Executor::~Executor() { - delete pImpl; - PVDATA_REFCOUNT_MONITOR_DESTRUCT(executor); -} - -ExecutorNode * Executor::createNode(Command*command) -{return pImpl->createNode(command);} - -void Executor::execute(ExecutorNode *node) {pImpl->execute(node);} - }} diff --git a/pvDataApp/misc/executor.h b/pvDataApp/misc/executor.h index 5fac993..d8118c3 100644 --- a/pvDataApp/misc/executor.h +++ b/pvDataApp/misc/executor.h @@ -7,30 +7,43 @@ #ifndef EXECUTOR_H #define EXECUTOR_H #include -#include -#include #include +#include +#include #include +#include namespace epics { namespace pvData { -// This is created by Executor.createNode and passed to Executor.execute -class ExecutorNode; +class Command; +class Executor; +typedef std::tr1::shared_ptr CommandPtr; +typedef std::tr1::shared_ptr ExecutorPtr; class Command { public: + POINTER_DEFINITIONS(Command); virtual ~Command(){} virtual void command() = 0; +private: + CommandPtr next; + friend class Executor; }; -class Executor : private NoDefaultMethods { +class Executor : public Runnable{ public: + POINTER_DEFINITIONS(Executor); Executor(String threadName,ThreadPriority priority); ~Executor(); - ExecutorNode * createNode(Command *command); - void execute(ExecutorNode *node); + void execute(CommandPtr const &node); + virtual void run(); private: - class ExecutorPvt *pImpl; + CommandPtr head; + CommandPtr tail; + epics::pvData::Mutex mutex; + epics::pvData::Event moreWork; + epics::pvData::Event stopped; + epics::pvData::Thread thread; }; }} diff --git a/pvDataApp/misc/linkedList.h b/pvDataApp/misc/linkedList.h deleted file mode 100644 index 9fa8fe7..0000000 --- a/pvDataApp/misc/linkedList.h +++ /dev/null @@ -1,84 +0,0 @@ -/* linkedList.h */ -/** - * 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. - */ -#ifndef LINKEDLIST_H -#define LINKEDLIST_H -#include -namespace epics { namespace pvData { - -template -class LinkedList; - -template -class LinkedListNode : private LinkedListVoidNode { -public: - LinkedListNode(T &object) : LinkedListVoidNode(&object){} - ~LinkedListNode() {} - T &getObject() { return *static_cast(LinkedListVoidNode::getObject());} - bool isOnList() {return LinkedListVoidNode::isOnList();} - friend class LinkedList; -}; - -template -class LinkedList : private LinkedListVoid { -public: - LinkedList() : LinkedListVoid() {} - ~LinkedList() {} - int getLength() {return LinkedListVoid::getLength();} - void addTail(LinkedListNode &listNode) - { - LinkedListVoid::addTail(static_cast(listNode)); - } - void addHead(LinkedListNode &listNode) - { - LinkedListVoid::addHead(static_cast(listNode)); - } - void insertAfter(LinkedListNode &listNode, - LinkedListNode &addNode) - { - LinkedListVoid::insertAfter( - static_cast(listNode), - static_cast(addNode)); - } - void insertBefore(LinkedListNode &listNode, - LinkedListNode &addNode) - { - LinkedListVoid::insertBefore( - static_cast(listNode), - static_cast(addNode)); - } - LinkedListNode *removeTail(){ - return static_cast *>(LinkedListVoid::removeTail()); - } - LinkedListNode *removeHead(){ - return static_cast *>(LinkedListVoid::removeHead()); - } - void remove(LinkedListNode &listNode){ - LinkedListVoid::remove(static_cast(listNode)); - } - LinkedListNode *getHead(){ - return static_cast *>(LinkedListVoid::getHead()); - } - LinkedListNode *getTail(){ - return static_cast *>(LinkedListVoid::getTail()); - } - LinkedListNode *getNext(LinkedListNode &listNode){ - return static_cast *>(LinkedListVoid::getNext( - static_cast(listNode))); - } - LinkedListNode *getPrev(LinkedListNode &listNode){ - return static_cast *>(LinkedListVoid::getPrev( - static_cast(listNode))); - } - bool isEmpty() { return LinkedListVoid::isEmpty();} -}; - - -}} -#endif /* LINKEDLIST_H */ - - - diff --git a/pvDataApp/misc/linkedListVoid.cpp b/pvDataApp/misc/linkedListVoid.cpp deleted file mode 100644 index 25eab96..0000000 --- a/pvDataApp/misc/linkedListVoid.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* linkedListVoid.cpp */ -/** - * 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. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace epics { namespace pvData { - -static String alreadyOnList("already on list"); - -PVDATA_REFCOUNT_MONITOR_DEFINE(LinkedListNode); -PVDATA_REFCOUNT_MONITOR_DEFINE(LinkedList); - -LinkedListVoidNode::LinkedListVoidNode(void *object) -: object(object),before(0),after(0),linkedListVoid(0) -{ - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedListNode); -} - -LinkedListVoidNode::LinkedListVoidNode(bool isHead) -: object(this),before(this),after(this) -{ - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedListNode); -} - - -LinkedListVoidNode::~LinkedListVoidNode() -{ - PVDATA_REFCOUNT_MONITOR_DESTRUCT(LinkedListNode); -} - -void *LinkedListVoidNode::getObject() { - return object; -} - -bool LinkedListVoidNode::isOnList() -{ - if(before==0 && after==0) return false; - return true; -} - -LinkedListVoid::LinkedListVoid() -: head(new LinkedListVoidNode(true)),length(0) -{ - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedList); -} - -LinkedListVoid::~LinkedListVoid() -{ - delete head; - PVDATA_REFCOUNT_MONITOR_DESTRUCT(LinkedList); -} - -int LinkedListVoid::getLength() -{ - return length; -} - -void LinkedListVoid::addTail(LinkedListVoidNode &node) -{ - if(node.before!=0 || node.after!=0) { - throw std::logic_error(alreadyOnList); - } - node.linkedListVoid = this; - node.before = head->before; - node.after = head; - head->before->after = &node; - head->before = &node; - ++length; -} - -void LinkedListVoid::addHead(LinkedListVoidNode &node) -{ - if(node.before!=0 || node.after!=0) { - throw std::logic_error(alreadyOnList); - } - node.linkedListVoid = this; - node.after = head->after; - node.before = head; - head->after->before = &node; - head->after = &node; - ++length; -} - -void LinkedListVoid::insertAfter(LinkedListVoidNode &node, - LinkedListVoidNode &addNode) -{ - LinkedListVoidNode *existingNode = &node; - LinkedListVoidNode *newNode = &addNode; - if(existingNode->after==0 || existingNode->before==0) { - throw std::logic_error(String("listNode not on list")); - } - if(newNode->before!=0 || newNode->after!=0) { - throw std::logic_error(alreadyOnList); - } - if(node.linkedListVoid!=this) { - throw std::logic_error(String("node not on this list")); - } - newNode->linkedListVoid = this; - newNode->after = existingNode->after; - newNode->before = existingNode; - existingNode->after->before = newNode; - existingNode->after = newNode; - ++length; -} - -void LinkedListVoid::insertBefore(LinkedListVoidNode &node, - LinkedListVoidNode &addNode) -{ - LinkedListVoidNode *existingNode = &node; - LinkedListVoidNode *newNode = &addNode; - if(existingNode->after==0 || existingNode->before==0) { - throw std::logic_error(String("listNode not on list")); - } - if(newNode->before!=0 || newNode->after!=0) { - throw std::logic_error(alreadyOnList); - } - if(node.linkedListVoid!=this) { - throw std::logic_error(String("node not on this list")); - } - newNode->linkedListVoid = this; - newNode->after = existingNode; - newNode->before = existingNode->before; - existingNode->before->after = newNode; - existingNode->before = newNode; - ++length; -} - -LinkedListVoidNode *LinkedListVoid::removeTail() -{ - if(head->after==head) return 0; - LinkedListVoidNode *node = head->before; - remove(*head->before); - return node; -} - -LinkedListVoidNode *LinkedListVoid::removeHead() -{ - if(head->after==head) return 0; - LinkedListVoidNode *node = head->after; - remove(*head->after); - return node; -} - -void LinkedListVoid::remove(LinkedListVoidNode &node) -{ - if(node.before==0 || node.after==0) { - throw std::logic_error(String("node not on list")); - } - if(node.linkedListVoid!=this) { - throw std::logic_error(String("node not on this list")); - } - node.linkedListVoid = 0; - LinkedListVoidNode *prev = node.before; - LinkedListVoidNode *next = node.after; - node.after = node.before = 0; - prev->after = next; - next->before = prev; - length--; -} - -LinkedListVoidNode *LinkedListVoid::getHead() -{ - if(head->after==head) return 0; - return head->after; -} - -LinkedListVoidNode *LinkedListVoid::getTail() -{ - if(head->after==head) return 0; - return head->before; -} - -LinkedListVoidNode *LinkedListVoid::getNext(LinkedListVoidNode &listNode) -{ - if(listNode.linkedListVoid!=this) { - throw std::logic_error(String("node not on this list")); - } - if(listNode.after==head) return 0; - return listNode.after; -} - -LinkedListVoidNode *LinkedListVoid::getPrev(LinkedListVoidNode &listNode) -{ - if(listNode.linkedListVoid!=this) { - throw std::logic_error(String("node not on this list")); - } - if(listNode.before==head) return 0; - return listNode.before; -} - -bool LinkedListVoid::isEmpty() -{ - if(head->after==head) return true; - return false; -} - -}} diff --git a/pvDataApp/misc/linkedListVoid.h b/pvDataApp/misc/linkedListVoid.h deleted file mode 100644 index bd92a54..0000000 --- a/pvDataApp/misc/linkedListVoid.h +++ /dev/null @@ -1,68 +0,0 @@ -/* linkedListVoid.h */ -/** - * 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. - */ - -#ifndef LINKEDLISTVOID_H -#define LINKEDLISTVOID_H -#include -namespace epics { namespace pvData { - -class LinkedListVoid; -class LinkedListVoidNode; - -class LinkedListVoidNode { -public: - ~LinkedListVoidNode(); - void *getObject(); - bool isOnList(); -protected: - LinkedListVoidNode(void *object); -private: - LinkedListVoidNode(bool isHead); - friend class LinkedListVoid; - void *object; - LinkedListVoidNode *before; - LinkedListVoidNode *after; - LinkedListVoid *linkedListVoid; - // do not implement the following - LinkedListVoidNode(const LinkedListVoidNode&); - LinkedListVoidNode & operator=(const LinkedListVoidNode&); -}; - -class LinkedListVoid { -public: - ~LinkedListVoid(); - int getLength(); - void addTail(LinkedListVoidNode &listNode); - void addHead(LinkedListVoidNode &listNode); - void insertAfter(LinkedListVoidNode &listNode, - LinkedListVoidNode &addNode); - void insertBefore(LinkedListVoidNode &listNode, - LinkedListVoidNode &addNode); - LinkedListVoidNode *removeTail(); - LinkedListVoidNode *removeHead(); - void remove(LinkedListVoidNode &listNode); - LinkedListVoidNode *getHead(); - LinkedListVoidNode *getTail(); - LinkedListVoidNode *getNext(LinkedListVoidNode &listNode); - LinkedListVoidNode *getPrev(LinkedListVoidNode &listNode); - bool isEmpty(); -protected: - LinkedListVoid(); -private: - friend class LinkedListVoidNode; - LinkedListVoidNode *head; - int length; - // do not implement the following - LinkedListVoid(const LinkedListVoid&); - LinkedListVoid & operator=(const LinkedListVoid&); -}; - -}} -#endif /* LINKEDLISTVOID_H */ - - - diff --git a/pvDataApp/misc/timeFunction.cpp b/pvDataApp/misc/timeFunction.cpp index 3dfcd33..5b43797 100644 --- a/pvDataApp/misc/timeFunction.cpp +++ b/pvDataApp/misc/timeFunction.cpp @@ -4,14 +4,19 @@ * EPICS pvDataCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ -#include +#include +#include +#include +#include +#include + #include #include #include namespace epics { namespace pvData { -TimeFunction::TimeFunction(TimeFunctionRequester *requester) +TimeFunction::TimeFunction(TimeFunctionRequesterPtr const &requester) : requester(requester) {} diff --git a/pvDataApp/misc/timeFunction.h b/pvDataApp/misc/timeFunction.h index 519f4ff..8ecd3d4 100644 --- a/pvDataApp/misc/timeFunction.h +++ b/pvDataApp/misc/timeFunction.h @@ -6,24 +6,31 @@ */ #ifndef TIMEFUNCTION_H #define TIMEFUNCTION_H -#include -#include +#include namespace epics { namespace pvData { +class TimeFunctionRequester; +class TimeFunction; +typedef std::tr1::shared_ptr TimeFunctionRequesterPtr; +typedef std::tr1::shared_ptr TimeFunctionPtr; + class TimeFunctionRequester { public: + POINTER_DEFINITIONS(TimeFunctionRequester); virtual ~TimeFunctionRequester(){} virtual void function() = 0; }; -class TimeFunction : private NoDefaultMethods { + +class TimeFunction { public: - TimeFunction(TimeFunctionRequester *requester); + POINTER_DEFINITIONS(TimeFunction); + TimeFunction(TimeFunctionRequesterPtr const & requester); ~TimeFunction(); double timeCall(); private: - TimeFunctionRequester *requester; + TimeFunctionRequesterPtr requester; }; diff --git a/pvDataApp/misc/timer.cpp b/pvDataApp/misc/timer.cpp index 6ffea19..5dc6883 100644 --- a/pvDataApp/misc/timer.cpp +++ b/pvDataApp/misc/timer.cpp @@ -11,224 +11,201 @@ #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include +#include namespace epics { namespace pvData { -PVDATA_REFCOUNT_MONITOR_DEFINE(timerNode); -PVDATA_REFCOUNT_MONITOR_DEFINE(timer); +TimerCallback::TimerCallback() +: period(0.0), + onList(false) +{ +} -typedef LinkedListNode TimerListNode; -typedef LinkedList TimerList; - -class TimerNode::Pvt { -public: - TimerNode *timerNode; - TimerCallback *callback; - TimerListNode timerListNode; - TimeStamp timeToRun; - Timer::Pvt *timerPvt; - double period; - Pvt(TimerNode &timerNode,TimerCallback &callback); - ~Pvt(){} -private: -}; - -TimerNode::Pvt::Pvt(TimerNode &timerNode,TimerCallback &callback) -: timerNode(&timerNode),callback(&callback), - timerListNode(*this),timeToRun(), - timerPvt(0), period(0.0) -{} - -struct Timer::Pvt : public Runnable{ -public: - Pvt(String threadName,ThreadPriority priority); - virtual void run(); -public: // only used by this source module - TimerList timerList; - Mutex mutex; - Event waitForWork; - Event waitForDone; - bool alive; - Thread thread; - void addElement(TimerNode::Pvt &node); -}; - -Timer::Pvt::Pvt(String threadName,ThreadPriority priority) -: timerList(), - mutex(), - waitForWork(false), +Timer::Timer(String threadName,ThreadPriority priority) +: waitForWork(false), waitForDone(false), alive(true), thread(threadName,priority,this) {} -void Timer::Pvt::addElement(TimerNode::Pvt &node) +void Timer::addElement(TimerCallbackPtr const & timerCallback) { - TimerListNode *nextNode = timerList.getHead(); - if(nextNode==0) { - timerList.addTail(node.timerListNode); + timerCallback->onList = true; + if(head.get()==NULL) { + head = timerCallback; + timerCallback->next.reset(); return; } + TimerCallbackPtr nextNode(head); + TimerCallbackPtr prevNode; while(true) { - TimerNode::Pvt &timerListNode = nextNode->getObject(); - if((node.timeToRun)<(timerListNode.timeToRun)) { - timerList.insertBefore(timerListNode.timerListNode,node.timerListNode); - return; - } - nextNode = timerList.getNext(timerListNode.timerListNode); - if(nextNode==0) { - timerList.addTail(node.timerListNode); + if(timerCallback->timeToRun < nextNode->timeToRun) { + if(prevNode.get()!=NULL) { + prevNode->next = timerCallback; + } else { + head = timerCallback; + } + timerCallback->next = nextNode; return; } + if(nextNode->next.get()==NULL) { + nextNode->next = timerCallback; + timerCallback->next.reset(); + return; + } + prevNode = nextNode; + nextNode = nextNode->next; } } -TimerNode::TimerNode(TimerCallback &callback) -: pImpl(new Pvt(*this,callback)) +void Timer::cancel(TimerCallbackPtr const &timerCallback) { - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(timerNode); + Lock xx(mutex); + if(!timerCallback->onList) return; + TimerCallbackPtr nextNode(head); + TimerCallbackPtr prevNode; + while(true) { + if(nextNode.get()==timerCallback.get()) { + if(prevNode.get()!=NULL) { + prevNode->next = timerCallback->next; + } else { + head = timerCallback->next; + } + timerCallback->next.reset(); + timerCallback->onList = false; + return; + } + prevNode = nextNode; + nextNode = nextNode->next; + } + throw std::logic_error(String("")); +} + +bool Timer::isScheduled(TimerCallbackPtr const &timerCallback) +{ + Lock xx(mutex); + return timerCallback->onList; } -TimerNode::~TimerNode() -{ - cancel(); - PVDATA_REFCOUNT_MONITOR_DESTRUCT(timerNode); -} - -void TimerNode::cancel() -{ - Timer::Pvt *timerPvt = pImpl->timerPvt; - if(timerPvt==0) return; - Lock xx(timerPvt->mutex); - if(pImpl->timerPvt==0) return; - pImpl->timerPvt->timerList.remove(pImpl->timerListNode); - pImpl->timerPvt = 0; -} - -bool TimerNode::isScheduled() -{ - Timer::Pvt *pvt = pImpl->timerPvt; - if(pvt==0) return false; - Lock xx(pvt->mutex); - return pImpl->timerListNode.isOnList(); -} - - -void Timer::Pvt::run() +void Timer::run() { TimeStamp currentTime; while(true) { - currentTime.getCurrent(); - TimeStamp *timeToRun = 0; double period = 0.0; - TimerNode::Pvt *nodeToCall = 0; + TimerCallbackPtr nodeToCall; { Lock xx(mutex); + currentTime.getCurrent(); if (!alive) break; - TimerListNode *timerListNode = timerList.getHead(); - if(timerListNode!=0) { - TimerNode::Pvt *timerNodePvt = &timerListNode->getObject(); - timeToRun = &timerNodePvt->timeToRun; + TimerCallbackPtr timerCallback = head; + if(timerCallback.get()!=NULL) { double diff = TimeStamp::diff( - *timeToRun,currentTime); + timerCallback->timeToRun,currentTime); if(diff<=0.0) { - nodeToCall = timerNodePvt; - timerList.removeHead(); - period = timerNodePvt->period; + nodeToCall = timerCallback; + nodeToCall->onList = false; + head = head->next; + period = timerCallback->period; if(period>0.0) { - timerNodePvt->timeToRun += period; - addElement(*timerNodePvt); - } else { - timerNodePvt->timerPvt = 0; - } - timerListNode = timerList.getHead(); - if(timerListNode!=0) { - timerNodePvt = &timerListNode->getObject(); - timeToRun = &timerNodePvt->timeToRun; - } else { - timeToRun = 0; + timerCallback->timeToRun += period; + addElement(timerCallback); } + timerCallback = head; } } } - if(nodeToCall!=0) { - nodeToCall->callback->callback(); + if(nodeToCall.get()!=NULL) { + nodeToCall->callback(); } { Lock xx(mutex); if(!alive) break; } - if(timeToRun==0) { + if(head.get()==NULL) { waitForWork.wait(); } else { - double delay = TimeStamp::diff(*timeToRun,currentTime); + double delay = TimeStamp::diff(head->timeToRun,currentTime); waitForWork.wait(delay); } } waitForDone.signal(); } -Timer::Timer(String threadName, ThreadPriority priority) -: pImpl(new Pvt(threadName,priority)) -{ - PVDATA_REFCOUNT_MONITOR_CONSTRUCT(timer); -} - Timer::~Timer() { { - Lock xx(pImpl->mutex); - pImpl->alive = false; + Lock xx(mutex); + alive = false; } - pImpl->waitForWork.signal(); - pImpl->waitForDone.wait(); - TimerListNode *node = 0; - while((node = pImpl->timerList.removeHead())!=0) { - node->getObject().callback->timerStopped(); + waitForWork.signal(); + waitForDone.wait(); + TimerCallbackPtr timerCallback; + while(true) { + timerCallback = head; + if(head.get()==NULL) break; + head->timerStopped(); + head = timerCallback->next; + timerCallback->next.reset(); + timerCallback->onList = false; } - PVDATA_REFCOUNT_MONITOR_DESTRUCT(timer); } -void Timer::scheduleAfterDelay(TimerNode &timerNode,double delay) +void Timer::scheduleAfterDelay( + TimerCallbackPtr const &timerCallback, + double delay) { - schedulePeriodic(timerNode,delay,0.0); + schedulePeriodic(timerCallback,delay,0.0); } -void Timer::schedulePeriodic(TimerNode &timerNode,double delay,double period) + +void Timer::schedulePeriodic( + TimerCallbackPtr const &timerCallback, + double delay, + double period) { - TimerNode::Pvt *timerNodePvt = timerNode.pImpl.get(); - if(timerNodePvt->timerListNode.isOnList()) { + if(isScheduled(timerCallback)) { throw std::logic_error(String("already queued")); } { - Lock xx(pImpl->mutex); - if(!pImpl->alive) { - timerNodePvt->callback->timerStopped(); + Lock xx(mutex); + if(!alive) { + timerCallback->timerStopped(); return; } } - TimeStamp *timeStamp = &timerNodePvt->timeToRun; - timeStamp->getCurrent(); - *timeStamp += delay; - timerNodePvt->period = period; + TimeStamp timeStamp; + timeStamp.getCurrent(); + timeStamp += delay; + timerCallback->timeToRun.getCurrent(); + timerCallback->timeToRun += delay; + timerCallback->period = period; bool isFirst = false; { - Lock xx(pImpl->mutex); - timerNodePvt->timerPvt = pImpl.get(); - pImpl->addElement(*timerNodePvt); - TimerNode::Pvt *first = &pImpl->timerList.getHead()->getObject(); - if(first==timerNodePvt) isFirst = true; + Lock xx(mutex); + addElement(timerCallback); + if(timerCallback.get()==head.get()) isFirst = true; } - if(isFirst) pImpl->waitForWork.signal(); + if(isFirst) waitForWork.signal(); +} + +void Timer::toString(StringBuilder builder) +{ + Lock xx(mutex); + if(!alive) return; + TimeStamp currentTime; + TimerCallbackPtr nodeToCall(head); + currentTime.getCurrent(); + while(true) { + if(nodeToCall.get()==NULL) return; + TimeStamp timeToRun = nodeToCall->timeToRun; + double period = nodeToCall->period; + double diff = TimeStamp::diff(timeToRun,currentTime); + char buffer[50]; + sprintf(buffer,"timeToRun %f period %f\n",diff,period); + *builder += buffer; + nodeToCall = nodeToCall->next; + } } }} diff --git a/pvDataApp/misc/timer.h b/pvDataApp/misc/timer.h index adce64e..5cdb16c 100644 --- a/pvDataApp/misc/timer.h +++ b/pvDataApp/misc/timer.h @@ -15,44 +15,57 @@ #include #include -#include +#include +#include +#include #include namespace epics { namespace pvData { +class TimerCallback; class Timer; +typedef std::tr1::shared_ptr TimerCallbackPtr; +typedef std::tr1::shared_ptr TimerPtr; class TimerCallback { public: + POINTER_DEFINITIONS(TimerCallback); + TimerCallback(); virtual ~TimerCallback(){} virtual void callback() = 0; virtual void timerStopped() = 0; -}; - -class TimerNode { -public: - TimerNode(TimerCallback &timerCallback); - ~TimerNode(); - void cancel(); - bool isScheduled(); - class Pvt; private: - std::auto_ptr pImpl; + TimerCallbackPtr next; + TimeStamp timeToRun; + double period; + bool onList; friend class Timer; }; -class Timer : private NoDefaultMethods { +class Timer : public Runnable { public: POINTER_DEFINITIONS(Timer); - Timer(String threadName, ThreadPriority priority); - ~Timer(); - void scheduleAfterDelay(TimerNode &timerNode,double delay); - void schedulePeriodic(TimerNode &timerNode,double delay,double period); - - class Pvt; + virtual ~Timer(); + virtual void run(); + void scheduleAfterDelay( + TimerCallbackPtr const &timerCallback, + double delay); + void schedulePeriodic( + TimerCallbackPtr const &timerCallback, + double delay, + double period); + void cancel(TimerCallbackPtr const &timerCallback); + bool isScheduled(TimerCallbackPtr const &timerCallback); + void toString(StringBuilder builder); private: - std::auto_ptr pImpl; + void addElement(TimerCallbackPtr const &timerCallback); + TimerCallbackPtr head; + Mutex mutex; + Event waitForWork; + Event waitForDone; + bool alive; + Thread thread; }; }} diff --git a/testApp/misc/Makefile b/testApp/misc/Makefile index d98b7cf..3b66c17 100644 --- a/testApp/misc/Makefile +++ b/testApp/misc/Makefile @@ -42,10 +42,6 @@ PROD_HOST += testMessageQueue testMessageQueue_SRCS += testMessageQueue.cpp testMessageQueue_LIBS += pvData Com -PROD_HOST += testLinkedList -testLinkedList_SRCS += testLinkedList.cpp -testLinkedList_LIBS += pvData Com - include $(TOP)/configure/RULES #---------------------------------------- # ADD RULES AFTER THIS LINE diff --git a/testApp/misc/testBitSet.cpp b/testApp/misc/testBitSet.cpp index 45447f2..85b5e65 100644 --- a/testApp/misc/testBitSet.cpp +++ b/testApp/misc/testBitSet.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -150,8 +149,6 @@ int main(int argc,char *argv[]) } testGetSetClearFlip(fd); testOperators(fd); - epicsExitCallAtExits(); - CDRMonitor::get().show(fd); return(0); } diff --git a/testApp/misc/testLinkedList.cpp b/testApp/misc/testLinkedList.cpp deleted file mode 100644 index ed2d655..0000000 --- a/testApp/misc/testLinkedList.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/** - * 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. - */ -/* - * testLinkedList.cpp - * - * Created on: 2010.11 - * Author: Marty Kraimer - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - - -using namespace epics::pvData; - -static const int numNodes = 5; -class Basic; -typedef LinkedListNode BasicListNode; -typedef LinkedList BasicList; - -class Basic { -public: - Basic(int i): index(i),node(*this) {} - ~Basic() { } - int index; - BasicListNode node; -}; - -static void testBasic(FILE * fd ) { - LinkedList basicList; - Basic *basics[numNodes]; - for(int i=0; inode); - assert(basicList.getLength()==i+1); - } - BasicListNode *basicNode = basicList.getHead(); - fprintf(fd,"basic addTail"); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.getNext(*basicNode); - } - assert(basicList.isEmpty()==false); - basicNode = basicList.getTail(); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - assert(basicNode->isOnList()); - basicNode = basicList.getPrev(*basicNode); - } - fprintf(fd,"\n"); - for(int i=0; igetObject(); - assert(basic.index==i); - assert(basics[i]->node.isOnList()==true); - basicList.remove(basics[i]->node); - assert(basics[i]->node.isOnList()==false); - int length = basicList.getLength(); - assert(length==(numNodes-i-1)); - } - assert(basicList.isEmpty()); - for(int i=numNodes-1; i>=0; i--) { - basicList.addHead(basics[i]->node); - assert(basicList.getLength()==numNodes-i); - } - basicNode = basicList.getHead(); - fprintf(fd,"basic addHead"); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.getNext(*basicNode); - } - fprintf(fd,"\n"); - for(int i=0; igetObject(); - assert(basic.index==i); - basicList.removeHead(); - assert(basic.node.isOnList()==false); - int length = basicList.getLength(); - assert(length==(numNodes-i-1)); - } - assert(basicList.isEmpty()); - basicList.addTail(basics[0]->node); - basicNode = basicList.getTail(); - assert(basicNode->getObject().index==0); - for(int i=1;inode); - basicNode = basicList.getTail(); - assert(basicList.getLength()==i+1); - } - fprintf(fd,"basic addTail insertAfter"); - basicNode = basicList.getHead(); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.getNext(*basicNode); - } - fprintf(fd,"\n"); - for(int i=numNodes-1; i>=0; i--) { - Basic &basic = basicList.getTail()->getObject(); - assert(basic.index==i); - basicList.removeTail(); - assert(basic.node.isOnList()==false); - int length = basicList.getLength(); - assert(length==i); - } - assert(basicList.isEmpty()); - basicList.addHead(basics[numNodes-1]->node); - basicNode = basicList.getHead(); - assert(basicNode->getObject().index==4); - for(int i=numNodes-2; i>=0; i--) { - basicList.insertBefore(*basicNode,basics[i]->node); - basicNode = basicList.getHead(); - assert(basicList.getLength()==numNodes-i); - } - fprintf(fd,"basic addTail insertBefore"); - basicNode = basicList.getHead(); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.getNext(*basicNode); - } - fprintf(fd,"\n"); - for(int i=numNodes-1; i>=0; i--) { - Basic &basic = basicList.getTail()->getObject(); - assert(basic.index==i); - basicList.remove(basic.node); - assert(basic.node.isOnList()==false); - int length = basicList.getLength(); - assert(length==i); - } - assert(basicList.isEmpty()); - for(int i=0; i basicList; - Basic *basics[numNodes]; - for(int i=0; inode); - assert(basicList.getLength()==i+1); - } - BasicListNode *basicNode = basicList.removeHead(); - while(basicNode!=0) basicNode = basicList.removeHead(); - for(int i=0;inode); - basicNode = basicList.removeHead(); - fprintf(fd,"queue"); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.removeHead(); - } - fprintf(fd,"\n"); - assert(basicList.isEmpty()); - for(int i=0; i basicList; - Basic *basics[numNodes]; - for(int i=0; inode); - assert(basicList.getLength()==i+1); - } - BasicListNode *basicNode = basicList.removeHead(); - while(basicNode!=0) basicNode = basicList.removeHead(); - for(int i=0;inode); - basicNode = basicList.removeHead(); - fprintf(fd,"stack"); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.removeHead(); - } - fprintf(fd,"\n"); - assert(basicList.isEmpty()); - for(int i=0; i basicList; - Basic *basics[numNodes]; - for(int i=0; inode); - fprintf(fd,"list"); - BasicListNode *basicNode = basicList.removeHead(); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.removeHead(); - } - fprintf(fd,"\n"); - assert(basicList.isEmpty()); - for(int i=0; i basicList; - Basic *basics[numNodes]; - for(int i=0; inode); - basicList.insertAfter(basics[4]->node,basics[3]->node); - basicList.insertAfter(basics[3]->node,basics[2]->node); - basicList.addTail(basics[1]->node); - basicList.addTail(basics[0]->node); - BasicListNode *basicNode = basicList.removeHead(); - fprintf(fd,"stack"); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.removeHead(); - } - fprintf(fd,"\n"); - assert(basicList.isEmpty()); - for(int i=0; i basicList; - Basic *basics[numNodes]; - for(int i=0; inode); - for(int i=0;inode.isOnList()) continue; - basicNode = basicList.getHead(); - while(basicNode!=0) { - if(basicNode->getObject().index>=basics[i]->index) { - basicList.insertBefore(*basicNode,basics[i]->node); - break; - } - basicNode = basicList.getNext(*basicNode); - } - if(basics[i]->node.isOnList()) continue; - basicList.addTail(basics[i]->node); - } - fprintf(fd,"list"); - basicNode = basicList.removeHead(); - while(basicNode!=0) { - fprintf(fd," %d",basicNode->getObject().index); - basicNode = basicList.removeHead(); - } - fprintf(fd,"\n"); - assert(basicList.isEmpty()); - for(int i=0; i basicList; - Basic *basics[numNodes]; - for(int i=0; inode); - BasicListNode *basicNode = basicList.removeHead(); - while(basicNode!=0) basicNode = basicList.removeHead(); - } - endTime.getCurrent(); - double diff = TimeStamp::diff(endTime,startTime); - diff *= 1000.0; - fprintf(auxFd,"diff %f milliSeconds\n",diff); - diff = diff/1000.0; // convert from milliseconds to seconds - diff = diff/ntimes; // seconds per outer loop - diff = diff*1e6; // converty to microseconds - fprintf(auxFd,"time per iteration %f microseconds\n",diff); - diff = diff/(numNodes*2); // convert to per addTail/removeHead - fprintf(auxFd,"time per addTail/removeHead %f microseconds\n",diff); - assert(basicList.isEmpty()); - for(int i=0; i basicList; - Basic *basics[numNodes]; - for(int i=0; inode); - } - BasicListNode *basicNode = 0; - { - Lock xx(mutex); - basicNode = basicList.removeHead(); - } - while(basicNode!=0) { - Lock xx(mutex); - basicNode = basicList.removeHead(); - } - } - endTime.getCurrent(); - double diff = TimeStamp::diff(endTime,startTime); - diff *= 1000.0; - fprintf(auxFd,"diff %f milliSeconds\n",diff); - diff = diff/1000.0; // convert from milliseconds to seconds - diff = diff/ntimes; // seconds per outer loop - diff = diff*1e6; // converty to microseconds - fprintf(auxFd,"time per iteration %f microseconds\n",diff); - diff = diff/(numNodes*2); // convert to per addTail/removeHead - fprintf(auxFd,"time per addTail/removeHead %f microseconds\n",diff); - assert(basicList.isEmpty()); - for(int i=0; i stdList; -static void testStdListTime(FILE *auxFd) { - TimeStamp startTime; - TimeStamp endTime; - const int numNodes = 1000; - - stdList basicList; - Basic *basics[numNodes]; - for(int i=0; i0) { - basicList.begin(); - basicList.pop_front(); - } - } - endTime.getCurrent(); - double diff = TimeStamp::diff(endTime,startTime); - diff *= 1000.0; - fprintf(auxFd,"diff %f milliSeconds\n",diff); - diff = diff/1000.0; // convert from milliseconds to seconds - diff = diff/ntimes; // seconds per outer loop - diff = diff*1e6; // converty to microseconds - fprintf(auxFd,"time per iteration %f microseconds\n",diff); - diff = diff/(numNodes*2); // convert to per addTail/removeHead - fprintf(auxFd,"time per addTail/removeHead %f microseconds\n",diff); - for(int i=0; i0) { - Lock xx(mutex); - basicList.begin(); - basicList.pop_front(); - } - } - endTime.getCurrent(); - double diff = TimeStamp::diff(endTime,startTime); - diff *= 1000.0; - fprintf(auxFd,"diff %f milliSeconds\n",diff); - diff = diff/1000.0; // convert from milliseconds to seconds - diff = diff/ntimes; // seconds per outer loop - diff = diff*1e6; // converty to microseconds - fprintf(auxFd,"time per iteration %f microseconds\n",diff); - diff = diff/(numNodes*2); // convert to per addTail/removeHead - fprintf(auxFd,"time per addTail/removeHead %f microseconds\n",diff); - for(int i=0; i1) 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+"); - } - testBasic(fd); - testQueue(fd); - testStack(fd); - testList(fd); - testRandomInsertRemove(fd); - testOrderedQueue(fd); - testTime(auxFd); - testTimeLocked(auxFd); - testStdListTime(auxFd); - testStdListTimeLocked(auxFd); - epicsExitCallAtExits(); - CDRMonitor::get().show(fd); - return (0); -} - diff --git a/testApp/misc/testMessageQueue.cpp b/testApp/misc/testMessageQueue.cpp index 52b1461..8ad691b 100644 --- a/testApp/misc/testMessageQueue.cpp +++ b/testApp/misc/testMessageQueue.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -89,8 +88,6 @@ int main(int argc, char *argv[]) { auxfd = fopen(auxFileName,"w+"); } testBasic(fd,auxfd); - epicsExitCallAtExits(); - CDRMonitor::get().show(fd); return (0); } diff --git a/testApp/misc/testSerialization.cpp b/testApp/misc/testSerialization.cpp index 8d18528..67f784d 100644 --- a/testApp/misc/testSerialization.cpp +++ b/testApp/misc/testSerialization.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -661,8 +660,6 @@ int main(int argc, char *argv[]) { delete flusher; epicsExitCallAtExits(); - (*out)<<"Done.\n"< #include #include -#include #include using namespace epics::pvData; @@ -39,7 +38,7 @@ public: begin.signal(); bool waited=end.wait(); actuallyRan=true; - fprintf(out, "Action1 %s\n", waited?"true":"false"); + fprintf(out, "Action %s\n", waited?"true":"false"); } }; @@ -49,81 +48,89 @@ static void testThreadRun(FILE *fd) { { Thread tr("Action", lowPriority, &ax); bool w=ax.begin.wait(); - fprintf(fd, "main1 %s\n", w?"true":"false"); + 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"); } -class Basic : public Command { +class Basic : + public Command, + public std::tr1::enable_shared_from_this +{ public: - Basic(Executor *executor); + POINTER_DEFINITIONS(Basic); + Basic(ExecutorPtr const &executor); ~Basic(); void run(); virtual void command(); private: - Executor *executor; - ExecutorNode *executorNode; - Event *wait; + Basic::shared_pointer getPtrSelf() + { + return shared_from_this(); + } + ExecutorPtr executor; + Event wait; }; -Basic::Basic(Executor *executor) -: executor(executor), - executorNode(executor->createNode(this)), - wait(new Event()) +typedef std::tr1::shared_ptr BasicPtr; + +Basic::Basic(ExecutorPtr const &executor) +: executor(executor) { } Basic::~Basic() { - delete wait; } void Basic::run() { - executor->execute(executorNode); - bool result = wait->wait(); + executor->execute(getPtrSelf()); + bool result = wait.wait(); if(result==false) printf("basic::run wait returned false\n"); } void Basic::command() { - wait->signal(); + wait.signal(); } static void testBasic(FILE *fd) { - Executor *executor = new Executor(String("basic"),middlePriority); - Basic *basic = new Basic(executor); + ExecutorPtr executor( new Executor(String("basic"),middlePriority)); + BasicPtr basic( new Basic(executor)); basic->run(); - delete basic; - String buf(""); - delete executor; } class MyFunc : public TimeFunctionRequester { public: - MyFunc(Basic *basic) - : basic(basic) - {} - virtual void function() - { - basic->run(); - } + POINTER_DEFINITIONS(MyFunc); + MyFunc(BasicPtr const &basic); + virtual void function(); private: - Basic *basic; + BasicPtr basic; }; +MyFunc::MyFunc(BasicPtr const &basic) + : basic(basic) + {} +void MyFunc::function() +{ + basic->run(); +} + + +typedef std::tr1::shared_ptr MyFuncPtr; + static void testThreadContext(FILE *fd,FILE *auxFd) { - Executor *executor = new Executor(String("basic"),middlePriority); - Basic *basic = new Basic(executor); - MyFunc myFunc(basic); - TimeFunction timeFunction(&myFunc); - double perCall = timeFunction.timeCall(); + 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); - delete basic; - delete executor; } int main(int argc, char *argv[]) { @@ -142,7 +149,5 @@ int main(int argc, char *argv[]) { testThreadRun(fd); testBasic(fd); testThreadContext(fd,auxFd); - epicsExitCallAtExits(); - CDRMonitor::get().show(fd); - return (0); + return 0; } diff --git a/testApp/misc/testTimer.cpp b/testApp/misc/testTimer.cpp index bea28dd..e0d680d 100644 --- a/testApp/misc/testTimer.cpp +++ b/testApp/misc/testTimer.cpp @@ -22,19 +22,26 @@ #include #include #include -#include using namespace epics::pvData; static TimeStamp currentTimeStamp; static double oneDelay = 4.0; static double twoDelay = 2.0; +static double threeDelay = 1.0; +static int ntimes = 3; + +class MyCallback; +typedef std::tr1::shared_ptr MyCallbackPtr; class MyCallback : public TimerCallback { public: - MyCallback(String name,FILE *fd,FILE *auxfd,Event *wait) - : name(name),fd(fd),auxfd(auxfd),wait(wait), - timerNode(*this),timeStamp(TimeStamp()) + POINTER_DEFINITIONS(MyCallback); + MyCallback(String name,FILE *fd,FILE *auxfd,EventPtr const & wait) + : name(name), + fd(fd), + auxfd(auxfd), + wait(wait) { } ~MyCallback() @@ -49,45 +56,115 @@ public: { fprintf(fd,"timerStopped %s\n",name.c_str()); } - TimerNode &getTimerNode() { return timerNode;} TimeStamp &getTimeStamp() { return timeStamp;} private: String name; FILE *fd; FILE *auxfd; - Event *wait; - TimerNode timerNode; + EventPtr wait; TimeStamp timeStamp; }; static void testBasic(FILE *fd, FILE *auxfd) { +printf("\n\ntestBasic oneDelay %lf twoDelay %lf threeDaley %lf\n", +oneDelay,twoDelay,threeDelay); String one("one"); String two("two"); - Event *eventOne = new Event(); - Event *eventTwo = new Event(); - Timer *timer = new Timer(String("timer"),middlePriority); - MyCallback *callbackOne = new MyCallback( - one,fd,auxfd,eventOne); - MyCallback *callbackTwo = new MyCallback( - two,fd,auxfd,eventTwo); - currentTimeStamp.getCurrent(); - timer->scheduleAfterDelay(callbackOne->getTimerNode(),oneDelay); - timer->scheduleAfterDelay(callbackTwo->getTimerNode(),twoDelay); - eventOne->wait(); - eventTwo->wait(); - double diff; - diff = TimeStamp::diff( - callbackOne->getTimeStamp(),currentTimeStamp); - fprintf(auxfd,"one requested %f diff %f seconds\n",oneDelay,diff); - diff = TimeStamp::diff( - callbackTwo->getTimeStamp(),currentTimeStamp); - fprintf(auxfd,"two requested %f diff %f seconds\n",twoDelay,diff); - delete timer; - delete callbackTwo; - delete callbackOne; - delete eventTwo; - delete eventOne; + String three("three"); + EventPtr eventOne(new Event()); + EventPtr eventTwo(new Event()); + EventPtr eventThree(new Event()); + TimerPtr timer(new Timer(String("timer"),middlePriority)); + MyCallbackPtr callbackOne(new MyCallback(one,fd,auxfd,eventOne)); + MyCallbackPtr callbackTwo(new MyCallback(two,fd,auxfd,eventTwo)); + MyCallbackPtr callbackThree(new MyCallback(three,fd,auxfd,eventThree)); + for(int n=0; nisScheduled(callbackOne)); + assert(!timer->isScheduled(callbackTwo)); + assert(!timer->isScheduled(callbackThree)); + timer->scheduleAfterDelay(callbackOne,oneDelay); + timer->scheduleAfterDelay(callbackTwo,twoDelay); + timer->scheduleAfterDelay(callbackThree,threeDelay); + if(oneDelay>.1) assert(timer->isScheduled(callbackOne)); + if(twoDelay>.1) assert(timer->isScheduled(callbackTwo)); + if(threeDelay>.1) assert(timer->isScheduled(callbackThree)); + String builder; + timer->toString(&builder); + printf("timerQueue\n%s",builder.c_str()); + eventOne->wait(); + eventTwo->wait(); + eventThree->wait(); + double diff; + double delta; + diff = TimeStamp::diff( + callbackOne->getTimeStamp(),currentTimeStamp); + delta = diff - oneDelay; + fprintf(auxfd,"one requested %f actual %f delta %f\n",oneDelay,diff,delta); + if(delta<0.0) delta = -delta; + assert(delta<.1); + diff = TimeStamp::diff( + callbackTwo->getTimeStamp(),currentTimeStamp); + delta = diff - twoDelay; + fprintf(auxfd,"two requested %f actual %f delta %f\n",twoDelay,diff,delta); + if(delta<0.0) delta = -delta; + assert(delta<.1); + diff = TimeStamp::diff( + callbackThree->getTimeStamp(),currentTimeStamp); + delta = diff - threeDelay; + fprintf(auxfd,"three requested %f actual %f delta %f\n",threeDelay,diff,delta); + if(delta<0.0) delta = -delta; + assert(delta<.1); + } +} + +static void testCancel(FILE *fd, FILE *auxfd) +{ +printf("\n\ntestCancel oneDelay %lf twoDelay %lf threeDaley %lf\n", +oneDelay,twoDelay,threeDelay); + String one("one"); + String two("two"); + String three("three"); + EventPtr eventOne(new Event()); + EventPtr eventTwo(new Event()); + EventPtr eventThree(new Event()); + TimerPtr timer(new Timer(String("timer"),middlePriority)); + MyCallbackPtr callbackOne(new MyCallback(one,fd,auxfd,eventOne)); + MyCallbackPtr callbackTwo(new MyCallback(two,fd,auxfd,eventTwo)); + MyCallbackPtr callbackThree(new MyCallback(three,fd,auxfd,eventThree)); + for(int n=0; nisScheduled(callbackOne)); + assert(!timer->isScheduled(callbackTwo)); + assert(!timer->isScheduled(callbackThree)); + timer->scheduleAfterDelay(callbackOne,oneDelay); + timer->scheduleAfterDelay(callbackTwo,twoDelay); + timer->scheduleAfterDelay(callbackThree,threeDelay); + timer->cancel(callbackTwo); + if(oneDelay>.1) assert(timer->isScheduled(callbackOne)); + assert(!timer->isScheduled(callbackTwo)); + if(threeDelay>.1) assert(timer->isScheduled(callbackThree)); + String builder; + timer->toString(&builder); + printf("timerQueue\n%s",builder.c_str()); + eventOne->wait(); + eventThree->wait(); + double diff; + double delta; + diff = TimeStamp::diff( + callbackOne->getTimeStamp(),currentTimeStamp); + delta = diff - oneDelay; + fprintf(auxfd,"one requested %f actual %f delta %f\n",oneDelay,diff,delta); + if(delta<0.0) delta = -delta; + assert(delta<.1); + diff = TimeStamp::diff( + callbackThree->getTimeStamp(),currentTimeStamp); + delta = diff - threeDelay; + fprintf(auxfd,"three requested %f actual %f delta %f\n",threeDelay,diff,delta); + if(delta<0.0) delta = -delta; + assert(delta<.1); + } } int main(int argc, char *argv[]) { @@ -105,14 +182,24 @@ int main(int argc, char *argv[]) { } oneDelay = .4; twoDelay = .2; + threeDelay = .1; testBasic(fd,auxfd); - oneDelay = .2; + testCancel(fd,auxfd); + oneDelay = .1; + twoDelay = .2; + threeDelay = .4; + testBasic(fd,auxfd); + testCancel(fd,auxfd); + oneDelay = .1; twoDelay = .4; + threeDelay = .2; testBasic(fd,auxfd); + testCancel(fd,auxfd); oneDelay = .0; twoDelay = .0; + threeDelay = .0; testBasic(fd,auxfd); + testCancel(fd,auxfd); epicsExitCallAtExits(); - CDRMonitor::get().show(fd); return (0); } diff --git a/testApp/pv/testIntrospect.cpp b/testApp/pv/testIntrospect.cpp index 19924da..23dd05d 100644 --- a/testApp/pv/testIntrospect.cpp +++ b/testApp/pv/testIntrospect.cpp @@ -20,7 +20,6 @@ #include #include #include -#include using namespace epics::pvData; diff --git a/testApp/pv/testPVStructureArray.cpp b/testApp/pv/testPVStructureArray.cpp index 8543d8a..cff40d6 100644 --- a/testApp/pv/testPVStructureArray.cpp +++ b/testApp/pv/testPVStructureArray.cpp @@ -89,7 +89,7 @@ void testPowerSupplyArray(FILE * fd) { powerSupplyArray->remove(2,1); buffer.clear(); powerSupplyArrayStruct->toString(&buffer); - fprintf(fd,"after remove 0,1,3%s\n",buffer.c_str()); + fprintf(fd,"after remove 2,1%s\n",buffer.c_str()); powerSupplyArray->compress(); buffer.clear(); powerSupplyArrayStruct->toString(&buffer);