Skip to content

Commit dc7000c

Browse files
committed
Update for V5.8
1 parent 7a39035 commit dc7000c

File tree

9 files changed

+426
-36
lines changed

9 files changed

+426
-36
lines changed

utility/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ $(srcdir)/util/file.cpp \
1616
$(srcdir)/util/file.h \
1717
$(srcdir)/util/net.cpp \
1818
$(srcdir)/util/net.h \
19+
$(srcdir)/util/numeric.cpp \
20+
$(srcdir)/util/numeric.h \
1921
$(srcdir)/util/os.cpp \
2022
$(srcdir)/util/os.h \
2123
$(srcdir)/util/system.cpp \

utility/util/allocator.cpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -895,9 +895,12 @@ void FixedSizeCachedAllocator::setLimit(
895895

896896
AllocatorLimitter* FixedSizeCachedAllocator::setLimit(
897897
AllocatorStats::Type type, AllocatorLimitter *limitter, bool force) {
898-
static_cast<void>(type);
899-
static_cast<void>(limitter);
900-
static_cast<void>(force);
898+
if (localAlloc_.get() != NULL) {
899+
localAlloc_->setLimit(type, limitter, force);
900+
}
901+
if (localLockedAlloc_.get() != NULL) {
902+
localLockedAlloc_->setLimit(type, limitter, force);
903+
}
901904
return NULL;
902905
}
903906

@@ -1419,8 +1422,6 @@ void* StackAllocator::allocateOverBlock(size_t size) {
14191422
hugeCount_++;
14201423
hugeSize_ += blockSize;
14211424

1422-
stats_.values_[AllocatorStats::STAT_TOTAL_SIZE] =
1423-
AllocatorStats::asStatValue(getTotalSizeForStats());
14241425
stats_.values_[AllocatorStats::STAT_PEAK_TOTAL_SIZE] = std::max(
14251426
stats_.values_[AllocatorStats::STAT_PEAK_TOTAL_SIZE],
14261427
stats_.values_[AllocatorStats::STAT_TOTAL_SIZE]);
@@ -1441,6 +1442,8 @@ void* StackAllocator::allocateOverBlock(size_t size) {
14411442
restSize_ = newBlock->bodySize() - size;
14421443

14431444
totalSize_ += newBlock->blockSize_;
1445+
stats_.values_[AllocatorStats::STAT_TOTAL_SIZE] =
1446+
AllocatorStats::asStatValue(getTotalSizeForStats());
14441447

14451448
return newBlock->body();
14461449
#endif
@@ -1805,7 +1808,9 @@ void AllocatorManager::setSharingLimitterGroup(GroupId id, GroupId sharingId) {
18051808
assert(sharingEntry.totalLimitter_ != NULL);
18061809

18071810
entry.sharingLimitterId_ = sharingId;
1808-
entry.totalLimitter_ = sharingEntry.totalLimitter_;
1811+
setLimit(id, LIMIT_GROUP_TOTAL_SIZE, std::numeric_limits<size_t>::max());
1812+
1813+
assert(entry.totalLimitter_ != NULL);
18091814
}
18101815

18111816
int64_t AllocatorManager::estimateHeapUsage(
@@ -1869,7 +1874,7 @@ void AllocatorManager::applyAllocatorLimit(
18691874
switch (limitType) {
18701875
case LIMIT_GROUP_TOTAL_SIZE:
18711876
command = COMMAND_SET_TOTAL_LIMITTER;
1872-
type = AllocatorStats::STAT_TYPE_END;
1877+
type = AllocatorStats::STAT_GROUP_TOTAL_LIMIT;
18731878
if (groupEntry.totalLimitter_ == NULL) {
18741879
return;
18751880
}
@@ -2119,6 +2124,7 @@ AllocatorLimitter& AllocatorManager::prepareTotalLimitter(
21192124
else {
21202125
entry.totalLimitter_ =
21212126
&prepareTotalLimitter(entry.sharingLimitterId_, found);
2127+
found = false;
21222128
}
21232129
}
21242130
else {
@@ -2243,6 +2249,7 @@ AllocatorLimitter::AllocatorLimitter(
22432249
limit_(std::numeric_limits<size_t>::max()),
22442250
acquired_(0),
22452251
reserved_(0),
2252+
peakUsage_(0),
22462253
failOnExcess_(false),
22472254
errorHandler_(NULL) {
22482255
}
@@ -2251,6 +2258,18 @@ AllocatorLimitter::~AllocatorLimitter() {
22512258
assert(acquired_ == 0);
22522259
}
22532260

2261+
AllocatorLimitter::Stats AllocatorLimitter::getStats() {
2262+
util::LockGuard<util::Mutex> guard(mutex_);
2263+
2264+
Stats stats;
2265+
stats.usage_ = getLocalUsageSize();
2266+
stats.peakUsage_ = peakUsage_;
2267+
stats.limit_ = limit_;
2268+
stats.failOnExcess_ = failOnExcess_;
2269+
2270+
return stats;
2271+
}
2272+
22542273
void AllocatorLimitter::setFailOnExcess(bool enabled) {
22552274
util::LockGuard<util::Mutex> guard(mutex_);
22562275
failOnExcess_ = enabled;
@@ -2278,6 +2297,7 @@ size_t AllocatorLimitter::acquire(
22782297
const size_t size =
22792298
acquireLocal(requestingMin, requestingDesired, force, requester);
22802299
reserved_ -= std::min(reserved_, size);
2300+
updatePeakUsageSize();
22812301
return size;
22822302
}
22832303

@@ -2296,6 +2316,7 @@ void AllocatorLimitter::shrinkReservation(size_t size) {
22962316
const size_t actualSize = std::min(reserved_, size);
22972317
releaseLocal(actualSize);
22982318
reserved_ -= actualSize;
2319+
updatePeakUsageSize();
22992320
}
23002321

23012322
size_t AllocatorLimitter::getAvailableSize() {
@@ -2388,6 +2409,17 @@ size_t AllocatorLimitter::getLocalAvailableSize() {
23882409
return limit_ - acquired_;
23892410
}
23902411

2412+
size_t AllocatorLimitter::getLocalUsageSize() {
2413+
return acquired_ - reserved_;
2414+
}
2415+
2416+
void AllocatorLimitter::updatePeakUsageSize() {
2417+
const size_t current = getLocalUsageSize();
2418+
if (current > peakUsage_) {
2419+
peakUsage_ = current;
2420+
}
2421+
}
2422+
23912423
const AllocatorLimitter& AllocatorLimitter::resolveRequester(
23922424
const AllocatorLimitter *base) {
23932425
if (base == NULL) {
@@ -2447,4 +2479,11 @@ AllocatorLimitter::Scope::~Scope() {
24472479
unbinder_(allocator_, orgLimitter_);
24482480
}
24492481

2482+
AllocatorLimitter::Stats::Stats() :
2483+
usage_(0),
2484+
peakUsage_(0),
2485+
limit_(0),
2486+
failOnExcess_(false) {
2487+
}
2488+
24502489
}

utility/util/allocator.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,11 +2228,13 @@ static AllocatorManager::Initializer g_allocatorManagerInitializer;
22282228
class AllocatorLimitter {
22292229
public:
22302230
class Scope;
2231+
struct Stats;
22312232

22322233
AllocatorLimitter(const AllocatorInfo &info, AllocatorLimitter *parent);
22332234
~AllocatorLimitter();
22342235

2235-
size_t getLimit();
2236+
Stats getStats();
2237+
22362238
void setLimit(size_t size);
22372239
void setFailOnExcess(bool enabled);
22382240

@@ -2260,6 +2262,8 @@ class AllocatorLimitter {
22602262
void releaseLocal(size_t size);
22612263

22622264
size_t getLocalAvailableSize();
2265+
size_t getLocalUsageSize();
2266+
void updatePeakUsageSize();
22632267

22642268
const AllocatorLimitter& resolveRequester(const AllocatorLimitter *base);
22652269
bool resolveFailOnExcess(
@@ -2273,6 +2277,7 @@ class AllocatorLimitter {
22732277
size_t limit_;
22742278
size_t acquired_;
22752279
size_t reserved_;
2280+
size_t peakUsage_;
22762281
bool failOnExcess_;
22772282
util::Mutex mutex_;
22782283
util::AllocationErrorHandler *errorHandler_;
@@ -2295,6 +2300,15 @@ class AllocatorLimitter::Scope {
22952300
UnbindFunc unbinder_;
22962301
};
22972302

2303+
struct AllocatorLimitter::Stats {
2304+
Stats();
2305+
2306+
size_t usage_;
2307+
size_t peakUsage_;
2308+
size_t limit_;
2309+
bool failOnExcess_;
2310+
};
2311+
22982312
/*!
22992313
@brief STL string template for using allocators with members.
23002314
*/
@@ -3131,6 +3145,12 @@ inline void FixedSizeAllocator<Mutex>::acquireForRequester(
31313145
if (requester.acquire(elementSize_, limitter_)) {
31323146
assert(totalElementCount_ > 0);
31333147
totalElementCount_--;
3148+
3149+
int64_t &statValue = stats_.values_[AllocatorStats::STAT_TOTAL_SIZE];
3150+
const int64_t statSize = static_cast<int64_t>(elementSize_);
3151+
3152+
assert(statValue >= statSize);
3153+
statValue -= statSize;
31343154
}
31353155
}
31363156

@@ -3140,6 +3160,11 @@ inline void FixedSizeAllocator<Mutex>::releaseForRequester(
31403160
const R &requester) {
31413161
if (requester.release(elementSize_, limitter_)) {
31423162
totalElementCount_++;
3163+
3164+
int64_t &statValue = stats_.values_[AllocatorStats::STAT_TOTAL_SIZE];
3165+
const int64_t statSize = static_cast<int64_t>(elementSize_);
3166+
3167+
statValue += statSize;
31433168
}
31443169
}
31453170

@@ -3549,6 +3574,9 @@ AllocatorLimitter* VariableSizeAllocator<Mutex, Traits>::setLimit(
35493574
case AllocatorStats::STAT_GROUP_TOTAL_LIMIT:
35503575
limitter_ = AllocatorLimitter::moveSize(
35513576
limitter, limitter_, hugeElementSize_, force);
3577+
for (size_t i = 0; i < FIXED_ALLOCATOR_COUNT; i++) {
3578+
baseList_[i]->setLimit(type, limitter, force);
3579+
}
35523580
break;
35533581
default:
35543582
break;
@@ -4190,12 +4218,12 @@ inline void AllocatorManager::Accessor<Alloc>::access(
41904218
target->getStats(*params.stats_);
41914219
break;
41924220
case COMMAND_SET_TOTAL_LIMITTER:
4193-
target->setLimit(params.type_, params.size_);
4194-
break;
4195-
case COMMAND_SET_EACH_LIMIT:
41964221
assert(params.limitter_ != NULL);
41974222
target->setLimit(params.type_, params.limitter_);
41984223
break;
4224+
case COMMAND_SET_EACH_LIMIT:
4225+
target->setLimit(params.type_, params.size_);
4226+
break;
41994227
#if UTIL_ALLOCATOR_DIFF_REPORTER_TRACE_ENABLED
42004228
case COMMAND_SAVE_REPORTER_SNAPSHOT: {
42014229
LockGuard<MutexType> guard(ManagerTool::getLock(*target));

utility/util/file.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,13 +1566,13 @@ bool Directory::nextEntry(u8string &name) {
15661566
name.clear();
15671567

15681568
#ifdef UTIL_HAVE_OPENDIR
1569-
DirEnt entryBuf;
15701569
struct dirent *result;
1571-
if (readdir_r(data_->dir_, &entryBuf.body_, &result) != 0) {
1572-
UTIL_THROW_PLATFORM_ERROR(NULL);
1573-
}
1574-
1570+
errno = 0;
1571+
result = readdir(data_->dir_);
15751572
if (result == NULL) {
1573+
if (errno != 0) {
1574+
UTIL_THROW_PLATFORM_ERROR(NULL);
1575+
}
15761576
return false;
15771577
}
15781578

utility/util/numeric.h

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "util/type.h"
2525
#include <limits>
26+
#include <climits>
2627

2728
#if UTIL_CXX11_SUPPORTED
2829
#include <cmath>
@@ -34,11 +35,15 @@
3435

3536
namespace util {
3637

38+
3739
template<typename T> bool isInf(const T &value);
3840
template<typename T> bool isFinite(const T &value);
3941
template<typename T> bool isNaN(const T &value);
4042
template<typename T> T copySign(const T &value1, const T &value2);
4143

44+
/**
45+
* 数値の算術演算ユーティリティ
46+
*/
4247
struct NumberArithmetic {
4348
public:
4449
template<typename T, typename H> static T add(
@@ -193,6 +198,106 @@ struct ArithmeticErrorHandlers::Checked {
193198
UtilityException::Code &errorCode_;
194199
};
195200

201+
/**
202+
* 固定長データ管理型の、double値(IEEE754の64ビット浮動小数点数)の合計値表現
203+
*
204+
* ほぼ任意回数(最大2^64回)のdouble値の加減算を繰り返しても、一切桁落ちしない。
205+
* 無限大、NaNの追加回数を記憶できる。その回数分除外操作をすると、それらの
206+
* 追加前のdouble値を参照できる。
207+
*/
208+
class FixedDoubleSum {
209+
public:
210+
211+
FixedDoubleSum();
212+
213+
void add(double value);
214+
215+
void remove(double value);
216+
217+
double get() const;
218+
219+
private:
220+
enum MergeMode {
221+
MODE_ADD,
222+
MODE_SUBTRACT_NORMAL,
223+
MODE_SUBTRACT_REVERSED
224+
};
225+
226+
enum {
227+
UNIT_BIT = (sizeof(uint64_t) * CHAR_BIT),
228+
229+
MAX_EXPONENT = (std::numeric_limits<double>::max_exponent - 1),
230+
MIN_EXPONENT = (std::numeric_limits<double>::min_exponent - 1),
231+
EXPONENT_RANGE = (MAX_EXPONENT - MIN_EXPONENT + 1),
232+
233+
MANTISSA_IMPLICIT_BIT = 1,
234+
MANTISSA_BIT = (
235+
std::numeric_limits<double>::digits -
236+
MANTISSA_IMPLICIT_BIT),
237+
EXPONENT_BIT = (sizeof(double) * CHAR_BIT - MANTISSA_BIT - 1),
238+
239+
FINITE_VALUE_BIT = (
240+
UNIT_BIT +
241+
EXPONENT_RANGE +
242+
MANTISSA_BIT),
243+
244+
FINITE_VALUE_SIZE = ((FINITE_VALUE_BIT + UNIT_BIT - 1) / UNIT_BIT)
245+
};
246+
247+
typedef uint64_t FiniteValue[FINITE_VALUE_SIZE];
248+
typedef std::pair<uint64_t, uint64_t> FiniteValuePart;
249+
250+
uint64_t& getSpecialValueCounter(double value);
251+
bool findSpecialValue(double &value) const;
252+
253+
void addFiniteValue(double value);
254+
255+
MergeMode getMergeMode(
256+
uint64_t mantissa, uint32_t exponent, bool sign,
257+
bool &nextSign) const;
258+
int32_t compareFiniteValue(uint64_t mantissa, uint32_t exponent) const;
259+
260+
static uint32_t getAmountPosition(
261+
MergeMode mode, uint32_t exponent, bool lower);
262+
static uint64_t getAmountPart(
263+
uint64_t mantissa, uint32_t exponent, uint32_t unitPos);
264+
265+
static FiniteValuePart getFiniteValuePart(
266+
const FiniteValue &finiteValue, uint32_t exponent);
267+
static uint64_t mergeFiniteValuePart(
268+
MergeMode mode, uint64_t target, uint64_t amount, bool lastCarry,
269+
bool &nextCarry);
270+
static uint64_t mergeFiniteValuePartWithLastCarry(
271+
MergeMode mode, uint64_t target, uint64_t amount, bool &nextCarry);
272+
static uint32_t resolveExponent(
273+
const FiniteValue &finiteValue, uint32_t curPos, uint32_t lastExponent);
274+
275+
static void decomposeValue(
276+
double value, uint64_t &mantissa, uint32_t &exponent);
277+
static double makeFiniteValue(
278+
const FiniteValuePart &valuePart, uint32_t exponent, bool sign);
279+
280+
static uint64_t valueToBits(double value);
281+
static double bitsToValue(uint64_t bits);
282+
283+
static bool isSpecialValue(double value);
284+
static bool isNegativeZero(double value);
285+
286+
static void initializeFiniteValue(FiniteValue &value);
287+
288+
static void errorNegativeCount();
289+
290+
FiniteValue finiteValue_;
291+
292+
uint64_t negativeZeroCount_;
293+
uint64_t positiveInfCount_;
294+
uint64_t negativeInfCount_;
295+
uint64_t nanCount_;
296+
297+
uint32_t exponent_;
298+
bool sign_;
299+
};
300+
196301
}
197302

198303
namespace util {

0 commit comments

Comments
 (0)