bitmap_allocator.cc revision 1.1.1.7
1// Bitmap Allocator. Out of line function definitions. -*- C++ -*-
2
3// Copyright (C) 2004-2018 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25#include <ext/bitmap_allocator.h>
26
27namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
28{
29_GLIBCXX_BEGIN_NAMESPACE_VERSION
30
31  namespace __detail
32  {
33    template class __mini_vector<
34      std::pair<bitmap_allocator<char>::_Alloc_block*,
35		bitmap_allocator<char>::_Alloc_block*> >;
36
37    template class __mini_vector<
38      std::pair<bitmap_allocator<wchar_t>::_Alloc_block*,
39		bitmap_allocator<wchar_t>::_Alloc_block*> >;
40
41    template class __mini_vector<size_t*>;
42
43    template size_t** __lower_bound(size_t**, size_t**, size_t const&,
44				    free_list::_LT_pointer_compare);
45  }
46
47  size_t*
48  free_list::
49  _M_get(size_t __sz) throw(std::bad_alloc)
50  {
51#if defined __GTHREADS
52    __mutex_type& __bfl_mutex = _M_get_mutex();
53    __bfl_mutex.lock();
54#endif
55    const vector_type& __free_list = _M_get_free_list();
56    using __gnu_cxx::__detail::__lower_bound;
57    iterator __tmp = __lower_bound(__free_list.begin(), __free_list.end(),
58				   __sz, _LT_pointer_compare());
59
60    if (__tmp == __free_list.end() || !_M_should_i_give(**__tmp, __sz))
61      {
62	// We release the lock here, because operator new is
63	// guaranteed to be thread-safe by the underlying
64	// implementation.
65#if defined __GTHREADS
66	__bfl_mutex.unlock();
67#endif
68	// Try twice to get the memory: once directly, and the 2nd
69	// time after clearing the free list. If both fail, then throw
70	// std::bad_alloc().
71	int __ctr = 2;
72	while (__ctr)
73	  {
74	    size_t* __ret = 0;
75	    --__ctr;
76	    __try
77	      {
78		__ret = reinterpret_cast<size_t*>
79		  (::operator new(__sz + sizeof(size_t)));
80	      }
81	    __catch(const std::bad_alloc&)
82	      {
83		this->_M_clear();
84	      }
85	    if (!__ret)
86	      continue;
87	    *__ret = __sz;
88	    return __ret + 1;
89	  }
90	std::__throw_bad_alloc();
91      }
92    else
93      {
94	size_t* __ret = *__tmp;
95	_M_get_free_list().erase(__tmp);
96#if defined __GTHREADS
97	__bfl_mutex.unlock();
98#endif
99	return __ret + 1;
100      }
101  }
102
103  void
104  free_list::
105  _M_clear()
106  {
107#if defined __GTHREADS
108    __gnu_cxx::__scoped_lock __bfl_lock(_M_get_mutex());
109#endif
110    vector_type& __free_list = _M_get_free_list();
111    iterator __iter = __free_list.begin();
112    while (__iter != __free_list.end())
113      {
114	::operator delete((void*)*__iter);
115	++__iter;
116      }
117    __free_list.clear();
118  }
119
120  // Instantiations.
121  template class bitmap_allocator<char>;
122  template class bitmap_allocator<wchar_t>;
123
124_GLIBCXX_END_NAMESPACE_VERSION
125} // namespace
126