aboutsummaryrefslogtreecommitdiffstats
path: root/vespamalloc
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2021-06-29 11:41:10 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2021-06-29 11:41:10 +0000
commitbb00676ae9d58e54e7079a7844250d50bd350682 (patch)
treeca0de1fca59411d845c72a6f3011d9210ed602e8 /vespamalloc
parentb2bcbb4807896b14ef34a41efa2054cc2a90a9ab (diff)
Remove support for configuring always-reuse-limit. It has never been used in 16 years...
Diffstat (limited to 'vespamalloc')
-rw-r--r--vespamalloc/etc/vespamalloc.conf1
-rw-r--r--vespamalloc/src/vespamalloc/malloc/common.h18
-rw-r--r--vespamalloc/src/vespamalloc/malloc/globalpool.h7
-rw-r--r--vespamalloc/src/vespamalloc/malloc/globalpool.hpp60
-rw-r--r--vespamalloc/src/vespamalloc/malloc/malloc.h9
-rw-r--r--vespamalloc/src/vespamalloc/malloc/memorywatcher.h11
-rw-r--r--vespamalloc/src/vespamalloc/malloc/threadlist.h4
-rw-r--r--vespamalloc/src/vespamalloc/malloc/threadpool.h7
-rw-r--r--vespamalloc/src/vespamalloc/malloc/threadpool.hpp6
9 files changed, 49 insertions, 74 deletions
diff --git a/vespamalloc/etc/vespamalloc.conf b/vespamalloc/etc/vespamalloc.conf
index c2b79061ea5..3ece047ae07 100644
--- a/vespamalloc/etc/vespamalloc.conf
+++ b/vespamalloc/etc/vespamalloc.conf
@@ -3,7 +3,6 @@
logfile stderr # default(stderr) This is the file to where log is written (stderr, stdout, filename)
# Tuning. But default is probably good.
-alwaysreuselimit 0x200000 # default(0x200000) Objects larger than this will always be returned to the segment for reuse, also by other size classes..
threadcachelimit 0x10000 # default(0x10000) Max bytes in thread local cache per size class.
fillvalue 0xa8 # default(0xa8) means not used. libvespamalloc(dXXXX).so have the possibility to fill memory on free and verify on malloc. This is to help catch use after free errors.
diff --git a/vespamalloc/src/vespamalloc/malloc/common.h b/vespamalloc/src/vespamalloc/malloc/common.h
index b1b26f6b350..2bb7df58957 100644
--- a/vespamalloc/src/vespamalloc/malloc/common.h
+++ b/vespamalloc/src/vespamalloc/malloc/common.h
@@ -52,15 +52,13 @@ static constexpr uint32_t NUM_THREADS = 16384;
#define PARANOID_CHECK3(a)
#endif
-typedef MmapMemory OSMemory;
-
-typedef int SizeClassT;
+using OSMemory = MmapMemory;
+using SizeClassT = int;
+constexpr size_t ALWAYS_REUSE_LIMIT = 0x200000ul;
-inline int msbIdx(uint64_t v) {
- int64_t result;
- __asm __volatile("bsrq %0,%0" : "=r" (result) : "0" (v));
- return result;
+inline constexpr int msbIdx(uint64_t v) {
+ return (sizeof(v)*8 - 1) - __builtin_clzl(v);
}
template <size_t MinClassSizeC>
@@ -69,14 +67,14 @@ class CommonT
public:
static constexpr size_t MAX_ALIGN = 0x200000ul;
enum {MinClassSize = MinClassSizeC};
- static inline SizeClassT sizeClass(size_t sz) {
+ static inline constexpr SizeClassT sizeClass(size_t sz) {
SizeClassT tmp(msbIdx(sz - 1) - (MinClassSizeC - 1));
return (sz <= (1 << MinClassSizeC )) ? 0 : tmp;
}
- static inline size_t classSize(SizeClassT sc) { return (size_t(1) << (sc + MinClassSizeC)); }
+ static inline constexpr size_t classSize(SizeClassT sc) { return (size_t(1) << (sc + MinClassSizeC)); }
};
-inline void crash() { *((volatile unsigned *) NULL) = 0; }
+inline void crash() { *((volatile unsigned *) nullptr) = 0; }
template <typename T>
inline void swap(T & a, T & b) { T tmp(a); a = b; b = tmp; }
diff --git a/vespamalloc/src/vespamalloc/malloc/globalpool.h b/vespamalloc/src/vespamalloc/malloc/globalpool.h
index 872fd9b936e..98f19efae31 100644
--- a/vespamalloc/src/vespamalloc/malloc/globalpool.h
+++ b/vespamalloc/src/vespamalloc/malloc/globalpool.h
@@ -27,8 +27,10 @@ public:
DataSegment<MemBlockPtrT> & dataSegment() { return _dataSegment; }
void enableThreadSupport() __attribute__((noinline));
- static void setParams(size_t alwaysReuseLimit, size_t threadCacheLimit);
- static size_t computeExactSize(size_t sz);
+ static void setParams(size_t threadCacheLimit);
+ static size_t computeExactSize(size_t sz) {
+ return (((sz + (ALWAYS_REUSE_LIMIT - 1)) / ALWAYS_REUSE_LIMIT) * ALWAYS_REUSE_LIMIT);
+ }
void info(FILE * os, size_t level=0) __attribute__((noinline));
private:
@@ -78,7 +80,6 @@ private:
std::atomic<size_t> _allocChunkList;
Stat _stat[NUM_SIZE_CLASSES];
static size_t _threadCacheLimit __attribute__((visibility("hidden")));
- static size_t _alwaysReuseLimit __attribute__((visibility("hidden")));
};
}
diff --git a/vespamalloc/src/vespamalloc/malloc/globalpool.hpp b/vespamalloc/src/vespamalloc/malloc/globalpool.hpp
index 69f2a2cf820..cd0546933ae 100644
--- a/vespamalloc/src/vespamalloc/malloc/globalpool.hpp
+++ b/vespamalloc/src/vespamalloc/malloc/globalpool.hpp
@@ -9,12 +9,10 @@ namespace vespamalloc {
template <typename MemBlockPtrT>
size_t AllocPoolT<MemBlockPtrT>::_threadCacheLimit __attribute__((visibility("hidden"))) = 0x10000;
-template <typename MemBlockPtrT>
-size_t AllocPoolT<MemBlockPtrT>::_alwaysReuseLimit __attribute__((visibility("hidden"))) = 0x200000;
template <typename MemBlockPtrT>
AllocPoolT<MemBlockPtrT>::AllocPoolT(DataSegment<MemBlockPtrT> & ds)
- : _chunkPool(NULL),
+ : _chunkPool(nullptr),
_scList(),
_dataSegment(ds),
_getChunks(0),
@@ -25,9 +23,7 @@ AllocPoolT<MemBlockPtrT>::AllocPoolT(DataSegment<MemBlockPtrT> & ds)
}
template <typename MemBlockPtrT>
-AllocPoolT<MemBlockPtrT>::~AllocPoolT()
-{
-}
+AllocPoolT<MemBlockPtrT>::~AllocPoolT() = default;
template <typename MemBlockPtrT>
void AllocPoolT<MemBlockPtrT>::enableThreadSupport()
@@ -37,9 +33,8 @@ void AllocPoolT<MemBlockPtrT>::enableThreadSupport()
template <typename MemBlockPtrT>
void
-AllocPoolT<MemBlockPtrT>::setParams(size_t alwaysReuseLimit, size_t threadCacheLimit)
+AllocPoolT<MemBlockPtrT>::setParams(size_t threadCacheLimit)
{
- _alwaysReuseLimit = alwaysReuseLimit;
_threadCacheLimit = threadCacheLimit;
}
@@ -48,16 +43,16 @@ typename AllocPoolT<MemBlockPtrT>::ChunkSList *
AllocPoolT<MemBlockPtrT>::getFree(SizeClassT sc)
{
typename ChunkSList::AtomicHeadPtr & empty = _scList[sc]._empty;
- ChunkSList * csl(NULL);
- while ((csl = ChunkSList::linkOut(empty)) == NULL) {
+ ChunkSList * csl(nullptr);
+ while ((csl = ChunkSList::linkOut(empty)) == nullptr) {
Guard sync(_mutex);
- if (empty.load(std::memory_order_relaxed)._ptr == NULL) {
+ if (empty.load(std::memory_order_relaxed)._ptr == nullptr) {
ChunkSList * ncsl(getChunks(sync, 1));
if (ncsl) {
ChunkSList::linkInList(empty, ncsl);
} else {
- assert(ncsl != NULL);
- return NULL;
+ assert(ncsl != nullptr);
+ return nullptr;
}
}
}
@@ -69,16 +64,16 @@ template <typename MemBlockPtrT>
typename AllocPoolT<MemBlockPtrT>::ChunkSList *
AllocPoolT<MemBlockPtrT>::getAlloc(SizeClassT sc)
{
- ChunkSList * csl(NULL);
+ ChunkSList * csl(nullptr);
typename ChunkSList::AtomicHeadPtr & full = _scList[sc]._full;
- while ((csl = ChunkSList::linkOut(full)) == NULL) {
+ while ((csl = ChunkSList::linkOut(full)) == nullptr) {
Guard sync(_mutex);
- if (full.load(std::memory_order_relaxed)._ptr == NULL) {
+ if (full.load(std::memory_order_relaxed)._ptr == nullptr) {
ChunkSList * ncsl(malloc(sync, sc));
if (ncsl) {
ChunkSList::linkInList(full, ncsl);
} else {
- return NULL;
+ return nullptr;
}
}
USE_STAT2(_stat[sc]._getAlloc.fetch_add(1, std::memory_order_relaxed));
@@ -122,12 +117,6 @@ AllocPoolT<MemBlockPtrT>::exchangeAlloc(SizeClassT sc, typename AllocPoolT<MemBl
}
template <typename MemBlockPtrT>
-size_t
-AllocPoolT<MemBlockPtrT>::computeExactSize(size_t sz) {
- return (((sz + (_alwaysReuseLimit - 1)) / _alwaysReuseLimit) * _alwaysReuseLimit);
-}
-
-template <typename MemBlockPtrT>
typename AllocPoolT<MemBlockPtrT>::ChunkSList *
AllocPoolT<MemBlockPtrT>::exactAlloc(size_t exactSize, SizeClassT sc,
typename AllocPoolT<MemBlockPtrT>::ChunkSList * csl)
@@ -145,10 +134,9 @@ AllocPoolT<MemBlockPtrT>::exactAlloc(size_t exactSize, SizeClassT sc,
template <typename MemBlockPtrT>
typename AllocPoolT<MemBlockPtrT>::ChunkSList *
-AllocPoolT<MemBlockPtrT>::returnMemory(SizeClassT sc,
- typename AllocPoolT<MemBlockPtrT>::ChunkSList * csl)
+AllocPoolT<MemBlockPtrT>::returnMemory(SizeClassT sc, typename AllocPoolT<MemBlockPtrT>::ChunkSList * csl)
{
- ChunkSList * completelyEmpty(NULL);
+ ChunkSList * completelyEmpty(nullptr);
#if 0
completelyEmpty = exchangeFree(sc, csl);
#else
@@ -174,15 +162,15 @@ AllocPoolT<MemBlockPtrT>::malloc(const Guard & guard, SizeClassT sc)
const size_t cs(MemBlockPtrT::classSize(sc));
size_t blockSize = cs * numBlocks;
void * block = _dataSegment.getBlock(blockSize, sc);
- ChunkSList * csl(NULL);
- if (block != NULL) {
+ ChunkSList * csl(nullptr);
+ if (block != nullptr) {
numBlocks = (blockSize + cs - 1)/cs;
const size_t blocksPerChunk(std::max(1, std::min(int(ChunkSList::NumBlocks),
int(_threadCacheLimit >> (MemBlockPtrT::MinClassSize + sc)))));
const size_t numChunks = (numBlocks+(blocksPerChunk-1))/blocksPerChunk;
csl = getChunks(guard, numChunks);
- if (csl != NULL) {
+ if (csl != nullptr) {
char *first = (char *) block;
const size_t itemSize = cs;
size_t numItems(0);
@@ -216,9 +204,9 @@ AllocPoolT<MemBlockPtrT>::getChunks(const Guard & guard, size_t numChunks)
ChunkSList * prev(csl);
bool enough(true);
for (size_t i=0; enough && (i < numChunks); i++, csl = csl->getNext()) {
- if (csl == NULL) {
+ if (csl == nullptr) {
csl = allocChunkList(guard);
- enough = (csl != NULL);
+ enough = (csl != nullptr);
if (prev) {
prev->setNext(csl);
} else {
@@ -230,9 +218,9 @@ AllocPoolT<MemBlockPtrT>::getChunks(const Guard & guard, size_t numChunks)
if (enough) {
csl = _chunkPool;
_chunkPool = prev->getNext();
- prev->setNext(NULL);
+ prev->setNext(nullptr);
} else {
- csl = NULL;
+ csl = nullptr;
}
USE_STAT2(_getChunks.fetch_add(1, std::memory_order_relaxed));
USE_STAT2(_getChunksSum.fetch_add(numChunks, std::memory_order_relaxed));
@@ -247,14 +235,14 @@ AllocPoolT<MemBlockPtrT>::allocChunkList(const Guard & guard)
(void) guard;
size_t blockSize(sizeof(ChunkSList)*0x2000);
void * block = _dataSegment.getBlock(blockSize, _dataSegment.SYSTEM_BLOCK);
- ChunkSList * newList(NULL);
- if (block != NULL) {
+ ChunkSList * newList(nullptr);
+ if (block != nullptr) {
size_t chunksInBlock(blockSize/sizeof(ChunkSList));
newList = new (block) ChunkSList[chunksInBlock];
for (size_t j=0; j < (chunksInBlock-1); j++) {
newList[j].setNext(newList+j+1);
}
- newList[chunksInBlock-1].setNext(NULL);
+ newList[chunksInBlock-1].setNext(nullptr);
}
USE_STAT2(_allocChunkList.fetch_add(1, std::memory_order_relaxed));
return newList;
diff --git a/vespamalloc/src/vespamalloc/malloc/malloc.h b/vespamalloc/src/vespamalloc/malloc/malloc.h
index e6330e7e55f..f9a749c006e 100644
--- a/vespamalloc/src/vespamalloc/malloc/malloc.h
+++ b/vespamalloc/src/vespamalloc/malloc/malloc.h
@@ -53,16 +53,15 @@ public:
void info(FILE * os, size_t level=0) __attribute__ ((noinline));
- void setupSegmentLog(size_t bigMemLogLevel, size_t bigLimit, size_t bigIncrement, size_t allocs2Show)
- {
+ void setupSegmentLog(size_t bigMemLogLevel, size_t bigLimit, size_t bigIncrement, size_t allocs2Show) {
_segment.setupLog(bigMemLogLevel, bigLimit, bigIncrement, allocs2Show);
}
void setupLog(size_t prAllocLimit) {
_prAllocLimit = prAllocLimit;
}
- void setParams(size_t alwayReuseLimit, size_t threadCacheLimit) {
- _threadList.setParams(alwayReuseLimit, threadCacheLimit);
- _allocPool.setParams(alwayReuseLimit, threadCacheLimit);
+ void setParams(size_t threadCacheLimit) {
+ _threadList.setParams(threadCacheLimit);
+ _allocPool.setParams(threadCacheLimit);
}
const DataSegment<MemBlockPtrT> & dataSegment() const { return _segment; }
private:
diff --git a/vespamalloc/src/vespamalloc/malloc/memorywatcher.h b/vespamalloc/src/vespamalloc/malloc/memorywatcher.h
index 333291c5394..b56200e2ab2 100644
--- a/vespamalloc/src/vespamalloc/malloc/memorywatcher.h
+++ b/vespamalloc/src/vespamalloc/malloc/memorywatcher.h
@@ -54,7 +54,6 @@ private:
class Params {
public:
enum {
- alwaysreuselimit = 0,
threadcachelimit,
logfile,
sigprof_loglevel,
@@ -106,8 +105,6 @@ private:
NameValuePair _params[numberofentries];
};
FILE * _logFile;
- int _infoAtAbort;
- int _infoAtNOMEM;
Params _params;
struct sigaction _oldSig;
@@ -116,7 +113,6 @@ private:
template <typename T, typename S>
MemoryWatcher<T, S>::Params::Params()
{
- _params[ alwaysreuselimit] = NameValuePair("alwaysreuselimit", "0x200000"); // 2M for allignment with hugepage size.
_params[ threadcachelimit] = NameValuePair("threadcachelimit", "0x10000"); // 64K
_params[ logfile] = NameValuePair("logfile", "stderr");
_params[ sigprof_loglevel] = NameValuePair("sigprof_loglevel", "1");
@@ -157,9 +153,7 @@ void MemoryWatcher<T, S>::NameValuePair::value(const char * v) {
template <typename T, typename S>
MemoryWatcher<T, S>::MemoryWatcher(int infoAtEnd, size_t prAllocAtStart) :
MemoryManager<T, S>(prAllocAtStart),
- _logFile(stderr),
- _infoAtAbort(-1),
- _infoAtNOMEM(1)
+ _logFile(stderr)
{
_manager = this;
char tmp[16];
@@ -206,8 +200,7 @@ void MemoryWatcher<T, S>::activateOptions()
_params[Params::bigsegment_increment].valueAsLong(),
_params[Params::allocs2show].valueAsLong());
this->setupLog(_params[Params::pralloc_loglimit].valueAsLong());
- this->setParams(_params[Params::alwaysreuselimit].valueAsLong(),
- _params[Params::threadcachelimit].valueAsLong());
+ this->setParams(_params[Params::threadcachelimit].valueAsLong());
T::bigBlockLimit(_params[Params::bigblocklimit].valueAsLong());
T::setFill(_params[Params::fillvalue].valueAsLong());
diff --git a/vespamalloc/src/vespamalloc/malloc/threadlist.h b/vespamalloc/src/vespamalloc/malloc/threadlist.h
index 9edf086ca96..91409eb2c95 100644
--- a/vespamalloc/src/vespamalloc/malloc/threadlist.h
+++ b/vespamalloc/src/vespamalloc/malloc/threadlist.h
@@ -19,8 +19,8 @@ public:
using AllocPool = AllocPoolT<MemBlockPtrT>;
ThreadListT(AllocPool & pool);
~ThreadListT();
- void setParams(size_t alwayReuseLimit, size_t threadCacheLimit) {
- ThreadPool::setParams(alwayReuseLimit, threadCacheLimit);
+ void setParams(size_t threadCacheLimit) {
+ ThreadPool::setParams(threadCacheLimit);
}
bool quitThisThread();
bool initThisThread();
diff --git a/vespamalloc/src/vespamalloc/malloc/threadpool.h b/vespamalloc/src/vespamalloc/malloc/threadpool.h
index d4a754532ff..493369a4441 100644
--- a/vespamalloc/src/vespamalloc/malloc/threadpool.h
+++ b/vespamalloc/src/vespamalloc/malloc/threadpool.h
@@ -37,7 +37,7 @@ public:
uint32_t threadId() const { return _threadId; }
void quit() { _osThreadId = 0; } // Implicit memory barrier
void init(int thrId);
- static void setParams(size_t alwayReuseLimit, size_t threadCacheLimit);
+ static void setParams(size_t threadCacheLimit);
bool grabAvailable();
private:
bool hasActuallyBeenUsed() const;
@@ -62,7 +62,7 @@ private:
ChunkSList *_freeTo;
};
void mallocHelper(size_t exactSize, SizeClassT sc, AllocFree & af, MemBlockPtrT & mem) __attribute__ ((noinline));
- static bool alwaysReuse(SizeClassT sc) { return sc > _alwaysReuseSCLimit; }
+ static constexpr bool alwaysReuse(SizeClassT sc) { return sc > ALWAYS_REUSE_SC_LIMIT; }
AllocPool * _allocPool;
AllocFree _memList[NUM_SIZE_CLASSES];
@@ -70,7 +70,8 @@ private:
uint32_t _threadId;
std::atomic<ssize_t> _osThreadId;
- static SizeClassT _alwaysReuseSCLimit __attribute__((visibility("hidden")));
+ static constexpr SizeClassT ALWAYS_REUSE_SC_LIMIT = std::max(MemBlockPtrT::sizeClass(ALWAYS_REUSE_LIMIT),
+ SizeClassT(MemBlockPtrT::SizeClassSpan));
static size_t _threadCacheLimit __attribute__((visibility("hidden")));
};
diff --git a/vespamalloc/src/vespamalloc/malloc/threadpool.hpp b/vespamalloc/src/vespamalloc/malloc/threadpool.hpp
index b28aa144c34..b4ce1b6d6d0 100644
--- a/vespamalloc/src/vespamalloc/malloc/threadpool.hpp
+++ b/vespamalloc/src/vespamalloc/malloc/threadpool.hpp
@@ -6,8 +6,6 @@
namespace vespamalloc {
template <typename MemBlockPtrT, typename ThreadStatT>
-SizeClassT ThreadPoolT<MemBlockPtrT, ThreadStatT>::_alwaysReuseSCLimit __attribute__((visibility("hidden"))) = MemBlockPtrT::sizeClass(0x200000);
-template <typename MemBlockPtrT, typename ThreadStatT>
size_t ThreadPoolT<MemBlockPtrT, ThreadStatT>::_threadCacheLimit __attribute__((visibility("hidden"))) = 0x10000;
template <typename MemBlockPtrT, typename ThreadStatT>
@@ -188,10 +186,8 @@ void ThreadPoolT<MemBlockPtrT, ThreadStatT>::init(int thrId)
}
template <typename MemBlockPtrT, typename ThreadStatT >
-void ThreadPoolT<MemBlockPtrT, ThreadStatT>::setParams(size_t alwaysReuseLimit, size_t threadCacheLimit)
+void ThreadPoolT<MemBlockPtrT, ThreadStatT>::setParams(size_t threadCacheLimit)
{
- _alwaysReuseSCLimit = std::max(MemBlockPtrT::sizeClass(alwaysReuseLimit),
- SizeClassT(MemBlockPtrT::SizeClassSpan));
_threadCacheLimit = threadCacheLimit;
}