9 #define ALLOC_USE_PTHREADS 10 #if defined(ALLOC_USE_PTHREADS) 14 #include <sys/syscall.h> 22 #if !defined(__x86_64__) && !defined(__i386__) 23 #define USE_LOCAL_MALLOC 25 #if defined(__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ < 28) 27 #define USE_LOCAL_MALLOC 31 std::atomic<bool>& alloc_monitor_running_state() {
32 static std::atomic<bool> s_state =
false;
37 T get(
const char* iName) {
38 void*
original = dlsym(RTLD_NEXT, iName);
43 inline auto thread_id() {
44 #if defined(ALLOC_USE_PTHREADS) 46 return pthread_self();
48 return syscall(SYS_gettid);
51 #ifdef USE_LOCAL_MALLOC 57 constexpr auto max_align =
alignof(std::max_align_t);
58 alignas(max_align)
char tmpbuff[131072];
59 unsigned long tmppos = 0;
60 unsigned long tmpallocs = 0;
62 void* local_malloc(
size_t size) noexcept {
64 size = ((
size + max_align - 1) / max_align) * max_align;
65 if (tmppos +
size <
sizeof(tmpbuff)) {
66 void* retptr = tmpbuff + tmppos;
76 void* local_calloc(
size_t nitems,
size_t item_size) noexcept {
return local_malloc(nitems * item_size); }
78 inline bool is_local_alloc(
void* ptr) noexcept {
return ptr >= (
void*)tmpbuff && ptr <= (
void*)(tmpbuff + tmppos); }
84 inline static void init() noexcept {
87 malloc = get<decltype(&::malloc)>(
"malloc");
88 calloc = get<decltype(&::calloc)>(
"calloc");
98 bool Originals::set =
false;
100 constexpr inline bool is_local_alloc(
void* ptr) noexcept {
return false; }
103 struct ThreadTracker {
104 static constexpr unsigned int kEntries = 128;
105 using entry_type = decltype(thread_id());
106 std::array<std::atomic<entry_type>, kEntries> used_threads_;
107 std::array<std::mutex, kEntries> used_threads_mutex_;
111 entry_type
entry = 0;
112 for (
auto&
v : used_threads_) {
117 std::size_t thread_index(entry_type
id)
const {
118 #if defined(ALLOC_USE_PTHREADS) 119 return (
id / 0x700) % kEntries;
121 return id % kEntries;
126 bool stop_reporting() {
127 auto id = thread_id();
128 auto index = thread_index(
id);
130 if (
id == used_threads_[
index]) {
133 used_threads_mutex_[
index].lock();
138 void start_reporting() {
139 auto id = thread_id();
140 auto index = thread_index(
id);
141 auto&
v = used_threads_[
index];
142 if (
v == static_cast<entry_type>(
index + 1)) {
147 used_threads_mutex_[
index].unlock();
151 static ThreadTracker& getTracker() {
152 static ThreadTracker s_tracker;
171 #ifdef USE_LOCAL_MALLOC 175 if (not alloc_monitor_running_state()) {
179 return reg.allocCalled(
183 void*
calloc(
size_t nitems,
size_t item_size) noexcept {
186 if (not alloc_monitor_running_state()) {
190 return reg.allocCalled(
193 [](
auto ret) {
return malloc_usable_size(
ret); });
196 void*
malloc(
size_t size) noexcept {
198 if (not alloc_monitor_running_state()) {
202 return reg.allocCalled(
203 size, [size]() {
return original(size); }, [](
auto ret) {
return malloc_usable_size(
ret); });
206 void*
calloc(
size_t nitems,
size_t item_size) noexcept {
208 if (not alloc_monitor_running_state()) {
212 return reg.allocCalled(
214 [nitems, item_size]() {
return original(nitems, item_size); },
215 [](
auto ret) {
return malloc_usable_size(
ret); });
219 void*
realloc(
void* ptr,
size_t size) noexcept {
221 if (not alloc_monitor_running_state()) {
224 size_t oldsize = malloc_usable_size(ptr);
229 [[maybe_unused]]
auto g = reg.makeGuard();
232 size_t used = malloc_usable_size(
ret);
233 if (used != oldsize) {
235 ptr, [](
auto) {}, [oldsize](
auto) {
return oldsize; });
237 size, []() {
return nullptr; }, [used](
auto) {
return used; });
244 if (not alloc_monitor_running_state()) {
249 return reg.allocCalled(
252 [](
auto ret) {
return malloc_usable_size(
ret); });
258 if (not alloc_monitor_running_state()) {
270 [](
auto ret) {
return malloc_usable_size(
ret); });
277 if (not alloc_monitor_running_state()) {
282 return reg.allocCalled(
285 [](
auto ret) {
return malloc_usable_size(
ret); });
288 void free(
void* ptr) noexcept {
291 if (not is_local_alloc(ptr)) {
292 if (not alloc_monitor_running_state()) {
299 ptr, [](
auto ptr) {
original(ptr); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
307 #define CPP_MEM_OVERRIDE 309 #if defined(CPP_MEM_OVERRIDE) 312 void*
operator new(std::size_t size) {
314 if (not alloc_monitor_running_state()) {
319 return reg.allocCalled(
320 size, [size]() {
return original(size); }, [](
auto ret) {
return malloc_usable_size(
ret); });
323 void operator delete(
void* ptr) noexcept {
325 if (not alloc_monitor_running_state()) {
332 ptr, [](
auto ptr) {
original(ptr); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
335 void*
operator new[](std::size_t size) {
337 if (not alloc_monitor_running_state()) {
342 return reg.allocCalled(
343 size, [size]() {
return original(size); }, [](
auto ret) {
return malloc_usable_size(
ret); });
346 void operator delete[](
void* ptr) noexcept {
349 if (not alloc_monitor_running_state()) {
355 ptr, [](
auto ptr) {
original(ptr); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
358 void*
operator new(std::size_t size, std::align_val_t al) {
359 CMS_SA_ALLOW static const auto original = get<void* (*)(std::size_t, std::align_val_t)>(
"_ZnwmSt11align_val_t");
360 if (not alloc_monitor_running_state()) {
365 return reg.allocCalled(
366 size, [size, al]() {
return original(size, al); }, [](
auto ret) {
return malloc_usable_size(
ret); });
369 void*
operator new[](std::size_t size, std::align_val_t al) {
370 CMS_SA_ALLOW static const auto original = get<void* (*)(std::size_t, std::align_val_t)>(
"_ZnamSt11align_val_t");
372 if (not alloc_monitor_running_state()) {
377 return reg.allocCalled(
378 size, [size, al]() {
return original(size, al); }, [](
auto ret) {
return malloc_usable_size(
ret); });
381 void*
operator new(std::size_t size,
const std::nothrow_t&
tag) noexcept {
383 get<void* (*)(std::size_t, const std::nothrow_t&) noexcept>(
"_ZnwmRKSt9nothrow_t");
385 if (not alloc_monitor_running_state()) {
390 return reg.allocCalled(
391 size, [size, &
tag]() {
return original(size,
tag); }, [](
auto ret) {
return malloc_usable_size(
ret); });
394 void*
operator new[](std::size_t size,
const std::nothrow_t&
tag) noexcept {
396 get<void* (*)(std::size_t, const std::nothrow_t&) noexcept>(
"_ZnamRKSt9nothrow_t");
398 if (not alloc_monitor_running_state()) {
403 return reg.allocCalled(
404 size, [size, &
tag]() {
return original(size,
tag); }, [](
auto ret) {
return malloc_usable_size(
ret); });
407 void*
operator new(std::size_t size, std::align_val_t al,
const std::nothrow_t&
tag) noexcept {
409 get<void* (*)(std::size_t, std::align_val_t, const std::nothrow_t&) noexcept>(
410 "_ZnwmSt11align_val_tRKSt9nothrow_t");
412 if (not alloc_monitor_running_state()) {
417 return reg.allocCalled(
418 size, [size, al, &
tag]() {
return original(size, al,
tag); }, [](
auto ret) {
return malloc_usable_size(
ret); });
421 void*
operator new[](std::size_t size, std::align_val_t al,
const std::nothrow_t&
tag) noexcept {
423 get<void* (*)(std::size_t, std::align_val_t, const std::nothrow_t&) noexcept>(
424 "_ZnamSt11align_val_tRKSt9nothrow_t");
426 if (not alloc_monitor_running_state()) {
431 return reg.allocCalled(
432 size, [size, al, &
tag]() {
return original(size, al,
tag); }, [](
auto ret) {
return malloc_usable_size(
ret); });
435 void operator delete(
void* ptr, std::align_val_t al) noexcept {
436 CMS_SA_ALLOW static const auto original = get<void (*)(void*, std::align_val_t) noexcept>(
"_ZdlPvSt11align_val_t");
438 if (not alloc_monitor_running_state()) {
444 ptr, [al](
auto ptr) {
original(ptr, al); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
447 void operator delete[](
void* ptr, std::align_val_t al) noexcept {
448 CMS_SA_ALLOW static const auto original = get<void (*)(void*, std::align_val_t) noexcept>(
"_ZdaPvSt11align_val_t");
450 if (not alloc_monitor_running_state()) {
456 ptr, [al](
auto ptr) {
original(ptr, al); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
459 void operator delete(
void* ptr, std::size_t sz) noexcept {
460 CMS_SA_ALLOW static const auto original = get<void (*)(void*, std::size_t) noexcept>(
"_ZdlPvm");
462 if (not alloc_monitor_running_state()) {
468 ptr, [sz](
auto ptr) {
original(ptr, sz); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
471 void operator delete[](
void* ptr, std::size_t sz) noexcept {
472 CMS_SA_ALLOW static const auto original = get<void (*)(void*, std::size_t) noexcept>(
"_ZdaPvm");
474 if (not alloc_monitor_running_state()) {
480 ptr, [sz](
auto ptr) {
original(ptr, sz); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
483 void operator delete(
void* ptr, std::size_t sz, std::align_val_t al) noexcept {
485 get<void (*)(void*, std::size_t, std::align_val_t) noexcept>(
"_ZdlPvmSt11align_val_t");
487 if (not alloc_monitor_running_state()) {
493 ptr, [sz, al](
auto ptr) {
original(ptr, sz, al); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
496 void operator delete[](
void* ptr, std::size_t sz, std::align_val_t al) noexcept {
498 get<void (*)(void*, std::size_t, std::align_val_t) noexcept>(
"_ZdaPvmSt11align_val_t");
500 if (not alloc_monitor_running_state()) {
506 ptr, [sz, al](
auto ptr) {
original(ptr, sz, al); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
509 void operator delete(
void* ptr,
const std::nothrow_t&
tag) noexcept {
511 get<void (*)(void*, const std::nothrow_t&) noexcept>(
"_ZdlPvRKSt9nothrow_t");
513 if (not alloc_monitor_running_state()) {
519 ptr, [&
tag](
auto ptr) {
original(ptr,
tag); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
522 void operator delete[](
void* ptr,
const std::nothrow_t&
tag) noexcept {
524 get<void (*)(void*, const std::nothrow_t&) noexcept>(
"_ZdaPvRKSt9nothrow_t");
526 if (not alloc_monitor_running_state()) {
532 ptr, [&
tag](
auto ptr) {
original(ptr,
tag); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
535 void operator delete(
void* ptr, std::align_val_t al,
const std::nothrow_t&
tag) noexcept {
537 get<void (*)(void*, std::align_val_t, const std::nothrow_t&) noexcept>(
"_ZdlPvSt11align_val_tRKSt9nothrow_t");
539 if (not alloc_monitor_running_state()) {
545 ptr, [al, &
tag](
auto ptr) {
original(ptr, al,
tag); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
548 void operator delete[](
void* ptr, std::align_val_t al,
const std::nothrow_t&
tag) noexcept {
550 get<void (*)(void*, std::align_val_t, const std::nothrow_t&) noexcept>(
"_ZdaPvSt11align_val_tRKSt9nothrow_t");
552 if (not alloc_monitor_running_state()) {
558 ptr, [al, &
tag](
auto ptr) {
original(ptr, al,
tag); }, [](
auto ptr) {
return malloc_usable_size(ptr); });
ret
prodAgent to be discontinued
int posix_memalign(void **memptr, size_t alignment, size_t size) noexcept
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
void free(void *ptr) noexcept
void * aligned_alloc(size_t alignment, size_t size) noexcept
void alloc_monitor_start_thread_reporting()
void * malloc(size_t size) noexcept
void * realloc(void *ptr, size_t size) noexcept
void alloc_monitor_start()
void * memalign(size_t alignment, size_t size) noexcept
void alloc_monitor_stop()
bool alloc_monitor_stop_thread_reporting()
void * calloc(size_t nitems, size_t item_size) noexcept