use placement new

This commit is contained in:
Jeff Hill
2002-10-23 22:32:39 +00:00
parent 0b66cd3811
commit 1e976b7eed
5 changed files with 80 additions and 65 deletions

View File

@@ -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 ( ... ) {

View File

@@ -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

View File

@@ -18,6 +18,7 @@
*/
#include <typeinfo>
#include <stdexcept>
#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" );
}

View File

@@ -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

View File

@@ -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 );