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
00041
00050
00052
00070 void set_default_workspace_store( const Teuchos::RefCountPtr<WorkspaceStore> &default_workspace_store );
00071
00073
00075 Teuchos::RefCountPtr<WorkspaceStore> get_default_workspace_store();
00076
00078
00085 void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out );
00086
00088
00092 class RawWorkspace {
00093 public:
00095 friend class WorkspaceStore;
00097
00119 RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes);
00121 ~RawWorkspace();
00123 size_t num_bytes() const;
00125 char* workspace_ptr();
00127 const char* workspace_ptr() const;
00128 private:
00129 WorkspaceStore *workspace_store_;
00130 char *workspace_begin_;
00131 char *workspace_end_;
00132 bool owns_memory_;
00133
00134
00135 RawWorkspace();
00136 RawWorkspace(const RawWorkspace&);
00137 RawWorkspace& operator=(const RawWorkspace&);
00138 static void* operator new(size_t);
00139 static void operator delete(void*);
00140 };
00141
00143
00167 template<class T>
00168 class Workspace {
00169 public:
00171
00202 Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors = true);
00204
00207 ~Workspace();
00209 size_t size() const;
00211
00217 T& operator[](size_t i);
00219
00225 const T& operator[](size_t i) const;
00226 private:
00227 RawWorkspace raw_workspace_;
00228 bool call_constructors_;
00229
00230 Workspace();
00231 Workspace(const RawWorkspace&);
00232 Workspace& operator=(const RawWorkspace&);
00233 static void* operator new(size_t);
00234 static void operator delete(void*);
00235 };
00236
00238
00249 class WorkspaceStore {
00250 public:
00252 friend class RawWorkspace;
00254 ~WorkspaceStore();
00256
00258 size_t num_bytes_total() const;
00260
00262 size_t num_bytes_remaining() const;
00264
00269 int num_static_allocations() const;
00271
00276 int num_dyn_allocations() const;
00278
00281 size_t num_current_bytes_total();
00283
00286 size_t num_max_bytes_needed() const;
00287 protected:
00289 WorkspaceStore(size_t num_bytes);
00291 void protected_initialize(size_t num_bytes);
00292 private:
00293 char *workspace_begin_;
00294
00295 char *workspace_end_;
00296
00297 char *curr_ws_ptr_;
00298
00299 int num_static_allocations_;
00300
00301 int num_dyn_allocations_;
00302
00303
00304 size_t num_current_bytes_total_;
00305 size_t num_max_bytes_needed_;
00306
00307 WorkspaceStore(const WorkspaceStore&);
00308 WorkspaceStore& operator=(const WorkspaceStore&);
00309 };
00310
00312
00319 class WorkspaceStoreInitializeable
00320 : public WorkspaceStore
00321 {
00322 public:
00324
00327 WorkspaceStoreInitializeable(size_t num_bytes = 0);
00329
00335 void initialize(size_t num_bytes);
00336 };
00337
00339
00340
00341
00342
00343 template<class T>
00344 inline
00345 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors)
00346 : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors)
00347 {
00348 if(call_constructors_) {
00349 char* raw_ptr = raw_workspace_.workspace_ptr();
00350 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00351 ::new (raw_ptr) T();
00352 }
00353 }
00354
00355 template<class T>
00356 inline
00357 Workspace<T>::~Workspace()
00358 {
00359 if(call_constructors_) {
00360 const size_t num_elements = this->size();
00361 char* raw_ptr = raw_workspace_.workspace_ptr();
00362 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00363 reinterpret_cast<T*>(raw_ptr)->~T();
00364 }
00365 }
00366
00367 template<class T>
00368 inline
00369 size_t Workspace<T>::size() const
00370 {
00371 return raw_workspace_.num_bytes() / sizeof(T);
00372 }
00373
00374 template<class T>
00375 inline
00376 T& Workspace<T>::operator[](size_t i)
00377 {
00378 #ifdef _DEBUG
00379 TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" );
00380 #endif
00381 return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i];
00382 }
00383
00384 template<class T>
00385 inline
00386 const T& Workspace<T>::operator[](size_t i) const
00387 {
00388 return const_cast<Workspace<T>*>(this)->operator[](i);
00389 }
00390
00391 #ifdef __PGI // Should not have to define this but pgCC is complaining!
00392 template<class T>
00393 inline
00394 void* Workspace<T>::operator new(size_t)
00395 {
00396 assert(0);
00397 return NULL;
00398 }
00399 #endif
00400
00401
00402 template<class T>
00403 inline
00404 void Workspace<T>::operator delete(void*)
00405 {
00406 assert(0);
00407 }
00408
00409
00410
00411
00412 inline
00413 size_t WorkspaceStore::num_bytes_total() const
00414 {
00415 return workspace_end_ - workspace_begin_;
00416 }
00417
00418 inline
00419 size_t WorkspaceStore::num_bytes_remaining() const
00420 {
00421 return workspace_end_ - curr_ws_ptr_;
00422 }
00423
00424 inline
00425 int WorkspaceStore::num_static_allocations() const
00426 {
00427 return num_static_allocations_;
00428 }
00429
00430 inline
00431 int WorkspaceStore::num_dyn_allocations() const
00432 {
00433 return num_dyn_allocations_;
00434 }
00435
00436 inline
00437 size_t WorkspaceStore::num_current_bytes_total()
00438 {
00439 return num_current_bytes_total_;
00440 }
00441
00442 inline
00443 size_t WorkspaceStore::num_max_bytes_needed() const
00444 {
00445 return num_max_bytes_needed_;
00446 }
00447
00448
00449
00450
00451 inline
00452 WorkspaceStoreInitializeable::WorkspaceStoreInitializeable(size_t num_bytes)
00453 : WorkspaceStore(num_bytes)
00454 {}
00455
00456 inline
00457 void WorkspaceStoreInitializeable::initialize(size_t num_bytes)
00458 {
00459 protected_initialize(num_bytes);
00460 }
00461
00462
00463
00464
00465 inline
00466 size_t RawWorkspace::num_bytes() const
00467 {
00468 return workspace_end_ - workspace_begin_;
00469 }
00470
00471 inline
00472 char* RawWorkspace::workspace_ptr()
00473 {
00474 return workspace_begin_;
00475 }
00476
00477 inline
00478 const char* RawWorkspace::workspace_ptr() const
00479 {
00480 return workspace_begin_;
00481 }
00482
00483
00484 inline
00485 void RawWorkspace::operator delete(void*)
00486 {
00487 assert(0);
00488 }
00489
00490 }
00491
00492 #endif // TEUCHOS_WORKSPACE_HPP