vnl_alloc.h
Go to the documentation of this file.
1 // This is core/vnl/vnl_alloc.h
2 #ifndef vnl_alloc_h_
3 #define vnl_alloc_h_
4 //:
5 // \file
6 // \author unknown
7 //
8 // \brief Default node allocator.
9 //
10 // With a reasonable compiler, this should be roughly as fast as the
11 // original STL class-specific allocators, but with less fragmentation.
12 // Default_alloc_template parameters are experimental and MAY
13 // DISAPPEAR in the future. Clients should just use vcl_alloc for now.
14 //
15 // Important implementation properties:
16 // - If the client request an object of size > __MAX_BYTES, the resulting
17 // object will be obtained directly from malloc.
18 // - In all other cases, we allocate an object of size exactly
19 // ROUND_UP(requested_size). Thus the client has enough size
20 // information that we can return the object to the proper free li*st
21 // without permanently losing part of the object.
22 //
23 // The first template parameter specifies whether more than one thread
24 // may use this allocator. It is safe to allocate an object from
25 // one instance of a default_alloc and deallocate it with another
26 // one. This effectively transfers its ownership to the second one.
27 // This may have undesirable effects on reference locality.
28 // The second parameter is unreferenced and serves only to allow the
29 // creation of multiple default_alloc instances.
30 //
31 // Note that containers built on different allocator instances have
32 // different types, limiting the utility of this approach.
33 
34 #include <cstddef>
35 #ifdef _MSC_VER
36 # include <vcl_msvc_warnings.h>
37 #endif
38 #include "vnl/vnl_export.h"
39 
40 constexpr int VNL_ALLOC_ALIGN = 8;
41 constexpr std::size_t VNL_ALLOC_MAX_BYTES = 256;
43 
44 class VNL_EXPORT vnl_alloc
45 {
46  static std::size_t ROUND_UP(std::size_t bytes) {
47  return (bytes + VNL_ALLOC_ALIGN-1) & ~(VNL_ALLOC_ALIGN - 1);
48  }
49  union obj;
50  friend union obj;
51  union obj {
53  char client_data[1]; /* The client sees this. */
54  };
55 # if defined ( _AIX )
56  static obj * free_list[];
57  // Specifying a size results in duplicate def for 4.1
58 # else
59  static obj * free_list[VNL_ALLOC_NFREELISTS];
60 # endif
61  static std::size_t FREELIST_INDEX(std::size_t bytes) {
62  return (bytes + VNL_ALLOC_ALIGN-1)/VNL_ALLOC_ALIGN - 1;
63  }
64 
65  // Returns an object of size n, and optionally adds to size n free li*st.
66  static void *refill(std::size_t n);
67  // Allocates a chunk for nobjs of size size. nobjs may be reduced
68  // if it is inconvenient to allocate the requested number.
69  static char *chunk_alloc(std::size_t size, int &nobjs);
70 
71  // Chunk allocation state.
72  static char *start_free;
73  static char *end_free;
74  static std::size_t heap_size;
75 
76  class lock
77  {
78  public:
79  lock() = default;
80  ~lock() = default;
81  };
82  friend class lock;
83 
84  public:
85  // this one is needed for proper vcl_simple_alloc wrapping
86  typedef char value_type;
87 
88  /* n must be > 0 */
89  static void * allocate(std::size_t n) {
90  obj * * my_free_list;
91  obj * result;
92 
93  if (n > VNL_ALLOC_MAX_BYTES) {
94  return (void*)new char[n];
95  }
96  my_free_list = free_list + FREELIST_INDEX(n);
97  // Acquire the lock here with a constructor call.
98  // This ensures that it is released in exit or during stack
99  // unwinding.
100  result = *my_free_list;
101  if (result == nullptr) {
102  void *r = refill(ROUND_UP(n));
103  return r;
104  }
105  *my_free_list = result -> free_list_link;
106  return result;
107  };
108 
109  /* p may not be 0 */
110  static void deallocate(void *p, std::size_t n)
111  {
112  obj *q = (obj *)p;
113  obj * * my_free_list;
114 
115  if (n > VNL_ALLOC_MAX_BYTES) {
116  delete [] (char*)p;
117  return;
118  }
119  my_free_list = free_list + FREELIST_INDEX(n);
120  q -> free_list_link = *my_free_list;
121  *my_free_list = q;
122  }
123 
124  static void * reallocate(void *p, std::size_t old_sz, std::size_t new_sz);
125 };
126 
127 # endif // vnl_alloc_h_
static char * end_free
Definition: vnl_alloc.h:73
static char * start_free
Definition: vnl_alloc.h:72
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
constexpr int VNL_ALLOC_ALIGN
Definition: vnl_alloc.h:40
static std::size_t heap_size
Definition: vnl_alloc.h:74
static std::size_t ROUND_UP(std::size_t bytes)
Definition: vnl_alloc.h:46
union obj * free_list_link
Definition: vnl_alloc.h:52
char value_type
Definition: vnl_alloc.h:86
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