Skip to content

Commit a1b4091

Browse files
authored
MultiSizeBufferPool: remove invalid thrown exception, avoid overflow (#2960)
Due to the thread model of the pool, which avoid as much as possible from locking, I have to remove one of the exception thrown. The exception logic is invalid in some rare cases. Furthermore, due to the chance for overflow, we convert some of the statistics class members into signed integers - overflow on unsigned integers is undefined according to the C++ standard.
1 parent d17685d commit a1b4091

File tree

2 files changed

+21
-27
lines changed

2 files changed

+21
-27
lines changed

libs/util/MultiSizeBufferPool.hpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -253,39 +253,39 @@ class MultiSizeBufferPool {
253253
// Subpool level:
254254
// numAllocatedBytes_ + numNonAllocatedBytes_ = SubpoolConfig::numMaxBuffers * (SubpoolConfig::bufferSize +
255255
// chunkMetadataSize())
256-
std::atomic_uint64_t numAllocatedBytes_{};
257-
std::atomic_uint64_t numNonAllocatedBytes_{};
256+
std::atomic_int64_t numAllocatedBytes_{};
257+
std::atomic_int64_t numNonAllocatedBytes_{};
258258

259259
// numAllocatedBytes_ = numUnusedBytes_ + numUsedBytes_
260-
std::atomic_uint64_t numUsedBytes_{};
261-
std::atomic_uint64_t numUnusedBytes_{};
260+
std::atomic_int64_t numUsedBytes_{};
261+
std::atomic_int64_t numUnusedBytes_{};
262262

263263
// numAllocatedChunks_ + numNonAllocatedChunks_ = SubpoolConfig::numMaxBuffers
264-
std::atomic_uint64_t numAllocatedChunks_{};
265-
std::atomic_uint64_t numNonAllocatedChunks_{};
264+
std::atomic_int64_t numAllocatedChunks_{};
265+
std::atomic_int64_t numNonAllocatedChunks_{};
266266

267267
// numAllocatedChunks_ = numUsedChunks_ + numUnusedChunks_
268-
std::atomic_uint64_t numUsedChunks_{};
269-
std::atomic_uint64_t numUnusedChunks_{};
268+
std::atomic_int64_t numUsedChunks_{};
269+
std::atomic_int64_t numUnusedChunks_{};
270270
} current_;
271271

272272
// Overall statistics are accumulating
273273
struct OverallStatistics {
274-
std::atomic_uint64_t numAllocatedBytes_{};
275-
std::atomic_uint64_t numDeletedBytes_{};
276-
std::atomic_uint64_t numUsedBytes_{};
274+
std::atomic_int64_t numAllocatedBytes_{};
275+
std::atomic_int64_t numDeletedBytes_{};
276+
std::atomic_int64_t numUsedBytes_{};
277277

278-
std::atomic_uint64_t numAllocatedChunks_{};
279-
std::atomic_uint64_t numDeletedChunks_{};
280-
std::atomic_uint64_t numUsedChunks_{};
278+
std::atomic_int64_t numAllocatedChunks_{};
279+
std::atomic_int64_t numDeletedChunks_{};
280+
std::atomic_int64_t numUsedChunks_{};
281281

282282
// Amount of times where a chunk did not fit into the needed buffer size and returned to pool without use
283-
std::atomic_uint64_t numBufferUsageFailed_{};
283+
std::atomic_int64_t numBufferUsageFailed_{};
284284
// Amount of times where a chunk fit into the needed buffer size and returned to pool without use
285-
std::atomic_uint64_t numBufferUsageSuccess_{};
285+
std::atomic_int64_t numBufferUsageSuccess_{};
286286

287-
std::atomic_uint64_t maxNumAllocatedBytes_{};
288-
std::atomic_uint64_t maxNumAllocatedChunks_{};
287+
std::atomic_int64_t maxNumAllocatedBytes_{};
288+
std::atomic_int64_t maxNumAllocatedChunks_{};
289289
} overall_;
290290

291291
// relevant only if reportOnChangesOnly_ is true. Used to mark if the content need to be reported, only if there was
@@ -337,7 +337,7 @@ class MultiSizeBufferPool {
337337

338338
std::atomic_bool stopFlag_;
339339
std::atomic_bool purgeFlag_;
340-
std::atomic_uint64_t purgeLimit_;
340+
std::atomic_int64_t purgeLimit_;
341341
const logging::Logger& logger_;
342342
std::string name_;
343343
const uint32_t chunkSize_;

libs/util/src/MultiSizeBufferPool.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -545,12 +545,6 @@ MultiSizeBufferPool::SubPool::AllocationResult MultiSizeBufferPool::SubPool::get
545545

546546
void MultiSizeBufferPool::SubPool::returnChunk(char* chunk) {
547547
DEBUG_PRINT(logger_, "returnChunk enter" << KVLOG(KVLOG_PREFIX));
548-
if ((stats_.current_.numUsedChunks_ == 0) || (stats_.current_.numUnusedChunks_ == config_.numMaxBuffers)) {
549-
std::stringstream ss;
550-
ss << KVLOG(KVLOG_PREFIX, config_.numMaxBuffers, (void*)chunk) << stats_;
551-
throwException<std::runtime_error>(logger_, "No more chunks are marked as unused:", ss.str());
552-
}
553-
554548
bool shouldPurge = (purgeFlag_ && (stats_.current_.numAllocatedChunks_ > purgeLimit_));
555549
auto opType = shouldPurge ? Statistics::operationType::DELETE : Statistics::operationType::PUSH;
556550
stats_.onChunkBecomeUnused(chunkSize_, opType);
@@ -587,7 +581,7 @@ std::pair<char*, MultiSizeBufferPool::SubPool::AllocationStatus> MultiSizeBuffer
587581
return std::make_pair(nullptr, AllocationStatus::EXCEED_MAX_BUFFERS);
588582
}
589583
if ((poolConfig_.maxAllocatedBytes != 0) &&
590-
((poolStats_.current_.numAllocatedBytes_ + chunkSize_) > poolConfig_.maxAllocatedBytes)) {
584+
((poolStats_.current_.numAllocatedBytes_ + chunkSize_) > static_cast<int64_t>(poolConfig_.maxAllocatedBytes))) {
591585
LOG_WARN(logger_, "allocateChunk exit" << KVLOG(KVLOG_PREFIX));
592586
return std::make_pair(nullptr, AllocationStatus::EXCEED_POOL_MAX_BYTES);
593587
}
@@ -688,7 +682,7 @@ void MultiSizeBufferPool::Statistics::onInit(uint32_t numMaxBuffers, uint32_t ch
688682

689683
void MultiSizeBufferPool::Statistics::setLimits(uint64_t maxAllocatedBytes) {
690684
if (maxAllocatedBytes == 0) return;
691-
if (maxAllocatedBytes < current_.numNonAllocatedBytes_) {
685+
if (static_cast<int64_t>(maxAllocatedBytes) < current_.numNonAllocatedBytes_) {
692686
current_.numNonAllocatedBytes_ = maxAllocatedBytes;
693687
}
694688
}

0 commit comments

Comments
 (0)