-
Notifications
You must be signed in to change notification settings - Fork 296
Expand file tree
/
Copy pathmemory.cpp
More file actions
112 lines (105 loc) · 5.19 KB
/
Copy pathmemory.cpp
File metadata and controls
112 lines (105 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//==================================================================================
// BSD 2-Clause License
//
// Copyright (c) 2014-2024, NJIT, Duality Technologies Inc. and other contributors
//
// All rights reserved.
//
// Author TPOC: contact@openfhe.org
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//==================================================================================
#include "config_core.h"
#include "utils/memory.h"
#if defined(__APPLE__)
#include <malloc/malloc.h>
#elif defined(__GLIBC__)
#include <malloc.h>
#elif defined(_MSC_VER)
#include <malloc.h>
#endif
namespace lbcrypto {
#if defined(WITH_MALLOC_TUNING)
// Tune the process allocator to retain freed memory for reuse. OpenFHE operations allocate and
// free many large (~0.5-30 MB) buffers; on allocators that return freed buffers to the OS right
// away, re-faulting the pages on the next operation can dominate single-threaded runtime. Any
// tuning below runs once, process-wide, at library load. NOTE: retained memory shows up as a
// higher resident set size for workloads with large transient allocation peaks. Use AllocTrim()
// after large allocations are freed if this becomes an issue, or build with
// -DWITH_MALLOC_TUNING=OFF to disable this tuning entirely.
namespace {
#if defined(__APPLE__)
// Nothing to tune: macOS libmalloc already retains freed memory in-process. Freed pages of
// small/medium allocations stay mapped and are marked reusable (the kernel reclaims them only
// under memory pressure), and freed large allocations are held in the default zone's cache.
// There is no public API to tune this behavior further; AllocTrim() releases these caches.
#elif defined(__GLIBC__)
// By default glibc returns freed large buffers to the OS (brk heap-trim / munmap) and re-faults
// the pages on the next operation. Keeping large allocations on the heap (M_MMAP_MAX=0) and
// never trimming it back to the OS (M_TRIM_THRESHOLD=-1) lets the buffers be reused,
// eliminating the churn.
[[maybe_unused]] const bool ofheGlibcMallocTuned = []() noexcept {
mallopt(M_MMAP_MAX, 0);
mallopt(M_TRIM_THRESHOLD, -1);
return true;
}();
#elif defined(_MSC_VER)
// Nothing to tune: the CRT heap is the Windows process heap, which serves allocations above
// roughly 0.5-1 MB directly via VirtualAlloc and returns them to the OS on free, with no
// supported process-wide switch to retain them. If this churn matters, link a caching
// allocator (e.g. mimalloc or tcmalloc) instead.
#endif
} // namespace
#endif
// AllocTrim() asks the allocator to return free (unused) heap memory to the OS. It is the
// companion to the retain-by-default malloc tuning above: call it at a quiescent point after a
// large transient-footprint operation (e.g. EvalBootstrap) to reclaim peak scratch memory.
//
// WARNING: this is a performance / RSS tool, NOT a security primitive. It does not erase data --
// it only releases already-free chunks (the bytes are not scrubbed; the kernel zero-fills pages
// only when they are next handed out). To wipe sensitive data (keys, plaintext, noise) use
// secure_memset() before freeing.
//
// Not async-signal-safe and acquires allocator locks; call only from normal execution context,
// never from a signal handler. Returns true if a trim was attempted, false on unsupported builds.
bool AllocTrim() {
#if defined(__APPLE__)
malloc_zone_pressure_relief(nullptr, 0);
return true;
#elif defined(__GLIBC__)
malloc_trim(0);
return true;
#elif defined(_MSC_VER)
_heapmin();
return true;
#else
return false;
#endif
}
// secure_memset() overwrites memory with c and, unlike a plain std::memset() of an object about
// to be freed or go out of scope, is guaranteed not to be removed by dead-store elimination.
void secure_memset(volatile void* mem, uint8_t c, size_t len) {
volatile uint8_t* ptr = static_cast<volatile uint8_t*>(mem);
for (size_t i = 0; i < len; ++i)
*(ptr + i) = c;
}
} // namespace lbcrypto