CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
smalloc.h
Go to the documentation of this file.
1 
7 #ifndef CVMFS_UTIL_SMALLOC_H_
8 #define CVMFS_UTIL_SMALLOC_H_
9 
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <sys/mman.h>
13 
14 #include <cassert>
15 // #include <cstdio>
16 
17 #include <limits>
18 
19 #ifdef __APPLE__
20 #define PLATFORM_MAP_ANONYMOUS MAP_ANON
21 #else
22 #define PLATFORM_MAP_ANONYMOUS MAP_ANONYMOUS
23 #endif
24 
25 
26 #ifdef CVMFS_NAMESPACE_GUARD
27 namespace CVMFS_NAMESPACE_GUARD {
28 #endif
29 
30 // Checkerboard marker (binary 101010...)
31 const uint32_t kMemMarker = 0xAAAAAAAA;
32 
37 static inline uint64_t RoundUp8(const uint64_t size) {
38  return (size + 7) & ~static_cast<uint64_t>(7);
39 }
40 
41 static inline void * __attribute__((used)) smalloc(size_t size) {
42  void *mem = NULL;
43 #ifdef CVMFS_SUPPRESS_ASSERTS
44  do {
45 #endif
46  mem = malloc(size);
47 #ifdef CVMFS_SUPPRESS_ASSERTS
48  } while ((size > 0) && (mem == NULL));
49 #endif
50  assert((mem || (size == 0)) && "Out Of Memory");
51  return mem;
52 }
53 
54 static inline void * __attribute__((used)) srealloc(void *ptr, size_t size) {
55  void *mem = NULL;
56 
57 #ifdef CVMFS_SUPPRESS_ASSERTS
58  do {
59 #endif
60  mem = realloc(ptr, size);
61 #ifdef CVMFS_SUPPRESS_ASSERTS
62  } while ((size > 0) && (mem == NULL));
63 #endif
64  assert((mem || (size == 0)) && "Out Of Memory");
65  return mem;
66 }
67 
68 static inline void * __attribute__((used)) scalloc(size_t count, size_t size) {
69  void *mem = NULL;
70 
71 #ifdef CVMFS_SUPPRESS_ASSERTS
72  do {
73 #endif
74  mem = calloc(count, size);
75 #ifdef CVMFS_SUPPRESS_ASSERTS
76  } while ((count * size > 0) && (mem == NULL));
77 #endif
78  assert((mem || ((count * size) == 0)) && "Out Of Memory");
79  return mem;
80 }
81 
82 static inline void * __attribute__((used)) smmap(size_t size) {
83  // TODO(reneme): make page size platform independent
84  assert(size > 0);
85  assert(size < std::numeric_limits<size_t>::max() - 4096);
86 
87  const int anonymous_fd = -1;
88  const off_t offset = 0;
89  size_t pages = ((size + 2 * sizeof(size_t)) + 4095)
90  / 4096; // round to full page
91  unsigned char *mem = NULL;
92 
93 #ifdef CVMFS_SUPPRESS_ASSERTS
94  do {
95 #endif
96  mem = static_cast<unsigned char *>(
97  mmap(NULL,
98  pages * 4096,
99  PROT_READ | PROT_WRITE,
100  MAP_PRIVATE | PLATFORM_MAP_ANONYMOUS,
101  anonymous_fd,
102  offset));
103 
104 #ifdef CVMFS_SUPPRESS_ASSERTS
105  } while (mem == MAP_FAILED);
106 #endif
107  // printf("SMMAP %d bytes at %p\n", pages*4096, mem);
108  // NOLINTNEXTLINE(performance-no-int-to-ptr)
109  assert((mem != MAP_FAILED) && "Out Of Memory");
110  *(reinterpret_cast<size_t *>(mem)) = kMemMarker;
111  *(reinterpret_cast<size_t *>(mem) + 1) = pages;
112  return mem + 2 * sizeof(size_t);
113 }
114 
115 static inline void __attribute__((used)) smunmap(void *mem) {
116  unsigned char *area = static_cast<unsigned char *>(mem);
117  area = area - sizeof(size_t);
118  size_t pages = *(reinterpret_cast<size_t *>(area));
119  int retval = munmap(area - sizeof(size_t), pages * 4096);
120  // printf("SUNMMAP %d bytes at %p\n", pages*4096, area);
121  assert((retval == 0) && "Invalid umnmap");
122 }
123 
124 
128 static inline void * __attribute__((used)) sxmmap(size_t size) {
129  const int anonymous_fd = -1;
130  const off_t offset = 0;
131  void *mem = NULL;
132 
133 #ifdef CVMFS_SUPPRESS_ASSERTS
134  do {
135 #endif
136  mem = mmap(NULL,
137  size,
138  PROT_READ | PROT_WRITE,
139  MAP_PRIVATE | PLATFORM_MAP_ANONYMOUS,
140  anonymous_fd,
141  offset);
142 
143 #ifdef CVMFS_SUPPRESS_ASSERTS
144  } while (mem == MAP_FAILED);
145 #endif
146  // NOLINTNEXTLINE(performance-no-int-to-ptr)
147  assert((mem != MAP_FAILED) && "Out Of Memory");
148  return mem;
149 }
150 
151 
155 static inline void __attribute__((used)) sxunmap(void *mem, size_t size) {
156  int retval = munmap(mem, size);
157  assert((retval == 0) && "Invalid umnmap");
158 }
159 
160 
165 static inline void * __attribute__((used)) sxmmap_align(size_t size) {
166  assert((size % (2 * 1024 * 1024)) == 0);
167  char *mem = NULL;
168 #ifdef CVMFS_SUPPRESS_ASSERTS
169  do {
170 #endif
171  mem = reinterpret_cast<char *>(sxmmap(2 * size));
172 #ifdef CVMFS_SUPPRESS_ASSERTS
173  } while (mem == MAP_FAILED);
174 #endif
175 
176  uintptr_t head = size - (uintptr_t(mem) % size);
177  sxunmap(mem, head);
178  mem += head;
179  uintptr_t tail = size - head;
180  if (tail > 0)
181  sxunmap(mem + size, tail);
182  return mem;
183 }
184 
185 
186 #ifdef CVMFS_NAMESPACE_GUARD
187 } // namespace CVMFS_NAMESPACE_GUARD
188 #endif
189 
190 #endif // CVMFS_UTIL_SMALLOC_H_
assert((mem||(size==0))&&"Out Of Memory")
struct cvmcache_object_info __attribute__
Definition: atomic.h:24
static uint64_t RoundUp8(const uint64_t size)
Definition: smalloc.h:37
#define PLATFORM_MAP_ANONYMOUS
Definition: smalloc.h:22
mem
Definition: smalloc.h:60
static void size_t size
Definition: smalloc.h:54
const uint32_t kMemMarker
Definition: smalloc.h:31