MPQC  3.0.0-alpha
integralenginepool.hpp
1 //
2 // integralenginepool.hpp
3 //
4 // Copyright (C) 2013 Drew Lewis
5 //
6 // Authors: Drew Lewis
7 // Maintainer: Drew Lewis and Edward Valeev
8 //
9 // This file is part of the MPQC Toolkit.
10 //
11 // The MPQC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The MPQC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the MPQC Toolkit; see the file COPYING.LIB. If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #ifndef MPQC_CHEMISTRY_QC_BASIS_INTEGRALENGINEPOOL_HPP_
29 #define MPQC_CHEMISTRY_QC_BASIS_INTEGRALENGINEPOOL_HPP_
30 
31 #include <pthread.h>
32 #include <mpqc/utility/mutex.hpp>
33 #include <chemistry/qc/basis/integral.h>
34 #include <vector>
35 #include <util/misc/scexception.h>
36 
37 namespace mpqc {
38  namespace TA {
41 
48  template<typename RefEngType>
51  pthread_key_t engine_key_;
52  RefEngType prototype_;
53  // Pointers to the TLS data which will allows us to manually delete them in the constructor.
54  std::vector<void*> tls_ptrs;
55 
56  public:
57 
58  typedef RefEngType engine_type;
59 
64  IntegralEnginePool(const RefEngType engine) :
65  prototype_(engine) {
66  if (pthread_key_create(&engine_key_, nullptr) != 0) // objects will be manually destroyed by the destructor
67  throw sc::SystemException(
68  "IntegralEnginePool::IntegralEnginePool() "
69  "Unable to register thread local storage key. "
70  "Likely due to a limited number of keys.",
71  __FILE__, __LINE__);
72  }
73 
78  /*
79  * The following loop manually calls delete for each TLS RefEngine pointer
80  * since they normally would not be deallocated until madness::Finalize()
81  * this is to avoid what is effectively a memory leak
82  */
83  for(void *ptr : tls_ptrs){ // For all TLS pointers
84  destroy_thread_object(ptr); // destory it
85  }
86 
87  pthread_key_delete(engine_key_);
88 
89  }
90 
96  RefEngType instance() {
97 
98  // Declare a pointer to a sc::Ref<Engine>
99  RefEngType *RefEngine =
100  reinterpret_cast<RefEngType*>(pthread_getspecific(engine_key_));
101 
102  if (RefEngine == nullptr) {
103  RefEngine = new RefEngType;
104 
105  // Get clone of prototype, must lock to ensure nobody else
106  // clones at the same time. As long as number of threads isn't
107  // Super high this should be ok.
108  mutex::global::lock(); // <<< Begin Critical Section
109  *RefEngine = prototype_->clone();
110  mutex::global::unlock(); // <<< End Critical Section
111 
112  // Asign RefEngine to its thread specific partner.
113  pthread_setspecific(engine_key_, RefEngine);
114 
115  // copy the key so that we can manually delete it's data later
116  tls_ptrs.push_back(pthread_getspecific(engine_key_));
117 
118  }
119 
120  return *RefEngine;
121 
122  }
123 
124  private:
126  static void destroy_thread_object(void* p) {
127  RefEngType* ptr = reinterpret_cast<RefEngType*>(p);
128  delete ptr;
129  ptr = nullptr;
130  }
131 
136  IntegralEnginePool(const IntegralEnginePool &) = delete;
137  IntegralEnginePool& operator=(const IntegralEnginePool &) = delete;
138 
139  };
140 // IntegralEnginePool
141 
142  }// namespace TA
143 } // namespace mpqc
145 
146 #endif /* MPQC_CHEMISTRY_QC_BASIS_INTEGRALENGINEPOOL_HPP_ */
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37
mpqc::TA::IntegralEnginePool::IntegralEnginePool
IntegralEnginePool(const RefEngType engine)
IntegralEnginePool constructor it takes a sc::Ref<sc::IntegralEngine> and sets that as the prototype ...
Definition: integralenginepool.hpp:64
mpqc::TA::IntegralEnginePool
IntegralEnginePool is a class that will take a Ref<Engine> as a prototype and then clone it multiple ...
Definition: integralenginepool.hpp:49
sc::SystemException
This is thrown when a system problem occurs.
Definition: scexception.h:194
mpqc::TA::IntegralEnginePool::instance
RefEngType instance()
Function that returns a clone of the prototype engine.
Definition: integralenginepool.hpp:96
mpqc::TA::IntegralEnginePool::~IntegralEnginePool
~IntegralEnginePool()
Delete the Engines that we allocated for TLS.
Definition: integralenginepool.hpp:77

Generated at Sun Jan 26 2020 23:23:57 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.