Commit c81aa04e authored by James Sutherland's avatar James Sutherland
Browse files

Fix a really tricky but bad bug on the SpatialFieldStore that could lead to...

Fix a really tricky but bad bug on the SpatialFieldStore that could lead to memory corruption in some cases.
parent d9ccef68
...@@ -214,8 +214,10 @@ class SpatialFieldStore { ...@@ -214,8 +214,10 @@ class SpatialFieldStore {
class Pool{ class Pool{
typedef std::stack<T*> FieldQueue; typedef std::stack<T*> FieldQueue;
typedef std::map<size_t,FieldQueue> FQSizeMap; typedef std::map<size_t,FieldQueue> FQSizeMap;
typedef std::map<double*,size_t> FieldSizeMap;
FQSizeMap fqm_; FQSizeMap fqm_;
FieldSizeMap fsm_;
size_t pad_; size_t pad_;
size_t highWater_; size_t highWater_;
...@@ -225,7 +227,7 @@ class SpatialFieldStore { ...@@ -225,7 +227,7 @@ class SpatialFieldStore {
public: public:
static Pool& self(); static Pool& self();
inline T* get( const size_t n ); inline T* get( const size_t n );
inline void put(T*, size_t); inline void put( T* );
inline size_t active() const; inline size_t active() const;
inline size_t total() const{ return highWater_; } inline size_t total() const{ return highWater_; }
}; };
...@@ -608,7 +610,6 @@ get_from_window( const structured::MemoryWindow& window, ...@@ -608,7 +610,6 @@ get_from_window( const structured::MemoryWindow& window,
const unsigned short int deviceIndex ) const unsigned short int deviceIndex )
{ {
typedef typename ValTypeSelector<FieldT,typename boost::is_pod<FieldT>::type>::type AtomicT; typedef typename ValTypeSelector<FieldT,typename boost::is_pod<FieldT>::type>::type AtomicT;
#ifdef ENABLE_THREADS #ifdef ENABLE_THREADS
boost::mutex::scoped_lock lock( get_mutex() ); boost::mutex::scoped_lock lock( get_mutex() );
#endif #endif
...@@ -621,7 +622,8 @@ get_from_window( const structured::MemoryWindow& window, ...@@ -621,7 +622,8 @@ get_from_window( const structured::MemoryWindow& window,
const size_t npts = mw.glob_npts(); const size_t npts = mw.glob_npts();
AtomicT* fnew = Pool<AtomicT>::self().get(npts); AtomicT* fnew = Pool<AtomicT>::self().get(npts);
# ifndef NDEBUG // only zero the field for debug runs. # ifndef NDEBUG // only zero the field for debug runs.
for( size_t i=0; i<npts; ++i ) fnew[i] = 0.0; AtomicT* iftmp = fnew;
for( size_t i=0; i<npts; ++i, ++iftmp ) *iftmp = 0.0;
# endif # endif
return SpatFldPtr<FieldT>( new FieldT(mw,fnew,structured::ExternalStorage), true ); return SpatFldPtr<FieldT>( new FieldT(mw,fnew,structured::ExternalStorage), true );
} }
...@@ -650,14 +652,13 @@ get_from_window( const structured::MemoryWindow& window, ...@@ -650,14 +652,13 @@ get_from_window( const structured::MemoryWindow& window,
template<typename FieldT> template<typename FieldT>
inline inline
void SpatialFieldStore::restore_field(FieldT& field) void SpatialFieldStore::restore_field( FieldT& field )
{ {
# ifdef ENABLE_THREADS # ifdef ENABLE_THREADS
boost::mutex::scoped_lock lock( get_mutex() ); boost::mutex::scoped_lock lock( get_mutex() );
# endif # endif
typedef typename ValTypeSelector<FieldT,typename boost::is_pod<FieldT>::type>::type AtomicT; typedef typename ValTypeSelector<FieldT,typename boost::is_pod<FieldT>::type>::type AtomicT;
Pool<AtomicT>::self().put( field.field_values(), Pool<AtomicT>::self().put( field.field_values() );
field.window_with_ghost().glob_npts() );
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
...@@ -691,18 +692,23 @@ SpatialFieldStore::Pool<T>::self() ...@@ -691,18 +692,23 @@ SpatialFieldStore::Pool<T>::self()
template< typename T > template< typename T >
T* T*
SpatialFieldStore::Pool<T>::get( const size_t n ) SpatialFieldStore::Pool<T>::get( const size_t _n )
{ {
if( pad_==0 ) pad_ = n+n/10; if( pad_==0 ) pad_ = _n/10;
size_t n = _n+pad_;
typename FQSizeMap::iterator ifq = fqm_.lower_bound( n ); typename FQSizeMap::iterator ifq = fqm_.lower_bound( n );
if( ifq == fqm_.end() ){ if( ifq == fqm_.end() ){
ifq = fqm_.insert( ifq, make_pair(n+pad_,FieldQueue()) ); ifq = fqm_.insert( ifq, make_pair(n,FieldQueue()) );
}
else{
n = ifq->first;
} }
T* field = NULL; T* field = NULL;
FieldQueue& fq = ifq->second; FieldQueue& fq = ifq->second;
if( fq.empty() ){ if( fq.empty() ){
++highWater_; ++highWater_;
field = new T[n+pad_]; field = new T[n];
fsm_[field] = n;
} }
else{ else{
field = fq.top(); fq.pop(); field = fq.top(); fq.pop();
...@@ -712,12 +718,12 @@ SpatialFieldStore::Pool<T>::get( const size_t n ) ...@@ -712,12 +718,12 @@ SpatialFieldStore::Pool<T>::get( const size_t n )
template< typename T > template< typename T >
void void
SpatialFieldStore::Pool<T>::put( T* t, size_t n ) SpatialFieldStore::Pool<T>::put( T* t )
{ {
const size_t n = fsm_[t];
const typename FQSizeMap::iterator ifq = fqm_.lower_bound( n ); const typename FQSizeMap::iterator ifq = fqm_.lower_bound( n );
assert( ifq != fqm_.end() ); assert( ifq != fqm_.end() );
FieldQueue& fq = ifq->second; ifq->second.push(t);
fq.push( t );
} }
template<typename T> template<typename T>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment