00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "neverFreeMemory.h"
00016 #include "atomicAdjust.h"
00017 #include "memoryHook.h"
00018
00019 NeverFreeMemory * TVOLATILE NeverFreeMemory::_global_ptr;
00020
00021
00022
00023 static const size_t min_page_remaining_size = 16;
00024
00025
00026 static const size_t min_page_size = 128 * 1024;
00027
00028
00029
00030
00031
00032
00033 NeverFreeMemory::
00034 NeverFreeMemory() {
00035 _total_alloc = 0;
00036 _total_used = 0;
00037 }
00038
00039
00040
00041
00042
00043
00044 void *NeverFreeMemory::
00045 ns_alloc(size_t size) {
00046 _lock.acquire();
00047
00048
00049
00050 static const size_t alignment_size = MemoryHook::get_memory_alignment();
00051
00052
00053 size = ((size + alignment_size - 1) / alignment_size) * alignment_size;
00054
00055 _total_used += size;
00056
00057
00058
00059 Pages::iterator pi = _pages.lower_bound(Page(NULL, size));
00060 if (pi != _pages.end()) {
00061
00062 Page page = (*pi);
00063 _pages.erase(pi);
00064 void *result = page.alloc(size);
00065 if (page._remaining >= min_page_remaining_size) {
00066 _pages.insert(page);
00067 }
00068 _lock.release();
00069 return result;
00070 }
00071
00072
00073
00074 size_t needed_size = max(size, min_page_size);
00075 needed_size = memory_hook->round_up_to_page_size(needed_size);
00076 void *start = memory_hook->mmap_alloc(needed_size, false);
00077 _total_alloc += needed_size;
00078
00079 Page page(start, needed_size);
00080 void *result = page.alloc(size);
00081 if (page._remaining >= min_page_remaining_size) {
00082 _pages.insert(page);
00083 }
00084 _lock.release();
00085 return result;
00086 }
00087
00088
00089
00090
00091
00092
00093 void NeverFreeMemory::
00094 make_global_ptr() {
00095 NeverFreeMemory *ptr = new NeverFreeMemory;
00096 void *result = AtomicAdjust::compare_and_exchange_ptr
00097 ((void * TVOLATILE &)_global_ptr, (void *)NULL, (void *)ptr);
00098 if (result != NULL) {
00099
00100 delete ptr;
00101 }
00102 }
00103