From 1e976b7eeddbb1d257e7e8fd50000fd38bdd0061 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Wed, 23 Oct 2002 22:32:39 +0000 Subject: [PATCH] use placement new --- src/libCom/timer/epicsTimer.cpp | 24 ++++------ src/libCom/timer/epicsTimer.h | 12 ++++- src/libCom/timer/timer.cpp | 23 ++++++---- src/libCom/timer/timerPrivate.h | 81 +++++++++++++++++---------------- src/libCom/timer/timerQueue.cpp | 5 +- 5 files changed, 80 insertions(+), 65 deletions(-) diff --git a/src/libCom/timer/epicsTimer.cpp b/src/libCom/timer/epicsTimer.cpp index 86429c591..26300cebf 100644 --- a/src/libCom/timer/epicsTimer.cpp +++ b/src/libCom/timer/epicsTimer.cpp @@ -27,21 +27,10 @@ # pragma warning ( disable:4660 ) #endif -template class tsFreeList < epicsTimerForC, 0x20 >; -template class tsFreeList < epicsTimerQueuePassiveForC, 0x10 >; -template class tsFreeList < epicsTimerQueueActiveForC, 0x10 >; -template class epicsSingleton < tsFreeList < epicsTimerForC, 0x20 > >; -template class epicsSingleton < tsFreeList < epicsTimerQueuePassiveForC, 0x10 > >; -template class epicsSingleton < tsFreeList < epicsTimerQueueActiveForC, 0x10 > >; - #ifdef _MSC_VER # pragma warning ( pop ) #endif -epicsSingleton < tsFreeList < epicsTimerForC, 0x20 > > epicsTimerForC::pFreeList; -epicsSingleton < tsFreeList < epicsTimerQueuePassiveForC, 0x10 > > epicsTimerQueuePassiveForC::pFreeList; -epicsSingleton < tsFreeList < epicsTimerQueueActiveForC, 0x10 > > epicsTimerQueueActiveForC::pFreeList; - epicsTimer::~epicsTimer () {} epicsTimerQueueNotify::~epicsTimerQueueNotify () {} @@ -61,7 +50,9 @@ epicsTimerForC::~epicsTimerForC () void epicsTimerForC::destroy () { - delete this; + timerQueue & queueTmp ( this->queue ); + this->~epicsTimerForC (); + epicsTimerForC::operator delete ( this, queueTmp.timerForCFreeList ); } epicsTimerNotify::expireStatus epicsTimerForC::expire ( const epicsTime & ) @@ -81,7 +72,9 @@ epicsTimerQueueActiveForC::~epicsTimerQueueActiveForC () void epicsTimerQueueActiveForC::release () { - pTimerQueueMgrEPICS->release ( *this ); + epicsSingleton < timerQueueActiveMgr >::reference pMgr = + timerQueueMgrEPICS; + pMgr->release ( *this ); } epicsTimerQueuePassiveForC::epicsTimerQueuePassiveForC @@ -186,8 +179,9 @@ extern "C" epicsTimerQueueId epicsShareAPI epicsTimerQueueAllocate ( int okToShare, unsigned int threadPriority ) { try { - epicsTimerQueueActiveForC &tmr = - pTimerQueueMgrEPICS->allocate ( okToShare ? true : false, threadPriority ); + epicsSingleton < timerQueueActiveMgr >::reference ref = timerQueueMgrEPICS; + epicsTimerQueueActiveForC & tmr = + ref->allocate ( okToShare ? true : false, threadPriority ); return &tmr; } catch ( ... ) { diff --git a/src/libCom/timer/epicsTimer.h b/src/libCom/timer/epicsTimer.h index a43457f65..513930733 100644 --- a/src/libCom/timer/epicsTimer.h +++ b/src/libCom/timer/epicsTimer.h @@ -50,7 +50,7 @@ public: class epicsTimer { // X aCC 655 public: - virtual ~epicsTimer () = 0; // use destroy + virtual ~epicsTimer () = 0; virtual void destroy () = 0; virtual void start ( epicsTimerNotify &, const epicsTime & ) = 0; virtual void start ( epicsTimerNotify &, double delaySeconds ) = 0; @@ -63,6 +63,11 @@ public: virtual expireInfo getExpireInfo () const = 0; double getExpireDelay (); virtual void show ( unsigned int level ) const = 0; +private: + void * operator new ( size_t ); + void * operator new [] ( size_t ); + void operator delete ( void * ); + void operator delete [] ( void * ); }; class epicsTimerQueue { // X aCC 655 @@ -81,6 +86,11 @@ public: virtual void release () = 0; protected: virtual ~epicsTimerQueueActive () = 0; +private: + void * operator new ( size_t ); + void * operator new [] ( size_t ); + void operator delete ( void * ); + void operator delete [] ( void * ); }; class epicsTimerQueueNotify { // X aCC 655 diff --git a/src/libCom/timer/timer.cpp b/src/libCom/timer/timer.cpp index de93d43e6..637b8c4a1 100644 --- a/src/libCom/timer/timer.cpp +++ b/src/libCom/timer/timer.cpp @@ -18,6 +18,7 @@ */ #include +#include #define epicsExportSharedSymbols #include "epicsGuard.h" @@ -29,16 +30,13 @@ #endif template class tsFreeList < timer, 0x20 >; -template class epicsSingleton < tsFreeList < timer, 0x20 > >; #ifdef _MSC_VER # pragma warning ( pop ) #endif -epicsSingleton < tsFreeList < timer, 0x20 > > timer::pFreeList; - -timer::timer ( timerQueue &queueIn ) : - curState ( stateLimbo ), pNotify ( 0 ), queue ( queueIn ) +timer::timer ( timerQueue & queueIn ) : + queue ( queueIn ), curState ( stateLimbo ), pNotify ( 0 ) { } @@ -49,7 +47,9 @@ timer::~timer () void timer::destroy () { - delete this; + timerQueue & queueTmp ( this->queue ); + this->~timer (); + timer::operator delete ( this, queueTmp.timerFreeList ) ; } void timer::start ( epicsTimerNotify & notify, double delaySeconds ) @@ -223,8 +223,15 @@ void timer::show ( unsigned int level ) const } } -timerQueue & timer::getPrivTimerQueue() +void timer::operator delete ( void * pCadaver ) { - return this->queue; + throw std::logic_error + ( "compiler is confused about placement delete" ); +} + +void epicsTimerForC::operator delete ( void * pCadaver ) +{ + throw std::logic_error + ( "compiler is confused about placement delete" ); } diff --git a/src/libCom/timer/timerPrivate.h b/src/libCom/timer/timerPrivate.h index 62097074d..d9cd44c04 100644 --- a/src/libCom/timer/timerPrivate.h +++ b/src/libCom/timer/timerPrivate.h @@ -22,6 +22,7 @@ #include "epicsSingleton.h" #include "tsDLList.h" #include "epicsTimer.h" +#include "cxxCompilerDepPlacementDelete.h" #ifdef DEBUG # define debugPrintf(ARGSINPAREN) printf ARGSINPAREN @@ -39,22 +40,23 @@ public: void cancel (); expireInfo getExpireInfo () const; void show ( unsigned int level ) const; - class timerQueue & getPrivTimerQueue (); - void * operator new ( size_t size ); - void operator delete ( void *pCadaver, size_t size ); - + void * operator new ( size_t size, tsFreeList < timer, 0x20 > & ); +#ifdef CXX_PLACEMENT_DELETE + void operator delete ( void *, tsFreeList < timer, 0x20 > & ); +#endif protected: - timer ( class timerQueue & ); + timer ( class timerQueue & ) throw (); ~timer (); + timerQueue & queue; private: enum state { statePending = 45, stateActive = 56, stateLimbo = 78 }; epicsTime exp; // experation time state curState; // current state epicsTimerNotify * pNotify; // callback - timerQueue & queue; - static epicsSingleton < tsFreeList < timer, 0x20 > > pFreeList; void privateStart ( epicsTimerNotify & notify, const epicsTime & ); timer & operator = ( const timer & ); + void * operator new ( size_t size ); + void operator delete ( void * ); friend class timerQueue; }; @@ -62,16 +64,19 @@ struct epicsTimerForC : public epicsTimerNotify, public timer { public: void destroy (); protected: - epicsTimerForC ( timerQueue &, epicsTimerCallback, void *pPrivateIn ); + epicsTimerForC ( timerQueue &, epicsTimerCallback, void *pPrivateIn ) throw (); ~epicsTimerForC (); - void * operator new ( size_t size ); - void operator delete ( void *pCadaver, size_t size ); + void * operator new ( size_t size, tsFreeList < epicsTimerForC, 0x20 > & ); +#ifdef CXX_PLACEMENT_DELETE + void operator delete ( void *, tsFreeList < epicsTimerForC, 0x20 > & ); +#endif private: epicsTimerCallback pCallBack; void * pPrivate; - static epicsSingleton < tsFreeList < epicsTimerForC, 0x20 > > pFreeList; expireStatus expire ( const epicsTime & currentTime ); epicsTimerForC & operator = ( const epicsTimerForC & ); + void * operator new ( size_t size ); + void operator delete ( void * ); friend class timerQueue; }; @@ -84,6 +89,8 @@ public: double process ( const epicsTime & currentTime ); void show ( unsigned int level ) const; private: + tsFreeList < timer, 0x20 > timerFreeList; + tsFreeList < epicsTimerForC, 0x20 > timerForCFreeList; mutable epicsMutex mutex; epicsEvent cancelBlockingEvent; tsDLList < timer > timerList; @@ -94,6 +101,7 @@ private: timerQueue ( const timerQueue & ); timerQueue & operator = ( const timerQueue & ); friend class timer; + friend struct epicsTimerForC; }; class timerQueueActiveMgrPrivate { // X aCC 655 @@ -117,6 +125,8 @@ public: void show ( unsigned int level ) const; bool sharingOK () const; unsigned threadPriority () const; + void * operator new ( size_t ); + void operator delete ( void * ); private: timerQueue queue; epicsEvent rescheduleEvent; @@ -146,7 +156,7 @@ private: timerQueueActiveMgr & operator = ( const timerQueueActiveMgr & ); }; -extern epicsSingleton < timerQueueActiveMgr > pTimerQueueMgrEPICS; +extern epicsSingleton < timerQueueActiveMgr > timerQueueMgrEPICS; class timerQueuePassive : public epicsTimerQueuePassive { public: @@ -167,8 +177,6 @@ struct epicsTimerQueuePassiveForC : public epicsTimerQueueNotify, public timerQu public: epicsTimerQueuePassiveForC ( epicsTimerQueueRescheduleCallback pCallback, void *pPrivate ); void destroy (); - void * operator new ( size_t size ); - void operator delete ( void *pCadaver, size_t size ); protected: virtual ~epicsTimerQueuePassiveForC (); private: @@ -183,12 +191,11 @@ struct epicsTimerQueueActiveForC : public timerQueueActive, public: epicsTimerQueueActiveForC ( bool okToShare, unsigned priority ); void release (); - void * operator new ( size_t size ); - void operator delete ( void *pCadaver, size_t size ); + void * operator new ( size_t ); + void operator delete ( void * ); protected: virtual ~epicsTimerQueueActiveForC (); private: - static epicsSingleton < tsFreeList < epicsTimerQueueActiveForC, 0x10 > > pFreeList; epicsTimerQueueActiveForC ( const epicsTimerQueueActiveForC & ); epicsTimerQueueActiveForC & operator = ( const epicsTimerQueueActiveForC & ); }; @@ -203,44 +210,42 @@ inline unsigned timerQueueActive::threadPriority () const return thread.getPriority (); } -inline void * timer::operator new ( size_t size ) +inline void * timer::operator new ( size_t size, + tsFreeList < timer, 0x20 > & freeList ) { - return timer::pFreeList->allocate ( size ); + return freeList.allocate ( size ); } -inline void timer::operator delete ( void *pCadaver, size_t size ) +#ifdef CXX_PLACEMENT_DELETE +inline void timer::operator delete ( void * pCadaver, + tsFreeList < timer, 0x20 > & freeList ) { - timer::pFreeList->release ( pCadaver, size ); + freeList.release ( pCadaver ); } +#endif -inline void * epicsTimerForC::operator new ( size_t size ) +inline void * epicsTimerForC::operator new ( size_t size, + tsFreeList < epicsTimerForC, 0x20 > & freeList ) { - return epicsTimerForC::pFreeList->allocate ( size ); + return freeList.allocate ( size ); } -inline void epicsTimerForC::operator delete ( void *pCadaver, size_t size ) +#ifdef CXX_PLACEMENT_DELETE +inline void epicsTimerForC::operator delete ( void * pCadaver, + tsFreeList < epicsTimerForC, 0x20 > & freeList ) { - epicsTimerForC::pFreeList->release ( pCadaver, size ); -} - -inline void * epicsTimerQueuePassiveForC::operator new ( size_t size ) -{ - return epicsTimerQueuePassiveForC::pFreeList->allocate ( size ); -} - -inline void epicsTimerQueuePassiveForC::operator delete ( void *pCadaver, size_t size ) -{ - epicsTimerQueuePassiveForC::pFreeList->release ( pCadaver, size ); + freeList.release ( pCadaver ); } +#endif inline void * epicsTimerQueueActiveForC::operator new ( size_t size ) { - return epicsTimerQueueActiveForC::pFreeList->allocate ( size ); + return ::operator new ( size ); } -inline void epicsTimerQueueActiveForC::operator delete ( void *pCadaver, size_t size ) +inline void epicsTimerQueueActiveForC::operator delete ( void * pCadaver ) { - epicsTimerQueueActiveForC::pFreeList->release ( pCadaver, size ); + ::operator delete ( pCadaver ); } #endif // epicsTimerPrivate_h diff --git a/src/libCom/timer/timerQueue.cpp b/src/libCom/timer/timerQueue.cpp index e1e9d43b4..d5735a913 100644 --- a/src/libCom/timer/timerQueue.cpp +++ b/src/libCom/timer/timerQueue.cpp @@ -157,15 +157,14 @@ double timerQueue::process ( const epicsTime & currentTime ) epicsTimer & timerQueue::createTimer () { - return * new timer ( * this ); + return * new ( this->timerFreeList ) timer ( * this ); } epicsTimerForC & timerQueue::createTimerForC ( epicsTimerCallback pCallback, void *pArg ) { - return * new epicsTimerForC ( *this, pCallback, pArg ); + return * new ( this->timerForCFreeList ) epicsTimerForC ( *this, pCallback, pArg ); } - void timerQueue::show ( unsigned level ) const { epicsGuard < epicsMutex > locker ( this->mutex );