Update copyright to LGPL on all files
[dyninst.git] / common / h / singleton_object_pool.h
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 #if !defined(SINGLETON_OBJECT_POOL_H)
32 #define SINGLETON_OBJECT_POOL_H
33
34 #include <boost/pool/pool.hpp>
35 #include <boost/pool/detail/singleton.hpp>
36 #include "pool_allocators.h"
37
38 #include <dyn_detail/boost/shared_ptr.hpp>
39
40 // This is only safe for objects with nothrow constructors...
41 template <typename T, typename Alloc = boost::default_user_allocator_new_delete>
42 class singleton_object_pool
43 {
44  private:
45  struct pool_impl
46  {
47    boost::pool<Alloc> p;
48    pool_impl() : p(sizeof(T), 32) 
49    {
50    }
51  };
52  
53  typedef boost::details::pool::singleton_default<pool_impl> singleton;
54  static std::set<T*> allocated_objects;
55  
56   
57  inline static void free(T* free_me)
58  {
59    singleton::instance().p.free(free_me);
60  }
61  
62  inline static T* malloc() 
63   {
64     return static_cast<T*>(singleton::instance().p.malloc());
65   }
66  public:
67   inline static bool is_from(T* t)
68   {
69     return singleton::instance().p.is_from(t);
70   }
71   
72   static T* construct()
73   {
74     T* const temp = malloc();
75     if(temp == 0) return temp;
76     new(temp) T();
77     return temp;
78   }
79   template <typename A1>
80   static T* construct(const A1& a1)
81   {
82     T* const temp = malloc();
83     if(temp == 0) return temp;
84     new(temp) T(a1);
85     return temp;
86   }
87   template <typename A1, typename A2>
88   static T* construct(const A1& a1, const A2& a2)
89   {
90     T* const temp = malloc();
91     if(temp == 0) return temp;
92     new(temp) T(a1, a2);
93     return temp;
94   }
95   template <typename A1, typename A2, typename A3>
96   static T* construct(const A1& a1, const A2& a2, const A3& a3)
97   {
98     T* const temp = malloc();
99     if(temp == 0) return temp;
100     new(temp) T(a1, a2, a3);
101     return temp;
102   }
103   template <typename A1, typename A2, typename A3, typename A4>
104   static T* construct(const A1& a1, const A2& a2, const A3& a3, const A4& a4)
105   {
106     T* const temp = malloc();
107     if(temp == 0) return temp;
108     new(temp) T(a1, a2, a3, a4);
109     return temp;
110   }
111   template <typename A1, typename A2, typename A3, typename A4, typename A5>
112   static T* construct(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
113   {
114     T* const temp = malloc();
115     if(temp == 0) return temp;
116     new(temp) T(a1, a2, a3, a4, a5);
117     return temp;
118   }
119   inline static void destroy(T* const kill_me)
120   {
121     kill_me->~T();
122     free(kill_me);
123   }
124   
125   
126 };
127
128
129 template <typename T> 
130 struct PoolDestructor
131 {
132   inline void operator()(T* e) 
133   {
134     // We'll see if this kills performance or not...
135     if(singleton_object_pool<T>::is_from(e)) {
136       singleton_object_pool<T>::destroy(e);
137     }
138     
139   }
140 };
141
142 template <typename T> inline
143 dyn_detail::boost::shared_ptr<T> make_shared(T* t)
144 {
145   return dyn_detail::boost::shared_ptr<T>(t, PoolDestructor<T>(), typename unlocked_fast_alloc<T>::type());
146 }
147  
148
149 #endif //!defined(SINGLETON_OBJECT_POOL_H)