CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sqlitemem.cc
Go to the documentation of this file.
1 
5 #define __STDC_FORMAT_MACROS
6 
7 
8 #include "sqlitemem.h"
9 
10 #include <cassert>
11 #include <cstddef>
12 #include <cstring>
13 #include <new>
14 
15 #include "malloc_arena.h"
16 #include "util/concurrency.h"
17 #include "util/exception.h"
18 #include "util/smalloc.h"
19 
20 using namespace std; // NOLINT
21 
22 
24  for (unsigned i = 0; i < kNoBitmaps; ++i) {
25  const int bit_set = ffs(freemap_[i]);
26  if (bit_set != 0) {
27  freemap_[i] &= ~(1 << (bit_set - 1)); // set bit to zero
28  const int nbuffer = i * sizeof(int) * 8 + bit_set - 1;
29  return reinterpret_cast<char *>(arena_) + nbuffer * kBufferSize;
30  }
31  }
32  return NULL;
33 }
34 
35 
37  for (unsigned i = 0; i < kNoBitmaps; ++i) {
38  if (~freemap_[i] != 0)
39  return false;
40  }
41  return true;
42 }
43 
44 
46  if ((buffer == NULL) || (buffer < arena_))
47  return false;
48  return (static_cast<uint64_t>((reinterpret_cast<char *>(buffer)
49  - reinterpret_cast<char *>(arena_)))
50  < kArenaSize);
51 }
52 
53 
55  : arena_(sxmmap(kArenaSize)) {
56  // All buffers unused, i.e. all bits set
57  memset(freemap_, 0xFF, kNoBitmaps * sizeof(int));
58 }
59 
60 
62  sxunmap(arena_, kArenaSize);
63 }
64 
65 
67  assert(buffer >= arena_);
68  const ptrdiff_t nbuffer =
69  (reinterpret_cast<char *>(buffer) - reinterpret_cast<char *>(arena_)) /
71  assert(static_cast<uint64_t>(nbuffer) < kBuffersPerArena);
72  const int nfreemap = nbuffer / (sizeof(int) * 8);
73  freemap_[nfreemap] |= 1 << (nbuffer % (sizeof(int) * 8));
74 }
75 
76 
77 //------------------------------------------------------------------------------
78 
79 
81 
82 
87  return instance_->GetMemory(size);
88 }
89 
90 
95 
96 
100 void *SqliteMemoryManager::xRealloc(void *ptr, int new_size) {
101  const int old_size = xSize(ptr);
102  if (old_size >= new_size)
103  return ptr;
104 
105  void *new_ptr = xMalloc(new_size);
106  memcpy(new_ptr, ptr, old_size);
107  xFree(ptr);
108  return new_ptr;
109 }
110 
111 
116  return instance_->GetMemorySize(ptr);
117 }
118 
119 
120 int SqliteMemoryManager::xRoundup(int size) { return RoundUp8(size); }
121 
122 
123 int SqliteMemoryManager::xInit(void *app_data __attribute__((unused))) {
124  return SQLITE_OK;
125 }
126 
127 
128 void SqliteMemoryManager::xShutdown(void *app_data __attribute__((unused))) { }
129 
130 
132  if (assigned_)
133  return;
134  int retval;
135 
136  retval = sqlite3_config(SQLITE_CONFIG_PAGECACHE, page_cache_memory_,
138  assert(retval == SQLITE_OK);
139 
140  retval = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &sqlite3_mem_vanilla_);
141  assert(retval == SQLITE_OK);
142  retval = sqlite3_config(SQLITE_CONFIG_MALLOC, &mem_methods_);
143  assert(retval == SQLITE_OK);
144 
145  assigned_ = true;
146 }
147 
148 
154  const MutexLockGuard lock_guard(lock_);
155 
156  void *buffer = GetLookasideBuffer();
157  assert(buffer != NULL);
158  const int retval =
159  sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, buffer,
161  assert(retval == SQLITE_OK);
162  return buffer;
163 }
164 
165 
167  delete instance_;
168  instance_ = NULL;
169 }
170 
171 
176  void *result;
177  vector<LookasideBufferArena *>::reverse_iterator
178  reverse_iter = lookaside_buffer_arenas_.rbegin();
179  const vector<LookasideBufferArena *>::reverse_iterator i_rend =
181  for (; reverse_iter != i_rend; ++reverse_iter) {
182  result = (*reverse_iter)->GetBuffer();
183  if (result != NULL)
184  return result;
185  }
186 
187  LookasideBufferArena *new_arena = new LookasideBufferArena();
188  lookaside_buffer_arenas_.push_back(new_arena);
189  return new_arena->GetBuffer();
190 }
191 
192 
195 }
196 
197 
202  void *p = malloc_arenas_[idx_last_arena_]->Malloc(size);
203  if (p != NULL)
204  return p;
205  const unsigned N = malloc_arenas_.size();
206  for (unsigned i = 0; i < N; ++i) {
207  p = malloc_arenas_[i]->Malloc(size);
208  if (p != NULL) {
209  idx_last_arena_ = i;
210  return p;
211  }
212  }
213  idx_last_arena_ = N;
215  malloc_arenas_.push_back(M);
216  p = M->Malloc(size);
217  assert(p != NULL);
218  return p;
219 }
220 
221 
223  : assigned_(false)
225  , idx_last_arena_(0) {
226  memset(&sqlite3_mem_vanilla_, 0, sizeof(sqlite3_mem_vanilla_));
227  const int retval = pthread_mutex_init(&lock_, NULL);
228  assert(retval == 0);
229 
231  malloc_arenas_.push_back(new MallocArena(kArenaSize));
232 
233  memset(&mem_methods_, 0, sizeof(mem_methods_));
234  mem_methods_.xMalloc = xMalloc;
235  mem_methods_.xFree = xFree;
236  mem_methods_.xRealloc = xRealloc;
237  mem_methods_.xSize = xSize;
238  mem_methods_.xRoundup = xRoundup;
239  mem_methods_.xInit = xInit;
240  mem_methods_.xShutdown = xShutdown;
241  mem_methods_.pAppData = NULL;
242 }
243 
244 
249  if (assigned_) {
250  // Reset sqlite to default values
251  int retval;
252  retval = sqlite3_config(SQLITE_CONFIG_PAGECACHE, NULL, 0, 0);
253  assert(retval == SQLITE_OK);
254  retval = sqlite3_config(SQLITE_CONFIG_MALLOC, &sqlite3_mem_vanilla_);
255  assert(retval == SQLITE_OK);
256  }
257 
259  for (unsigned i = 0; i < lookaside_buffer_arenas_.size(); ++i)
260  delete lookaside_buffer_arenas_[i];
261  for (unsigned i = 0; i < malloc_arenas_.size(); ++i)
262  delete malloc_arenas_[i];
263  pthread_mutex_destroy(&lock_);
264 }
265 
266 
273  const unsigned N = lookaside_buffer_arenas_.size();
274  for (unsigned i = 0; i < N; ++i) {
275  if (lookaside_buffer_arenas_[i]->Contains(buffer)) {
276  lookaside_buffer_arenas_[i]->PutBuffer(buffer);
277  if ((N > 1) && lookaside_buffer_arenas_[i]->IsEmpty()) {
278  delete lookaside_buffer_arenas_[i];
280  }
281  return;
282  }
283  }
284  PANIC(NULL);
285 }
286 
287 
293  M->Free(ptr);
294  const unsigned N = malloc_arenas_.size();
295  if ((N > 1) && M->IsEmpty()) {
296  for (unsigned i = 0; i < N; ++i) {
297  if (malloc_arenas_[i] == M) {
298  delete malloc_arenas_[i];
299  malloc_arenas_.erase(malloc_arenas_.begin() + i);
300  idx_last_arena_ = 0;
301  return;
302  }
303  }
304  PANIC(NULL);
305  }
306 }
307 
308 
313  const MutexLockGuard lock_guard(lock_);
314  PutLookasideBuffer(buffer);
315 }
struct sqlite3_mem_methods sqlite3_mem_vanilla_
Definition: sqlitemem.h:194
static const unsigned kPageCacheSlotSize
Definition: sqlitemem.h:65
static MallocArena * GetMallocArena(void *ptr, unsigned arena_size)
Definition: malloc_arena.h:77
static const unsigned kPageCacheNoSlots
Definition: sqlitemem.h:69
struct sqlite3_mem_methods mem_methods_
Definition: sqlitemem.h:196
const unsigned kBufferSize
Definition: compression.cc:148
static int xInit(void *app_data)
Definition: sqlitemem.cc:123
#define PANIC(...)
Definition: exception.h:29
static int xSize(void *ptr)
Definition: sqlitemem.cc:115
static const unsigned kArenaSize
Definition: sqlitemem.h:157
void * GetLookasideBuffer()
Definition: sqlitemem.cc:175
static void xShutdown(void *app_data)
Definition: sqlitemem.cc:128
assert((mem||(size==0))&&"Out Of Memory")
void PutMemory(void *ptr)
Definition: sqlitemem.cc:291
static void CleanupInstance()
Definition: sqlitemem.cc:166
void AssignGlobalArenas()
Definition: sqlitemem.cc:131
struct cvmcache_object_info __attribute__
Definition: atomic.h:24
int GetMemorySize(void *ptr)
Definition: sqlitemem.cc:193
static const unsigned kLookasideSlotsPerDb
Definition: sqlitemem.h:83
void * GetMemory(int size)
Definition: sqlitemem.cc:201
static const unsigned kPageCacheSize
Definition: sqlitemem.h:73
static SqliteMemoryManager * instance_
Definition: sqlitemem.h:158
static void * xRealloc(void *ptr, int new_size)
Definition: sqlitemem.cc:100
static uint64_t RoundUp8(const uint64_t size)
Definition: smalloc.h:37
unsigned idx_last_arena_
Definition: sqlitemem.h:203
void Free(void *ptr)
Definition: malloc_arena.cc:54
static void xFree(void *ptr)
Definition: sqlitemem.cc:94
pthread_mutex_t lock_
Definition: sqlitemem.h:182
void * page_cache_memory_
Definition: sqlitemem.h:197
static const unsigned kLookasideSlotSize
Definition: sqlitemem.h:79
bool IsEmpty() const
Definition: malloc_arena.h:95
static int xRoundup(int size)
Definition: sqlitemem.cc:120
void * Malloc(const uint32_t size)
Definition: mutex.h:42
void PutLookasideBuffer(void *buffer)
Definition: sqlitemem.cc:272
uint32_t GetSize(void *ptr) const
std::vector< LookasideBufferArena * > lookaside_buffer_arenas_
Definition: sqlitemem.h:198
static void size_t size
Definition: smalloc.h:54
static void * xMalloc(int size)
Definition: sqlitemem.cc:86
void ReleaseLookasideBuffer(void *buffer)
Definition: sqlitemem.cc:312
void * AssignLookasideBuffer(sqlite3 *db)
Definition: sqlitemem.cc:153
std::vector< MallocArena * > malloc_arenas_
Definition: sqlitemem.h:199