Coverage Report

Created: 2026-03-13 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/runtime/memory/mem_counter.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
// This file is copied from
18
#pragma once
19
20
#include <atomic>
21
#include <cstdint>
22
#include <string>
23
24
#include "common/compiler_util.h"
25
#include "util/pretty_printer.h"
26
27
namespace doris {
28
#include "common/compile_check_begin.h"
29
30
/*
31
 * A counter that keeps track of the current and peak memory usage seen.
32
 * Relaxed ordering, not accurate in real time.
33
 *
34
 * This class is thread-safe.
35
*/
36
class MemCounter {
37
public:
38
9.63M
    MemCounter() = default;
39
40
71.2M
    void add(int64_t delta) {
41
71.2M
        if (UNLIKELY(delta == 0)) {
42
2.82M
            return;
43
2.82M
        }
44
68.4M
        int64_t value = _current_value.fetch_add(delta, std::memory_order_relaxed) + delta;
45
68.4M
        update_peak(value);
46
68.4M
    }
47
48
0
    void add_no_update_peak(int64_t delta) { // need extreme fast
49
0
        _current_value.fetch_add(delta, std::memory_order_relaxed);
50
0
    }
51
52
8.11M
    bool try_add(int64_t delta, int64_t max) {
53
8.11M
        if (UNLIKELY(delta == 0)) {
54
0
            return true;
55
0
        }
56
8.11M
        int64_t cur_val = _current_value.load(std::memory_order_relaxed);
57
8.11M
        int64_t new_val = 0;
58
8.13M
        do {
59
8.13M
            new_val = cur_val + delta;
60
8.13M
            if (UNLIKELY(new_val > max)) {
61
1
                return false;
62
1
            }
63
8.13M
        } while (UNLIKELY(!_current_value.compare_exchange_weak(cur_val, new_val,
64
8.11M
                                                                std::memory_order_relaxed)));
65
8.11M
        update_peak(new_val);
66
8.11M
        return true;
67
8.11M
    }
68
69
21.7M
    void sub(int64_t delta) { _current_value.fetch_sub(delta, std::memory_order_relaxed); }
70
71
476k
    void set(int64_t v) {
72
476k
        _current_value.store(v, std::memory_order_relaxed);
73
476k
        update_peak(v);
74
476k
    }
75
76
77.0M
    void update_peak(int64_t value) {
77
77.0M
        int64_t pre_value = _peak_value.load(std::memory_order_relaxed);
78
77.1M
        while (value > pre_value &&
79
77.1M
               !_peak_value.compare_exchange_weak(pre_value, value, std::memory_order_relaxed)) {
80
7.86k
        }
81
77.0M
    }
82
83
90.7M
    int64_t current_value() const { return _current_value.load(std::memory_order_relaxed); }
84
47.6M
    int64_t peak_value() const { return _peak_value.load(std::memory_order_relaxed); }
85
86
private:
87
    std::atomic<int64_t> _current_value {0};
88
    std::atomic<int64_t> _peak_value {0};
89
};
90
91
#include "common/compile_check_end.h"
92
} // namespace doris