aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/balloc/lib/alloc_stats.cpp
blob: 3481cad56c8c6434ebbe86d2bde098d35833956a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <library/cpp/balloc/lib/alloc_stats.h>

#include <util/system/compiler.h>
#include <atomic>


namespace NAllocStats {

struct TThreadAllocStats {
    i64 CurrSize = 0;
    i64 MaxSize = 0;
};

struct TGlobalAllocStats {
    std::atomic<ui64> LiveLock = {0};
    std::atomic<ui64> Mmap = {0};
};

#if defined(_unix_) && !defined(_darwin_)

__thread bool isEnabled = false;

bool IsEnabled() noexcept {
    return isEnabled;
}

void EnableAllocStats(bool enable) noexcept {
    isEnabled = enable;
}

__thread TThreadAllocStats threadAllocStats;

void IncThreadAllocStats(i64 size) noexcept {
    threadAllocStats.CurrSize += size;
    if (Y_UNLIKELY(threadAllocStats.CurrSize > threadAllocStats.MaxSize)) {
        threadAllocStats.MaxSize = threadAllocStats.CurrSize;
    }
}

void DecThreadAllocStats(i64 size) noexcept {
    threadAllocStats.CurrSize -= size;
}

void ResetThreadAllocStats() noexcept {
    threadAllocStats.CurrSize = 0;
    threadAllocStats.MaxSize = 0;
}

i64 GetThreadAllocMax() noexcept {
    return threadAllocStats.MaxSize;
}

#else // _unix_ && ! _darwin_

bool IsEnabled() noexcept {
    return false;
}
void EnableAllocStats(bool /*enable*/) noexcept {
}
void IncThreadAllocStats(i64 /*size*/) noexcept {
}
void DecThreadAllocStats(i64 /*size*/) noexcept {
}
void ResetThreadAllocStats() noexcept {
}
i64 GetThreadAllocMax() noexcept {
    return 0;
}

#endif // _unix_ && ! _darwin_


#if defined(_x86_64_) || defined(_i386_)
    static constexpr size_t CACHE_LINE_SIZE = 64;
#elif defined(_arm64_) || defined(_ppc64_)
    static constexpr size_t CACHE_LINE_SIZE = 128;
#else
    static constexpr size_t CACHE_LINE_SIZE = 256; // default large enough
#endif

template <typename T>
struct alignas(sizeof(T)) TCacheLineDoublePaddedAtomic {
    char Prefix[CACHE_LINE_SIZE - sizeof(T)];
    T Value;
    char Postfix[CACHE_LINE_SIZE - sizeof(T)];
};

TCacheLineDoublePaddedAtomic<TGlobalAllocStats> GlobalCounters;

void IncLiveLockCounter() noexcept {
    GlobalCounters.Value.LiveLock.fetch_add(1, std::memory_order_seq_cst);
}

ui64 GetLiveLockCounter() noexcept {
    return GlobalCounters.Value.LiveLock.load(std::memory_order_acquire);
}

void IncMmapCounter(ui64 amount) noexcept {
    GlobalCounters.Value.Mmap.fetch_add(amount, std::memory_order_seq_cst);
}

ui64 GetMmapCounter() noexcept {
    return GlobalCounters.Value.Mmap.load(std::memory_order_acquire);
}

}  // namespace NAllocStats