MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ArenaPool.hpp
1 /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 #ifndef ARENA_POOL_HPP
17 #define ARENA_POOL_HPP
18 
19 #include "Pool.hpp"
20 #include "RWPool.hpp"
21 
22 struct ArenaBlock
23 {
24  Uint32 m_magic;
25  union {
26  Uint32 m_next_block;
27  Uint32 nextPool;
28  };
29 
30  Uint32 m_data[1];
31 
32  STATIC_CONST( HeaderSize = 2 );
33 
34  static Uint32 computeBlockSizeInWords(Uint32 datasz) {
35  return 16 * (((datasz + 2) + 8) / 16);
36  }
37 };
38 
39 struct ArenaHead
40 {
41  ArenaHead() {
42  m_first_free = ~(Uint16)0;
43  m_block_size = 0;
44  m_first_block = RNIL;
45  m_current_block = RNIL;
46  m_current_block_ptr = 0;
47  }
48 
49  ArenaBlock * m_current_block_ptr;
50  Uint32 m_first_block;
51  Uint32 m_current_block;
52  Uint16 m_first_free;
53  Uint16 m_block_size;
54 };
55 
56 class ArenaPool; // forward
57 
59 {
60  RWPool m_pool;
61  Uint32 m_block_size;
62  friend class ArenaPool;
63 public:
64  ArenaAllocator() {}
65  void init(Uint32 blockSize, Uint32 type_id, const Pool_context& pc);
66 
67  bool seize(ArenaHead&);
68  void release(ArenaHead&);
69 };
70 
71 class ArenaPool
72 {
73 public:
74  ArenaPool() {}
75 
76  void init(ArenaAllocator*, const Record_info& ri, const Pool_context& pc);
77 
78  bool seize(Ptr<void>&) { assert(false); return false; } // Not implemented...
79 
80  bool seize(ArenaHead&, Ptr<void>&);
81  void release(Ptr<void>);
82  void * getPtr(Uint32 i);
83 
84 private:
85  void handle_invalid_release(Ptr<void>) ATTRIBUTE_NORETURN;
86 
87  Record_info m_record_info;
88  ArenaAllocator * m_allocator;
89 };
90 
92 {
93  ArenaHead & m_head;
94  ArenaPool & m_pool;
95 public:
97  : m_head(head), m_pool(pool) {}
98 
99  bool seize(Ptr<void> & ptr) { return m_pool.seize(m_head, ptr); }
100  void release(Ptr<void> ptr) { m_pool.release(ptr); }
101  void * getPtr(Uint32 i) { return m_pool.getPtr(i); }
102 };
103 
104 inline
105 void*
106 ArenaPool::getPtr(Uint32 i)
107 {
108  return m_allocator->m_pool.getPtr(m_record_info, i);
109 }
110 
111 inline
112 void
113 ArenaPool::release(Ptr<void> ptr)
114 {
115  Uint32 * record_ptr = static_cast<Uint32*>(ptr.p);
116  Uint32 off = m_record_info.m_offset_magic;
117  Uint32 type_id = m_record_info.m_type_id;
118  Uint32 magic_val = * (record_ptr + off);
119 
120  if (likely(magic_val == ~type_id))
121  {
122  * (record_ptr + off) = 0;
123  return;
124  }
125  handle_invalid_release(ptr);
126 }
127 
128 #endif