Panda3D

neverFreeMemory.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file neverFreeMemory.cxx
10 * @author drose
11 * @date 2007-06-14
12 */
13
14 #include "neverFreeMemory.h"
15 #include "atomicAdjust.h"
16 #include "memoryHook.h"
17
18 NeverFreeMemory * TVOLATILE NeverFreeMemory::_global_ptr;
19
20 // If a page has fewer than this many bytes remaining, never mind about it.
21 static const size_t min_page_remaining_size = 16;
22
23 // We always allocate at least this many bytes at a time.
24 static const size_t min_page_size = 128 * 1024; // 128K
25
26 /**
27 *
28 */
29 NeverFreeMemory::
30 NeverFreeMemory() {
31 _total_alloc = 0;
32 _total_used = 0;
33 }
34
35 /**
36 *
37 */
38 void *NeverFreeMemory::
39 ns_alloc(size_t size) {
40 _lock.lock();
41
42 //NB: we no longer do alignment here. The only class that uses this is
43 // DeletedBufferChain, and we can do the alignment potentially more
44 // efficiently there since we don't end up overallocating as much.
45 _total_used += size;
46
47 // Look for a page that has sufficient space remaining.
48
49 Pages::iterator pi = _pages.lower_bound(Page(nullptr, size));
50 if (pi != _pages.end()) {
51 // Here's a page with enough remaining space.
52 Page page = (*pi);
53 _pages.erase(pi);
54 void *result = page.alloc(size);
55 if (page._remaining >= min_page_remaining_size) {
56 _pages.insert(page);
57 }
58 _lock.unlock();
59 return result;
60 }
61
62 // We have to allocate a new page. Allocate at least min_page_size bytes,
63 // and then round that up to the next _page_size bytes.
64 size_t needed_size = std::max(size, min_page_size);
65 needed_size = memory_hook->round_up_to_page_size(needed_size);
66 void *start = memory_hook->mmap_alloc(needed_size, false);
67 _total_alloc += needed_size;
68
69 Page page(start, needed_size);
70 void *result = page.alloc(size);
71 if (page._remaining >= min_page_remaining_size) {
72 _pages.insert(page);
73 }
74 _lock.unlock();
75 return result;
76 }
77
78 /**
79 *
80 */
81 void NeverFreeMemory::
82 make_global_ptr() {
83 NeverFreeMemory *ptr = new NeverFreeMemory;
84 void *result = AtomicAdjust::compare_and_exchange_ptr
85 ((void * TVOLATILE &)_global_ptr, nullptr, (void *)ptr);
86 if (result != nullptr) {
87 // Someone else got there first.
88 delete ptr;
89 }
90 }
atomicAdjust.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AtomicAdjustDummyImpl::compare_and_exchange_ptr
static Pointer compare_and_exchange_ptr(Pointer &mem, Pointer old_value, Pointer new_value)
Atomic compare and exchange.
Definition: atomicAdjustDummyImpl.I:109
MemoryHook::mmap_alloc
virtual void * mmap_alloc(size_t size, bool allow_exec)
Allocates a raw page or pages of memory directly from the OS.
Definition: memoryHook.cxx:512
MemoryHook::round_up_to_page_size
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:51
NeverFreeMemory
This class is used to allocate bytes of memory from a pool that is never intended to be freed.
Definition: neverFreeMemory.h:32
memoryHook.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
neverFreeMemory.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.