mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-29 11:02:08 +00:00
Better PHDR cache
This commit is contained in:
parent
cc7fe5fb8d
commit
796dfeb44e
@ -2,11 +2,11 @@
|
||||
|
||||
#include <link.h>
|
||||
#include <dlfcn.h>
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@ -24,9 +24,11 @@ DLIterateFunction getOriginalDLIteratePHDR()
|
||||
return reinterpret_cast<DLIterateFunction>(func);
|
||||
}
|
||||
|
||||
// Never destroyed to avoid races with static destructors.
|
||||
using PHDRCache = std::vector<dl_phdr_info>;
|
||||
PHDRCache * phdr_cache;
|
||||
|
||||
constexpr size_t phdr_cache_max_size = 128;
|
||||
size_t phdr_cache_size = 0;
|
||||
using PHDRCache = std::array<dl_phdr_info, phdr_cache_max_size>;
|
||||
PHDRCache phdr_cache;
|
||||
|
||||
}
|
||||
|
||||
@ -38,16 +40,16 @@ extern "C"
|
||||
#endif
|
||||
int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * data), void * data)
|
||||
{
|
||||
if (!phdr_cache)
|
||||
if (0 == phdr_cache_size)
|
||||
{
|
||||
// Cache is not yet populated, pass through to the original function.
|
||||
return getOriginalDLIteratePHDR()(callback, data);
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
for (auto & info : *phdr_cache)
|
||||
for (size_t i = 0; i < phdr_cache_size; ++i)
|
||||
{
|
||||
result = callback(&info, offsetof(dl_phdr_info, dlpi_adds), data);
|
||||
result = callback(&phdr_cache[i], offsetof(dl_phdr_info, dlpi_adds), data);
|
||||
if (result != 0)
|
||||
break;
|
||||
}
|
||||
@ -60,10 +62,12 @@ void enablePHDRCache()
|
||||
#if defined(__linux__)
|
||||
// Fill out ELF header cache for access without locking.
|
||||
// This assumes no dynamic object loading/unloading after this point
|
||||
phdr_cache = new PHDRCache;
|
||||
getOriginalDLIteratePHDR()([] (dl_phdr_info * info, size_t /*size*/, void * /*data*/)
|
||||
{
|
||||
phdr_cache->push_back(*info);
|
||||
if (phdr_cache_size >= phdr_cache_max_size)
|
||||
throw std::runtime_error("phdr_cache_max_size is not enough to accomodate the result of dl_iterate_phdr. You must recompile the code.");
|
||||
phdr_cache[phdr_cache_size] = *info;
|
||||
++phdr_cache_size;
|
||||
return 0;
|
||||
}, nullptr);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user