Teuchos - Trilinos Tools Package Version of the Day
Teuchos_Workspace.cpp
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include "Teuchos_Workspace.hpp"
00043 
00044 namespace {
00045 Teuchos::RCP<Teuchos::WorkspaceStore>  default_workspace_store(Teuchos::null);
00046 }
00047 
00048 // Global functions
00049 
00050 void Teuchos::set_default_workspace_store( const Teuchos::RCP<WorkspaceStore> &default_workspace_store_in )
00051 {
00052   default_workspace_store = default_workspace_store_in;
00053 }
00054 
00055 Teuchos::RCP<Teuchos::WorkspaceStore> Teuchos::get_default_workspace_store()
00056 {
00057   return default_workspace_store;
00058 }
00059 
00060 void Teuchos::print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out )
00061 {
00062   if( workspace_store ) {
00063     out
00064       << "\n*** Statistics for autmatic array workspace:"
00065       << "\n  Number of megabytes of preallocated workspace                = "
00066       << (workspace_store->num_bytes_total()*1e-6)
00067       << "\n  Number of megabytes needed                                   = "
00068       << (workspace_store->num_max_bytes_needed()*1e-6)
00069       << "\n  Number of allocations using preallocated workspace           = "
00070       << workspace_store->num_static_allocations()
00071       << "\n  Number of dynamic allocations beyond preallocated workspace  = "
00072       << workspace_store->num_dyn_allocations()
00073       << "\n";
00074   }
00075   else {
00076     out
00077       << "\n*** Statistics for autmatic array workspace:"
00078       << "\n  No workspace storage was allocated!\n";
00079   }
00080 }
00081 
00082 namespace Teuchos {
00083 
00084 // WorkspaceStore
00085 
00086 WorkspaceStore::WorkspaceStore(size_t num_bytes)
00087   : workspace_begin_(NULL)
00088   , workspace_end_(NULL)
00089   , curr_ws_ptr_(NULL)
00090   , num_static_allocations_(0)
00091   , num_dyn_allocations_(0)
00092   , num_current_bytes_total_(0)
00093   , num_max_bytes_needed_(0)
00094 {
00095   if(num_bytes)
00096     protected_initialize(num_bytes);
00097 }
00098 
00099 WorkspaceStore::~WorkspaceStore() {
00100   if(workspace_begin_) delete [] workspace_begin_;
00101 }
00102 
00103 void WorkspaceStore::protected_initialize(size_t num_bytes)
00104 {
00105   TEST_FOR_EXCEPTION(
00106     curr_ws_ptr_ != workspace_begin_, std::logic_error
00107     ,"WorkspaceStore::set_workspace_size(...) : Error, "
00108     "You can not reset the workspace size when any RawWorkspace objects "
00109     "are using workspace!" );
00110   if(workspace_begin_) delete [] workspace_begin_;
00111   workspace_begin_        = ::new char[num_bytes];
00112   workspace_end_          = workspace_begin_ + num_bytes;
00113   curr_ws_ptr_            = workspace_begin_;
00114   num_static_allocations_ = 0;
00115   num_dyn_allocations_    = 0;
00116   num_current_bytes_total_= 0;
00117   num_max_bytes_needed_   = 0;
00118 } 
00119 
00120 // RawWorkspace
00121 
00122 RawWorkspace::RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes_in)
00123 {
00124   if(num_bytes_in) {
00125     workspace_store_ = workspace_store;
00126     if( !workspace_store_ || workspace_store_->num_bytes_remaining() < num_bytes_in ) {
00127       workspace_begin_ = ::new char[num_bytes_in];
00128       workspace_end_   = workspace_begin_ + num_bytes_in;
00129       owns_memory_     = true;
00130       if(workspace_store_)
00131         workspace_store_->num_dyn_allocations_++;
00132     }
00133     else {
00134       workspace_begin_ = workspace_store_->curr_ws_ptr_;
00135       workspace_end_   = workspace_begin_ + num_bytes_in;
00136       owns_memory_     = false;
00137       workspace_store_->curr_ws_ptr_ += num_bytes_in;
00138       workspace_store_->num_static_allocations_++;
00139     }
00140   }
00141   else {
00142     workspace_store_ = NULL;
00143     workspace_begin_ = NULL;
00144     workspace_end_   = NULL;
00145     owns_memory_     = false;
00146   }
00147   if(workspace_store_) {
00148     workspace_store_->num_current_bytes_total_ += num_bytes_in;
00149     if( workspace_store_->num_current_bytes_total_ > workspace_store_->num_max_bytes_needed_ )
00150       workspace_store_->num_max_bytes_needed_ = workspace_store_->num_current_bytes_total_;
00151   }
00152 }
00153 
00154 RawWorkspace::~RawWorkspace()
00155 {
00156   if(workspace_store_)
00157     workspace_store_->num_current_bytes_total_ -= this->num_bytes();
00158   if(owns_memory_) {
00159     if(workspace_begin_) delete [] workspace_begin_;
00160   }
00161   else {
00162     if(workspace_store_) {
00163       TEST_FOR_EXCEPTION(
00164         workspace_store_->curr_ws_ptr_ != workspace_end_, std::logic_error
00165         ,"RawWorkspace::~RawWorkspace(...): Error, "
00166         "Invalid usage of RawWorkspace class, corrupted WorspaceStore object!" );
00167       workspace_store_->curr_ws_ptr_ = workspace_begin_;
00168     }
00169   }
00170 }
00171 
00172 #ifdef __PGI // Should not have to define this since it should not be called!
00173 void* RawWorkspace::operator new(size_t)
00174 {
00175   assert(0);
00176   return NULL;
00177 }
00178 #endif
00179 
00180 } // end namespace Teuchos
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines