vnl_alloc.cxx
Go to the documentation of this file.
1 // This is core/vnl/vnl_alloc.cxx
2 
3 #include <cstring>
4 #include <cstdlib>
5 #include <iostream>
6 #include "vnl_alloc.h"
7 
8 char*
9 vnl_alloc::chunk_alloc(std::size_t size, int& nobjs)
10 {
11  char * result;
12  std::size_t total_bytes = size * nobjs;
13  std::size_t bytes_left = end_free - start_free;
14 
15  if (bytes_left >= total_bytes) {
16  result = start_free;
17  start_free += total_bytes;
18  return result;
19  }
20  else if (bytes_left >= size) {
21  nobjs = int(bytes_left/size);
22  total_bytes = size * nobjs;
23  result = start_free;
24  start_free += total_bytes;
25  return result;
26  }
27  else
28  {
29  std::size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
30  // Try to make use of the left-over piece.
31  if (bytes_left > 0) {
32  obj * * my_free_list =
33  free_list + FREELIST_INDEX(bytes_left);
34  ((obj *)start_free) -> free_list_link = *my_free_list;
35  *my_free_list = (obj *)start_free;
36  }
37  start_free = (char*)std::malloc(bytes_to_get);
38  if (nullptr == start_free)
39  {
40  obj * * my_free_list, *p;
41  // Try to make do with what we have. That can't
42  // hurt. We do not try smaller requests, since that tends
43  // to result in disaster on multi-process machines.
44  for (std::size_t i = size; i <= VNL_ALLOC_MAX_BYTES; i += VNL_ALLOC_ALIGN)
45  {
46  my_free_list = free_list + FREELIST_INDEX(i);
47  p = *my_free_list;
48  if (nullptr != p) {
49  *my_free_list = p -> free_list_link;
50  start_free = (char *)p;
51  end_free = start_free + i;
52  return chunk_alloc(size, nobjs);
53  // Any leftover piece will eventually make it to the
54  // right free std::list.
55  }
56  }
57  start_free = (char*)std::malloc(bytes_to_get);
58  // This should either throw an
59  // exception or remedy the situation. Thus we assume it
60  // succeeded.
61  }
62  heap_size += bytes_to_get;
63  end_free = start_free + bytes_to_get;
64  return chunk_alloc(size, nobjs);
65  }
66 }
67 
68 
69 /* Returns an object of size n, and optionally adds to size n free std::list.*/
70 /* We assume that n is properly aligned. */
71 /* We hold the allocation lock. */
72 void* vnl_alloc::refill(std::size_t n)
73 {
74  int nobjs = 20;
75  char * chunk = chunk_alloc(n, nobjs);
76  obj * * my_free_list;
77  obj * result;
78  obj * current_obj, * next_obj;
79  int i;
80 
81  if (1 == nobjs) return chunk;
82  my_free_list = free_list + FREELIST_INDEX(n);
83 
84  /* Build free std::list in chunk */
85  result = (obj *)chunk;
86  *my_free_list = next_obj = (obj *)(chunk + n);
87  for (i = 1; ; i++) {
88  current_obj = next_obj;
89  next_obj = (obj *)((char *)next_obj + n);
90  if (nobjs - 1 == i) {
91  current_obj -> free_list_link = nullptr;
92  break;
93  }
94  else {
95  current_obj -> free_list_link = next_obj;
96  }
97  }
98  return result;
99 }
100 
101 void*
103  std::size_t old_sz,
104  std::size_t new_sz)
105 {
106  void * result;
107  std::size_t copy_sz;
108 
109  if (old_sz > VNL_ALLOC_MAX_BYTES && new_sz > VNL_ALLOC_MAX_BYTES) {
110  return std::realloc(p, new_sz);
111  }
112  if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return p;
113  result = allocate(new_sz);
114  copy_sz = new_sz > old_sz? old_sz : new_sz;
115  std::memcpy(result, p, copy_sz);
116  deallocate(p, old_sz);
117  return result;
118 }
119 
120 char *vnl_alloc::start_free = nullptr;
121 char *vnl_alloc::end_free = nullptr;
122 std::size_t vnl_alloc::heap_size = 0;
123 
126 
127 #ifdef TEST
128 int main()
129 {
130  char* p = (char*)vnl_alloc::allocate(10);
131  std::strcpy(p, "fred\n");
132  std::cerr << p << '\n';
133  vnl_alloc::deallocate(p,10);
134 }
135 
136 #endif // TEST
static char * end_free
Definition: vnl_alloc.h:73
static char * start_free
Definition: vnl_alloc.h:72
Default node allocator.
constexpr std::size_t VNL_ALLOC_NFREELISTS
Definition: vnl_alloc.h:42
constexpr std::size_t VNL_ALLOC_MAX_BYTES
Definition: vnl_alloc.h:41
static void deallocate(void *p, std::size_t n)
Definition: vnl_alloc.h:110
static char * chunk_alloc(std::size_t size, int &nobjs)
Definition: vnl_alloc.cxx:9
constexpr int VNL_ALLOC_ALIGN
Definition: vnl_alloc.h:40
static std::size_t heap_size
Definition: vnl_alloc.h:74
static void * reallocate(void *p, std::size_t old_sz, std::size_t new_sz)
Definition: vnl_alloc.cxx:102
static std::size_t ROUND_UP(std::size_t bytes)
Definition: vnl_alloc.h:46
static obj * free_list[VNL_ALLOC_NFREELISTS]
Definition: vnl_alloc.h:59
static std::size_t FREELIST_INDEX(std::size_t bytes)
Definition: vnl_alloc.h:61
static void * allocate(std::size_t n)
Definition: vnl_alloc.h:89
static void * refill(std::size_t n)
Definition: vnl_alloc.cxx:72