00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef TEUCHOS_WORKSPACE_HPP
00030 #define TEUCHOS_WORKSPACE_HPP
00031
00032 #include "Teuchos_RefCountPtr.hpp"
00033 #include "Teuchos_TestForException.hpp"
00034
00035 namespace Teuchos {
00036
00037 class WorkspaceStore;
00038 class RawWorkspace;
00039
00049
00068 void set_default_workspace_store( const Teuchos::RefCountPtr<WorkspaceStore> &default_workspace_store );
00069
00072 Teuchos::RefCountPtr<WorkspaceStore> get_default_workspace_store();
00073
00081 void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out );
00082
00087 class RawWorkspace {
00088 public:
00090 friend class WorkspaceStore;
00113 RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes);
00115 ~RawWorkspace();
00117 size_t num_bytes() const;
00119 char* workspace_ptr();
00121 const char* workspace_ptr() const;
00122 private:
00123 WorkspaceStore *workspace_store_;
00124 char *workspace_begin_;
00125 char *workspace_end_;
00126 bool owns_memory_;
00127
00128
00129 RawWorkspace();
00130 RawWorkspace(const RawWorkspace&);
00131 RawWorkspace& operator=(const RawWorkspace&);
00132 static void* operator new(size_t);
00133 static void operator delete(void*);
00134 };
00135
00160 template<class T>
00161 class Workspace {
00162 public:
00194 Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors = true);
00198 ~Workspace();
00200 size_t size() const;
00207 T& operator[](size_t i);
00214 const T& operator[](size_t i) const;
00215 private:
00216 RawWorkspace raw_workspace_;
00217 bool call_constructors_;
00218
00219 Workspace();
00220 Workspace(const RawWorkspace&);
00221 Workspace& operator=(const RawWorkspace&);
00222 static void* operator new(size_t);
00223 static void operator delete(void*);
00224 };
00225
00237 class WorkspaceStore {
00238 public:
00240 friend class RawWorkspace;
00242 ~WorkspaceStore();
00245 size_t num_bytes_total() const;
00248 size_t num_bytes_remaining() const;
00254 int num_static_allocations() const;
00260 int num_dyn_allocations() const;
00264 size_t num_current_bytes_total();
00268 size_t num_max_bytes_needed() const;
00269 protected:
00271 WorkspaceStore(size_t num_bytes);
00273 void protected_initialize(size_t num_bytes);
00274 private:
00275 char *workspace_begin_;
00276
00277 char *workspace_end_;
00278
00279 char *curr_ws_ptr_;
00280
00281 int num_static_allocations_;
00282
00283 int num_dyn_allocations_;
00284
00285
00286 size_t num_current_bytes_total_;
00287 size_t num_max_bytes_needed_;
00288
00289 WorkspaceStore(const WorkspaceStore&);
00290 WorkspaceStore& operator=(const WorkspaceStore&);
00291 };
00292
00300 class WorkspaceStoreInitializeable
00301 : public WorkspaceStore
00302 {
00303 public:
00307 WorkspaceStoreInitializeable(size_t num_bytes = 0);
00314 void initialize(size_t num_bytes);
00315 };
00316
00318
00319
00320
00321
00322 template<class T>
00323 inline
00324 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors)
00325 : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors)
00326 {
00327 if(call_constructors_) {
00328 char* raw_ptr = raw_workspace_.workspace_ptr();
00329 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00330 ::new (raw_ptr) T();
00331 }
00332 }
00333
00334 template<class T>
00335 inline
00336 Workspace<T>::~Workspace()
00337 {
00338 if(call_constructors_) {
00339 const size_t num_elements = this->size();
00340 char* raw_ptr = raw_workspace_.workspace_ptr();
00341 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00342 reinterpret_cast<T*>(raw_ptr)->~T();
00343 }
00344 }
00345
00346 template<class T>
00347 inline
00348 size_t Workspace<T>::size() const
00349 {
00350 return raw_workspace_.num_bytes() / sizeof(T);
00351 }
00352
00353 template<class T>
00354 inline
00355 T& Workspace<T>::operator[](size_t i)
00356 {
00357 #ifdef _DEBUG
00358 TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" );
00359 #endif
00360 return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i];
00361 }
00362
00363 template<class T>
00364 inline
00365 const T& Workspace<T>::operator[](size_t i) const
00366 {
00367 return const_cast<Workspace<T>*>(this)->operator[](i);
00368 }
00369
00370 #ifdef __PGI // Should not have to define this but pgCC is complaining!
00371 template<class T>
00372 inline
00373 void* Workspace<T>::operator new(size_t)
00374 {
00375 assert(0);
00376 return NULL;
00377 }
00378 #endif
00379
00380
00381 template<class T>
00382 inline
00383 void Workspace<T>::operator delete(void*)
00384 {
00385 assert(0);
00386 }
00387
00388
00389
00390
00391 inline
00392 size_t WorkspaceStore::num_bytes_total() const
00393 {
00394 return workspace_end_ - workspace_begin_;
00395 }
00396
00397 inline
00398 size_t WorkspaceStore::num_bytes_remaining() const
00399 {
00400 return workspace_end_ - curr_ws_ptr_;
00401 }
00402
00403 inline
00404 int WorkspaceStore::num_static_allocations() const
00405 {
00406 return num_static_allocations_;
00407 }
00408
00409 inline
00410 int WorkspaceStore::num_dyn_allocations() const
00411 {
00412 return num_dyn_allocations_;
00413 }
00414
00415 inline
00416 size_t WorkspaceStore::num_current_bytes_total()
00417 {
00418 return num_current_bytes_total_;
00419 }
00420
00421 inline
00422 size_t WorkspaceStore::num_max_bytes_needed() const
00423 {
00424 return num_max_bytes_needed_;
00425 }
00426
00427
00428
00429
00430 inline
00431 WorkspaceStoreInitializeable::WorkspaceStoreInitializeable(size_t num_bytes)
00432 : WorkspaceStore(num_bytes)
00433 {}
00434
00435 inline
00436 void WorkspaceStoreInitializeable::initialize(size_t num_bytes)
00437 {
00438 protected_initialize(num_bytes);
00439 }
00440
00441
00442
00443
00444 inline
00445 size_t RawWorkspace::num_bytes() const
00446 {
00447 return workspace_end_ - workspace_begin_;
00448 }
00449
00450 inline
00451 char* RawWorkspace::workspace_ptr()
00452 {
00453 return workspace_begin_;
00454 }
00455
00456 inline
00457 const char* RawWorkspace::workspace_ptr() const
00458 {
00459 return workspace_begin_;
00460 }
00461
00462
00463 inline
00464 void RawWorkspace::operator delete(void*)
00465 {
00466 assert(0);
00467 }
00468
00469 }
00470
00471 #endif // TEUCHOS_WORKSPACE_HPP