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_RCP.hpp"
00033 #include "Teuchos_TestForException.hpp"
00034
00035 namespace Teuchos {
00036
00037 class WorkspaceStore;
00038 class RawWorkspace;
00039
00051
00070 void set_default_workspace_store( const Teuchos::RCP<WorkspaceStore> &default_workspace_store );
00071
00074 Teuchos::RCP<WorkspaceStore> get_default_workspace_store();
00075
00083 void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out );
00084
00089 class RawWorkspace {
00090 public:
00092 friend class WorkspaceStore;
00115 RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes);
00117 ~RawWorkspace();
00119 size_t num_bytes() const;
00121 char* workspace_ptr();
00123 const char* workspace_ptr() const;
00124 private:
00125 WorkspaceStore *workspace_store_;
00126 char *workspace_begin_;
00127 char *workspace_end_;
00128 bool owns_memory_;
00129
00130
00131 RawWorkspace();
00132 RawWorkspace(const RawWorkspace&);
00133 RawWorkspace& operator=(const RawWorkspace&);
00134 static void* operator new(size_t);
00135 static void operator delete(void*);
00136 };
00137
00162 template<class T>
00163 class Workspace {
00164 public:
00196 Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors = true);
00200 ~Workspace();
00202 size_t size() const;
00209 T& operator[](size_t i);
00216 const T& operator[](size_t i) const;
00217 private:
00218 RawWorkspace raw_workspace_;
00219 bool call_constructors_;
00220
00221 Workspace();
00222 Workspace(const RawWorkspace&);
00223 Workspace& operator=(const RawWorkspace&);
00224 static void* operator new(size_t);
00225 static void operator delete(void*);
00226 };
00227
00239 class WorkspaceStore {
00240 public:
00242 friend class RawWorkspace;
00244 ~WorkspaceStore();
00247 size_t num_bytes_total() const;
00250 size_t num_bytes_remaining() const;
00256 int num_static_allocations() const;
00262 int num_dyn_allocations() const;
00266 size_t num_current_bytes_total();
00270 size_t num_max_bytes_needed() const;
00271 protected:
00273 WorkspaceStore(size_t num_bytes);
00275 void protected_initialize(size_t num_bytes);
00276 private:
00277 char *workspace_begin_;
00278
00279 char *workspace_end_;
00280
00281 char *curr_ws_ptr_;
00282
00283 int num_static_allocations_;
00284
00285 int num_dyn_allocations_;
00286
00287
00288 size_t num_current_bytes_total_;
00289 size_t num_max_bytes_needed_;
00290
00291 WorkspaceStore(const WorkspaceStore&);
00292 WorkspaceStore& operator=(const WorkspaceStore&);
00293 };
00294
00302 class WorkspaceStoreInitializeable
00303 : public WorkspaceStore
00304 {
00305 public:
00309 WorkspaceStoreInitializeable(size_t num_bytes = 0);
00316 void initialize(size_t num_bytes);
00317 };
00318
00320
00321
00322
00323
00324 template<class T>
00325 inline
00326 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors)
00327 : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors)
00328 {
00329 if(call_constructors_) {
00330 char* raw_ptr = raw_workspace_.workspace_ptr();
00331 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00332 ::new (raw_ptr) T();
00333 }
00334 }
00335
00336 template<class T>
00337 inline
00338 Workspace<T>::~Workspace()
00339 {
00340 if(call_constructors_) {
00341 const size_t num_elements = this->size();
00342 char* raw_ptr = raw_workspace_.workspace_ptr();
00343 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00344 reinterpret_cast<T*>(raw_ptr)->~T();
00345 }
00346 }
00347
00348 template<class T>
00349 inline
00350 size_t Workspace<T>::size() const
00351 {
00352 return raw_workspace_.num_bytes() / sizeof(T);
00353 }
00354
00355 template<class T>
00356 inline
00357 T& Workspace<T>::operator[](size_t i)
00358 {
00359 #ifdef TEUCHOS_DEBUG
00360 TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" );
00361 #endif
00362 return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i];
00363 }
00364
00365 template<class T>
00366 inline
00367 const T& Workspace<T>::operator[](size_t i) const
00368 {
00369 return const_cast<Workspace<T>*>(this)->operator[](i);
00370 }
00371
00372 #ifdef __PGI // Should not have to define this but pgCC is complaining!
00373 template<class T>
00374 inline
00375 void* Workspace<T>::operator new(size_t)
00376 {
00377 assert(0);
00378 return NULL;
00379 }
00380 #endif
00381
00382
00383 template<class T>
00384 inline
00385 void Workspace<T>::operator delete(void*)
00386 {
00387 assert(0);
00388 }
00389
00390
00391
00392
00393 inline
00394 size_t WorkspaceStore::num_bytes_total() const
00395 {
00396 return workspace_end_ - workspace_begin_;
00397 }
00398
00399 inline
00400 size_t WorkspaceStore::num_bytes_remaining() const
00401 {
00402 return workspace_end_ - curr_ws_ptr_;
00403 }
00404
00405 inline
00406 int WorkspaceStore::num_static_allocations() const
00407 {
00408 return num_static_allocations_;
00409 }
00410
00411 inline
00412 int WorkspaceStore::num_dyn_allocations() const
00413 {
00414 return num_dyn_allocations_;
00415 }
00416
00417 inline
00418 size_t WorkspaceStore::num_current_bytes_total()
00419 {
00420 return num_current_bytes_total_;
00421 }
00422
00423 inline
00424 size_t WorkspaceStore::num_max_bytes_needed() const
00425 {
00426 return num_max_bytes_needed_;
00427 }
00428
00429
00430
00431
00432 inline
00433 WorkspaceStoreInitializeable::WorkspaceStoreInitializeable(size_t num_bytes)
00434 : WorkspaceStore(num_bytes)
00435 {}
00436
00437 inline
00438 void WorkspaceStoreInitializeable::initialize(size_t num_bytes)
00439 {
00440 protected_initialize(num_bytes);
00441 }
00442
00443
00444
00445
00446 inline
00447 size_t RawWorkspace::num_bytes() const
00448 {
00449 return workspace_end_ - workspace_begin_;
00450 }
00451
00452 inline
00453 char* RawWorkspace::workspace_ptr()
00454 {
00455 return workspace_begin_;
00456 }
00457
00458 inline
00459 const char* RawWorkspace::workspace_ptr() const
00460 {
00461 return workspace_begin_;
00462 }
00463
00464
00465 inline
00466 void RawWorkspace::operator delete(void*)
00467 {
00468 assert(0);
00469 }
00470
00471 }
00472
00473 #endif // TEUCHOS_WORKSPACE_HPP