Panda3D
 All Classes Functions Variables Enumerations
neverFreeMemory.cxx
1 // Filename: neverFreeMemory.cxx
2 // Created by: drose (14Jun07)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "neverFreeMemory.h"
16 #include "atomicAdjust.h"
17 #include "memoryHook.h"
18 
19 NeverFreeMemory * TVOLATILE NeverFreeMemory::_global_ptr;
20 
21 // If a page has fewer than this many bytes remaining, never mind
22 // about it.
23 static const size_t min_page_remaining_size = 16;
24 
25 // We always allocate at least this many bytes at a time.
26 static const size_t min_page_size = 128 * 1024; // 128K
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: NeverFreeMemory::Constructor
30 // Access: Private
31 // Description:
32 ////////////////////////////////////////////////////////////////////
33 NeverFreeMemory::
34 NeverFreeMemory() {
35  _total_alloc = 0;
36  _total_used = 0;
37 }
38 
39 ////////////////////////////////////////////////////////////////////
40 // Function: NeverFreeMemory::ns_alloc
41 // Access: Private
42 // Description:
43 ////////////////////////////////////////////////////////////////////
44 void *NeverFreeMemory::
45 ns_alloc(size_t size) {
46  _lock.acquire();
47 
48  // We always allocate integer multiples of this many bytes, to
49  // guarantee this minimum alignment.
50  static const size_t alignment_size = MemoryHook::get_memory_alignment();
51 
52  // Round up to the next alignment_size.
53  size = ((size + alignment_size - 1) / alignment_size) * alignment_size;
54 
55  _total_used += size;
56 
57  // Look for a page that has sufficient space remaining.
58 
59  Pages::iterator pi = _pages.lower_bound(Page(NULL, size));
60  if (pi != _pages.end()) {
61  // Here's a page with enough remaining space.
62  Page page = (*pi);
63  _pages.erase(pi);
64  void *result = page.alloc(size);
65  if (page._remaining >= min_page_remaining_size) {
66  _pages.insert(page);
67  }
68  _lock.release();
69  return result;
70  }
71 
72  // We have to allocate a new page. Allocate at least min_page_size
73  // bytes, and then round that up to the next _page_size bytes.
74  size_t needed_size = max(size, min_page_size);
75  needed_size = memory_hook->round_up_to_page_size(needed_size);
76  void *start = memory_hook->mmap_alloc(needed_size, false);
77  _total_alloc += needed_size;
78 
79  Page page(start, needed_size);
80  void *result = page.alloc(size);
81  if (page._remaining >= min_page_remaining_size) {
82  _pages.insert(page);
83  }
84  _lock.release();
85  return result;
86 }
87 
88 ////////////////////////////////////////////////////////////////////
89 // Function: NeverFreeMemory::make_global_ptr
90 // Access: Private, Static
91 // Description:
92 ////////////////////////////////////////////////////////////////////
93 void NeverFreeMemory::
94 make_global_ptr() {
97  ((void * TVOLATILE &)_global_ptr, (void *)NULL, (void *)ptr);
98  if (result != NULL) {
99  // Someone else got there first.
100  delete ptr;
101  }
102 }
103 
This class is used to allocate bytes of memory from a pool that is never intended to be freed...
size_t round_up_to_page_size(size_t size) const
Rounds the indicated size request up to the next larger multiple of page_size, to qualify it for a ca...
Definition: memoryHook.I:118
virtual void * mmap_alloc(size_t size, bool allow_exec)
Allocates a raw page or pages of memory directly from the OS.
static Pointer compare_and_exchange_ptr(Pointer &mem, Pointer old_value, Pointer new_value)
Atomic compare and exchange.
static size_t get_memory_alignment()
Returns the global memory alignment.
Definition: memoryHook.I:53