From fc7075a319232ef9ade138d501162a59e48681f1 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Thu, 18 Jan 2024 17:21:26 +0100 Subject: [PATCH 1/6] Move memory related functions to memory.[ch]pp --- cmake/NeuronFileLists.cmake | 1 + src/oc/memory.cpp | 95 +++++++++++++++++++++++++++++++++++++ src/oc/memory.hpp | 18 +++++++ src/oc/symbol.cpp | 90 ----------------------------------- 4 files changed, 114 insertions(+), 90 deletions(-) create mode 100644 src/oc/memory.cpp create mode 100644 src/oc/memory.hpp diff --git a/cmake/NeuronFileLists.cmake b/cmake/NeuronFileLists.cmake index 30f36f5052..57c181cd4c 100644 --- a/cmake/NeuronFileLists.cmake +++ b/cmake/NeuronFileLists.cmake @@ -101,6 +101,7 @@ set(OC_FILE_LIST hoc_oop.cpp list.cpp math.cpp + memory.cpp mswinprt.cpp nonlin.cpp ocerf.cpp diff --git a/src/oc/memory.cpp b/src/oc/memory.cpp new file mode 100644 index 0000000000..a1c8902650 --- /dev/null +++ b/src/oc/memory.cpp @@ -0,0 +1,95 @@ +#include "memory.hpp" + +#include +#include + +// For hoc_warning and hoc_execerror +#include "oc_ansi.h" + +static bool emalloc_error = false; + +void* hoc_Emalloc(std::size_t n) { /* check return from malloc */ + void* p = std::malloc(n); + if (p == nullptr) { + emalloc_error = true; + } + return p; +} + +void* hoc_Ecalloc(std::size_t n, std::size_t size) { /* check return from calloc */ + if (n == 0) { + return nullptr; + } + void* p = std::calloc(n, size); + if (p == nullptr) { + emalloc_error = true; + } + return p; +} + +void* hoc_Erealloc(void* ptr, std::size_t size) { /* check return from realloc */ + if (!ptr) { + return hoc_Emalloc(size); + } + void* p = std::realloc(ptr, size); + if (p == nullptr) { + std::free(ptr); + emalloc_error = true; + } + return p; +} + +void hoc_malchk(void) { + if (emalloc_error) { + emalloc_error = 0; + hoc_execerror("out of memory", nullptr); + } +} + +void* emalloc(std::size_t n) { + void* p = hoc_Emalloc(n); + if (emalloc_error) { + hoc_malchk(); + } + return p; +} + +void* ecalloc(std::size_t n, std::size_t size) { + void* p = hoc_Ecalloc(n, size); + if (emalloc_error) { + hoc_malchk(); + } + return p; +} + +void* erealloc(void* ptr, std::size_t size) { + void* p = hoc_Erealloc(ptr, size); + if (emalloc_error) { + hoc_malchk(); + } + return p; +} + +void* nrn_cacheline_alloc(void** memptr, std::size_t size) { + static bool memalign_is_working = true; + if (memalign_is_working) { + *memptr = std::aligned_alloc(64, size); + if (memptr == nullptr) { + hoc_warning("posix_memalign not working, falling back to using malloc\n", nullptr); + memalign_is_working = false; + *memptr = hoc_Emalloc(size); + hoc_malchk(); + } + } else { + *memptr = hoc_Emalloc(size); + hoc_malchk(); + } + return *memptr; +} + +void* nrn_cacheline_calloc(void** memptr, std::size_t nmemb, std::size_t size) { + nrn_cacheline_alloc(memptr, nmemb * size); + std::memset(*memptr, 0, nmemb * size); + return *memptr; +} + diff --git a/src/oc/memory.hpp b/src/oc/memory.hpp new file mode 100644 index 0000000000..38960e0eba --- /dev/null +++ b/src/oc/memory.hpp @@ -0,0 +1,18 @@ +#pragma once + +// Some functions here are prepend with 'hoc_' but they are unrelated to hoc itself. +#include + +/* check return from malloc */ +void* hoc_Emalloc(std::size_t n); +void* hoc_Ecalloc(std::size_t n, std::size_t size); +void* hoc_Erealloc(void* ptr, std::size_t size); + +void hoc_malchk(void); + +void* emalloc(std::size_t n); +void* ecalloc(std::size_t n, std::size_t size); +void* erealloc(void* ptr, std::size_t size); + +void* nrn_cacheline_alloc(void** memptr, std::size_t size); +void* nrn_cacheline_calloc(void** memptr, std::size_t nmemb, std::size_t size); diff --git a/src/oc/symbol.cpp b/src/oc/symbol.cpp index 7257a91aa3..9bce789491 100644 --- a/src/oc/symbol.cpp +++ b/src/oc/symbol.cpp @@ -173,96 +173,6 @@ void hoc_link_symbol(Symbol* sp, Symlist* list) { sp->next = nullptr; } -static int emalloc_error = 0; - -void hoc_malchk(void) { - if (emalloc_error) { - emalloc_error = 0; - execerror("out of memory", nullptr); - } -} - -void* hoc_Emalloc(size_t n) { /* check return from malloc */ - void* p = malloc(n); - if (p == nullptr) - emalloc_error = 1; - return p; -} - -void* emalloc(size_t n) { - void* p = hoc_Emalloc(n); - if (emalloc_error) { - hoc_malchk(); - } - return p; -} - -void* hoc_Ecalloc(size_t n, size_t size) { /* check return from calloc */ - if (n == 0) { - return nullptr; - } - void* p = calloc(n, size); - if (p == nullptr) - emalloc_error = 1; - return p; -} - -void* ecalloc(size_t n, size_t size) { - void* p = hoc_Ecalloc(n, size); - if (emalloc_error) { - hoc_malchk(); - } - return p; -} - -void* nrn_cacheline_alloc(void** memptr, size_t size) { -#if HAVE_MEMALIGN - static int memalign_is_working = 1; - if (memalign_is_working) { - if (posix_memalign(memptr, 64, size) != 0) { - fprintf(stderr, "posix_memalign not working, falling back to using malloc\n"); - memalign_is_working = 0; - *memptr = hoc_Emalloc(size); - hoc_malchk(); - } - } else -#endif - *memptr = hoc_Emalloc(size); - hoc_malchk(); - return *memptr; -} - -void* nrn_cacheline_calloc(void** memptr, size_t nmemb, size_t size) { -#if HAVE_MEMALIGN - nrn_cacheline_alloc(memptr, nmemb * size); - memset(*memptr, 0, nmemb * size); -#else - *memptr = hoc_Ecalloc(nmemb, size); - hoc_malchk(); -#endif - return *memptr; -} - -void* hoc_Erealloc(void* ptr, size_t size) { /* check return from realloc */ - if (!ptr) { - return hoc_Emalloc(size); - } - void* p = realloc(ptr, size); - if (p == nullptr) { - free(ptr); - emalloc_error = 1; - } - return p; -} - -void* erealloc(void* ptr, size_t size) { - void* p = hoc_Erealloc(ptr, size); - if (emalloc_error) { - hoc_malchk(); - } - return p; -} - void hoc_free_symspace(Symbol* s1) { /* frees symbol space. Marks it UNDEF */ if (s1 && s1->cpublic != 2) { switch (s1->type) { From aa8a2348d7d9472ac750f50ed60ec136ea0827e6 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Thu, 18 Jan 2024 17:25:32 +0100 Subject: [PATCH 2/6] Remove previous declarations --- src/oc/hocdec.h | 4 ---- src/oc/oc_ansi.h | 9 ++------- src/oc/symbol.cpp | 11 ----------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/oc/hocdec.h b/src/oc/hocdec.h index 113defaf53..944d4e9d72 100644 --- a/src/oc/hocdec.h +++ b/src/oc/hocdec.h @@ -224,10 +224,6 @@ struct HocParmUnits { /* units for symbol values */ #include "oc_ansi.h" -void* emalloc(size_t n); -void* ecalloc(size_t n, size_t size); -void* erealloc(void* ptr, size_t n); - extern Inst *hoc_progp, *hoc_progbase, *hoc_prog, *hoc_prog_parse_recover; extern Inst* hoc_pc; diff --git a/src/oc/oc_ansi.h b/src/oc/oc_ansi.h index 399a86e408..34cc37062f 100644 --- a/src/oc/oc_ansi.h +++ b/src/oc/oc_ansi.h @@ -8,6 +8,8 @@ #include #include #include + +#include "memory.hpp" /** * \dir * \brief HOC Interpreter @@ -49,9 +51,6 @@ void ivoc_help(const char*); Symbol* hoc_lookup(const char*); -void* hoc_Ecalloc(std::size_t nmemb, std::size_t size); -void* hoc_Emalloc(size_t size); -void hoc_malchk(); [[noreturn]] void hoc_execerror(const char*, const char*); [[noreturn]] void hoc_execerr_ext(const char* fmt, ...); char* hoc_object_name(Object*); @@ -320,10 +319,6 @@ void hoc_obj_set(int i, Object*); void nrn_hoc_lock(); void nrn_hoc_unlock(); -void* hoc_Erealloc(void* ptr, std::size_t size); - -void* nrn_cacheline_alloc(void** memptr, std::size_t size); -void* nrn_cacheline_calloc(void** memptr, std::size_t nmemb, std::size_t size); [[noreturn]] void nrn_exit(int); void hoc_free_list(Symlist**); int hoc_errno_check(); diff --git a/src/oc/symbol.cpp b/src/oc/symbol.cpp index 9bce789491..605a7ba2a6 100644 --- a/src/oc/symbol.cpp +++ b/src/oc/symbol.cpp @@ -2,17 +2,6 @@ /* /local/src/master/nrn/src/oc/symbol.cpp,v 1.9 1999/02/25 18:01:58 hines Exp */ /* version 7.2.1 2-jan-89 */ -#if HAVE_POSIX_MEMALIGN -#define HAVE_MEMALIGN 1 -#endif -#if defined(DARWIN) /* posix_memalign seems not to work on Darwin 10.6.2 */ -#undef HAVE_MEMALIGN -#endif -#if HAVE_MEMALIGN -#undef _XOPEN_SOURCE /* avoid warnings about redefining this */ -#define _XOPEN_SOURCE 600 -#endif - #include "hoc.h" #include "hocdec.h" #include "hoclist.h" From c075605b4951a39e1749a05ed525ef01a8d18c36 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Thu, 18 Jan 2024 17:43:43 +0100 Subject: [PATCH 3/6] Format --- src/oc/memory.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/oc/memory.cpp b/src/oc/memory.cpp index a1c8902650..3654d06826 100644 --- a/src/oc/memory.cpp +++ b/src/oc/memory.cpp @@ -92,4 +92,3 @@ void* nrn_cacheline_calloc(void** memptr, std::size_t nmemb, std::size_t size) { std::memset(*memptr, 0, nmemb * size); return *memptr; } - From 29486f1548f9e2add53631b6e29aeb9279b8d38c Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Thu, 18 Jan 2024 17:44:15 +0100 Subject: [PATCH 4/6] install header --- cmake/NeuronFileLists.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/NeuronFileLists.cmake b/cmake/NeuronFileLists.cmake index 57c181cd4c..252f3e9ff6 100644 --- a/cmake/NeuronFileLists.cmake +++ b/cmake/NeuronFileLists.cmake @@ -39,6 +39,7 @@ set(HEADER_FILES_TO_INSTALL oc/hocparse.h oc/mcran4.h oc/mech_api.h + oc/memory.hpp oc/nrnapi.h oc/nrnassrt.h oc/nrnisaac.h From df10b1caa8ec616b65fa852695c479173de605ca Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Thu, 18 Jan 2024 17:54:21 +0100 Subject: [PATCH 5/6] Fix from 0 to false --- src/oc/memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oc/memory.cpp b/src/oc/memory.cpp index 3654d06826..124f179fd3 100644 --- a/src/oc/memory.cpp +++ b/src/oc/memory.cpp @@ -41,7 +41,7 @@ void* hoc_Erealloc(void* ptr, std::size_t size) { /* check return from realloc * void hoc_malchk(void) { if (emalloc_error) { - emalloc_error = 0; + emalloc_error = false; hoc_execerror("out of memory", nullptr); } } From f42bb821d25ee3329eab97dad77fc7dc9266e52b Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Thu, 18 Jan 2024 18:08:03 +0100 Subject: [PATCH 6/6] Still use posix_memalign --- src/oc/memory.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/oc/memory.cpp b/src/oc/memory.cpp index 124f179fd3..44a6b93e51 100644 --- a/src/oc/memory.cpp +++ b/src/oc/memory.cpp @@ -6,6 +6,17 @@ // For hoc_warning and hoc_execerror #include "oc_ansi.h" +#if HAVE_POSIX_MEMALIGN +#define HAVE_MEMALIGN 1 +#endif +#if defined(DARWIN) /* posix_memalign seems not to work on Darwin 10.6.2 */ +#undef HAVE_MEMALIGN +#endif +#if HAVE_MEMALIGN +#undef _XOPEN_SOURCE /* avoid warnings about redefining this */ +#define _XOPEN_SOURCE 600 +#endif + static bool emalloc_error = false; void* hoc_Emalloc(std::size_t n) { /* check return from malloc */ @@ -71,16 +82,18 @@ void* erealloc(void* ptr, std::size_t size) { } void* nrn_cacheline_alloc(void** memptr, std::size_t size) { +#if HAVE_MEMALIGN static bool memalign_is_working = true; if (memalign_is_working) { - *memptr = std::aligned_alloc(64, size); - if (memptr == nullptr) { + if (posix_memalign(memptr, 64, size) != 0) { hoc_warning("posix_memalign not working, falling back to using malloc\n", nullptr); memalign_is_working = false; *memptr = hoc_Emalloc(size); hoc_malchk(); } - } else { + } else +#endif + { *memptr = hoc_Emalloc(size); hoc_malchk(); } @@ -88,7 +101,12 @@ void* nrn_cacheline_alloc(void** memptr, std::size_t size) { } void* nrn_cacheline_calloc(void** memptr, std::size_t nmemb, std::size_t size) { +#if HAVE_MEMALIGN nrn_cacheline_alloc(memptr, nmemb * size); std::memset(*memptr, 0, nmemb * size); +#else + *memptr = hoc_Ecalloc(nmemb, size); + hoc_malchk(); +#endif return *memptr; }