NEURON
memory.cpp
Go to the documentation of this file.
1 #include "memory.hpp"
2 
3 #include <cstdlib>
4 #include <cstring>
5 
6 // For hoc_warning and hoc_execerror
7 #include "oc_ansi.h"
8 
9 #if HAVE_POSIX_MEMALIGN
10 #define HAVE_MEMALIGN 1
11 #endif
12 #if defined(DARWIN) /* posix_memalign seems not to work on Darwin 10.6.2 */
13 #undef HAVE_MEMALIGN
14 #endif
15 #if HAVE_MEMALIGN
16 #undef _XOPEN_SOURCE /* avoid warnings about redefining this */
17 #define _XOPEN_SOURCE 600
18 #endif
19 
20 static bool emalloc_error = false;
21 
22 void* hoc_Emalloc(std::size_t n) { /* check return from malloc */
23  void* p = std::malloc(n);
24  if (p == nullptr) {
25  emalloc_error = true;
26  }
27  return p;
28 }
29 
30 void* hoc_Ecalloc(std::size_t n, std::size_t size) { /* check return from calloc */
31  if (n == 0) {
32  return nullptr;
33  }
34  void* p = std::calloc(n, size);
35  if (p == nullptr) {
36  emalloc_error = true;
37  }
38  return p;
39 }
40 
41 void* hoc_Erealloc(void* ptr, std::size_t size) { /* check return from realloc */
42  if (!ptr) {
43  return hoc_Emalloc(size);
44  }
45  void* p = std::realloc(ptr, size);
46  if (p == nullptr) {
47  std::free(ptr);
48  emalloc_error = true;
49  }
50  return p;
51 }
52 
53 void hoc_malchk(void) {
54  if (emalloc_error) {
55  emalloc_error = false;
56  hoc_execerror("out of memory", nullptr);
57  }
58 }
59 
60 void* emalloc(std::size_t n) {
61  void* p = hoc_Emalloc(n);
62  if (emalloc_error) {
63  hoc_malchk();
64  }
65  return p;
66 }
67 
68 void* ecalloc(std::size_t n, std::size_t size) {
69  void* p = hoc_Ecalloc(n, size);
70  if (emalloc_error) {
71  hoc_malchk();
72  }
73  return p;
74 }
75 
76 void* erealloc(void* ptr, std::size_t size) {
77  void* p = hoc_Erealloc(ptr, size);
78  if (emalloc_error) {
79  hoc_malchk();
80  }
81  return p;
82 }
83 
84 void* nrn_cacheline_alloc(void** memptr, std::size_t size) {
85 #if HAVE_MEMALIGN
86  static bool memalign_is_working = true;
87  if (memalign_is_working) {
88  if (posix_memalign(memptr, 64, size) != 0) {
89  hoc_warning("posix_memalign not working, falling back to using malloc\n", nullptr);
90  memalign_is_working = false;
91  *memptr = hoc_Emalloc(size);
92  hoc_malchk();
93  }
94  } else
95 #endif
96  {
97  *memptr = hoc_Emalloc(size);
98  hoc_malchk();
99  }
100  return *memptr;
101 }
102 
103 void* nrn_cacheline_calloc(void** memptr, std::size_t nmemb, std::size_t size) {
104 #if HAVE_MEMALIGN
105  nrn_cacheline_alloc(memptr, nmemb * size);
106  std::memset(*memptr, 0, nmemb * size);
107 #else
108  *memptr = hoc_Ecalloc(nmemb, size);
109  hoc_malchk();
110 #endif
111  return *memptr;
112 }
void hoc_execerror(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:39
void hoc_warning(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:44
int const size_t const size_t n
Definition: nrngsl.h:10
size_t p
void * erealloc(void *ptr, std::size_t size)
Definition: memory.cpp:76
static bool emalloc_error
Definition: memory.cpp:20
void * hoc_Ecalloc(std::size_t n, std::size_t size)
Definition: memory.cpp:30
void * emalloc(std::size_t n)
Definition: memory.cpp:60
void * nrn_cacheline_calloc(void **memptr, std::size_t nmemb, std::size_t size)
Definition: memory.cpp:103
void hoc_malchk(void)
Definition: memory.cpp:53
void * nrn_cacheline_alloc(void **memptr, std::size_t size)
Definition: memory.cpp:84
void * ecalloc(std::size_t n, std::size_t size)
Definition: memory.cpp:68
void * hoc_Emalloc(std::size_t n)
Definition: memory.cpp:22
void * hoc_Erealloc(void *ptr, std::size_t size)
Definition: memory.cpp:41
HOC interpreter function declarations (included by hocdec.h)