MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WOPool.hpp
1 /*
2  Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef WOPOOL_HPP
19 #define WOPOOL_HPP
20 
21 #include "Pool.hpp"
22 
23 struct WOPage
24 {
25  STATIC_CONST( WOPAGE_WORDS = GLOBAL_PAGE_SIZE_WORDS - 2 );
26 
27  Uint32 m_type_id;
28  Uint32 m_ref_count;
29  Uint32 m_data[WOPAGE_WORDS];
30 };
31 
35 struct WOPool
36 {
37  Record_info m_record_info;
38  WOPage* m_memroot;
39  WOPage* m_current_page;
40  Pool_context m_ctx;
41  Uint32 m_current_page_no;
42  Uint16 m_current_pos;
43  Uint16 m_current_ref_count;
44 public:
45  WOPool();
46 
47  void init(const Record_info& ri, const Pool_context& pc);
48  bool seize(Ptr<void>&);
49  void release(Ptr<void>);
50  void * getPtr(Uint32 i);
51 
52 private:
53  bool seize_new_page(Ptr<void>&);
54  void release_not_current(Ptr<void>);
55 
56  void handle_invalid_release(Ptr<void>) ATTRIBUTE_NORETURN;
57  void handle_invalid_get_ptr(Uint32 i) ATTRIBUTE_NORETURN;
58  void handle_inconsistent_release(Ptr<void>) ATTRIBUTE_NORETURN;
59 };
60 
61 inline
62 bool
63 WOPool::seize(Ptr<void>& ptr)
64 {
65  Uint32 pos = m_current_pos;
66  Uint32 size = m_record_info.m_size;
67  WOPage *pageP = m_current_page;
68  if (likely(pos + size < WOPage::WOPAGE_WORDS))
69  {
70  ptr.i = (m_current_page_no << POOL_RECORD_BITS) + pos;
71  ptr.p = (pageP->m_data + pos);
72  pageP->m_data[pos+m_record_info.m_offset_magic] = ~(Uint32)m_record_info.m_type_id;
73  m_current_pos = pos + size;
74  m_current_ref_count++;
75  return true;
76  }
77 
78  return seize_new_page(ptr);
79 }
80 
81 inline
82 void
83 WOPool::release(Ptr<void> ptr)
84 {
85  Uint32 cur_page = m_current_page_no;
86  Uint32 ptr_page = ptr.i >> POOL_RECORD_BITS;
87  Uint32 *magic_ptr = (((Uint32*)ptr.p)+m_record_info.m_offset_magic);
88  Uint32 magic_val = *magic_ptr;
89 
90  if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
91  {
92  * magic_ptr = 0;
93  if (cur_page == ptr_page)
94  {
95  if (m_current_ref_count == 1)
96  {
97  m_current_pos = 0;
98  }
99  m_current_ref_count--;
100  return;
101  }
102  return release_not_current(ptr);
103  }
104  handle_invalid_release(ptr);
105 }
106 
107 inline
108 void*
109 WOPool::getPtr(Uint32 i)
110 {
111  Uint32 page_no = i >> POOL_RECORD_BITS;
112  Uint32 page_idx = i & POOL_RECORD_MASK;
113  WOPage * page = m_memroot + page_no;
114  Uint32 * record = page->m_data + page_idx;
115  Uint32 magic_val = * (record + m_record_info.m_offset_magic);
116  if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
117  {
118  return record;
119  }
120  handle_invalid_get_ptr(i);
121  return 0; /* purify: deadcode */
122 }
123 
124 #endif