• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

llnl / dftracer-utils / 28286012595

27 Jun 2026 10:04AM UTC coverage: 51.056% (-1.3%) from 52.356%
28286012595

Pull #79

github

web-flow
Merge 6c6535a19 into 8eb383f39
Pull Request #79: Add Valgrind memory checking (C++, Python, MPI) and fix the bugs it found

32079 of 80165 branches covered (40.02%)

Branch coverage included in aggregate %.

129 of 149 new or added lines in 11 files covered. (86.58%)

5116 existing lines in 181 files now uncovered.

32739 of 46790 relevant lines covered (69.97%)

9929.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

53.09
/src/dftracer/utils/core/tasks/task_result.cpp
1
#include <dftracer/utils/core/tasks/task_result.h>
2

3
#include <cassert>
4

5
namespace dftracer::utils {
6

7
void TaskResult::set_value(std::any value) {
760✔
8
    value_ = std::move(value);
760✔
9
    publish(State::value);
760✔
10
}
760✔
11

12
void TaskResult::set_exception(std::exception_ptr ex) {
17✔
13
    exception_ = ex;
17✔
14
    publish(State::exception);
17✔
15
}
17✔
16

17
void TaskResult::set_cancelled() { publish(State::cancelled); }
×
18

19
void TaskResult::mark_running() {
773✔
20
    auto expected = static_cast<std::uint8_t>(State::pending);
773✔
21
    state_.compare_exchange_strong(
773✔
22
        expected, static_cast<std::uint8_t>(State::running),
23
        std::memory_order_release, std::memory_order_relaxed);
24
}
773✔
25

26
void TaskResult::add_reader() {
561✔
27
    pending_readers_.fetch_add(1, std::memory_order_relaxed);
561✔
28
}
561✔
29

30
void TaskResult::release_reader() {
527✔
31
    int prev = pending_readers_.fetch_sub(1, std::memory_order_acq_rel);
527✔
32
    if (prev == 1) {
527✔
33
        // Last reader released -- free value memory
34
        std::lock_guard<std::mutex> lock(mutex_);
326✔
35
        value_ = std::any{};
326✔
36
    }
326✔
37
}
527✔
38

39
void TaskResult::publish(State s) {
775✔
40
    std::vector<std::coroutine_handle<>> to_resume;
775✔
41
    {
42
        std::lock_guard<std::mutex> lock(mutex_);
775✔
43
        state_.store(static_cast<std::uint8_t>(s), std::memory_order_release);
777✔
44
        to_resume.swap(continuations_);
777✔
45
    }
777✔
46
    cv_.notify_all();
777✔
47
    // Resume coroutine continuations OUTSIDE the lock.
48
    for (auto h : to_resume) {
777✔
49
        if (h && !h.done()) {
2!
50
            h.resume();
×
UNCOV
51
        }
×
52
    }
53
}
779✔
54

55
bool TaskResult::wait(std::chrono::milliseconds timeout) const {
426✔
56
    auto ready = [this] {
852✔
57
        auto s = static_cast<State>(state_.load(std::memory_order_acquire));
426✔
58
        return s == State::value || s == State::exception ||
426!
UNCOV
59
               s == State::cancelled;
×
60
    };
61
    if (ready()) return true;
426!
62

63
    std::unique_lock<std::mutex> lock(mutex_);
×
64
    if (timeout.count() == 0) {
×
65
        cv_.wait(lock, ready);
×
66
        return true;
×
67
    }
68
    return cv_.wait_for(lock, timeout, ready);
×
69
}
426✔
70

71
std::any TaskResult::get() const {
337✔
72
    wait();
337✔
73
    std::lock_guard<std::mutex> lock(mutex_);
337✔
74
    auto s = static_cast<State>(state_.load(std::memory_order_acquire));
337✔
75
    if (s == State::exception) {
337✔
76
        std::rethrow_exception(exception_);
3!
77
    }
78
    if (s == State::cancelled) {
334!
79
        throw std::runtime_error("Task was cancelled");
×
80
    }
81
    return value_;  // returns COPY
334!
82
}
337✔
83

84
std::any TaskResult::get_ready() const {
527✔
85
    std::lock_guard<std::mutex> lock(mutex_);
527✔
86
    auto s = static_cast<State>(state_.load(std::memory_order_acquire));
527✔
87
    assert(s == State::value || s == State::exception || s == State::cancelled);
527!
88
    if (s == State::exception) {
527!
89
        std::rethrow_exception(exception_);
×
90
    }
91
    if (s == State::cancelled) {
527!
92
        throw std::runtime_error("Task was cancelled");
×
93
    }
94
    return value_;  // returns COPY
527!
95
}
527✔
96

97
std::exception_ptr TaskResult::get_exception() const { return exception_; }
5✔
98

99
bool TaskResult::is_ready() const {
7✔
100
    auto s = static_cast<State>(state_.load(std::memory_order_acquire));
7✔
101
    return s == State::value || s == State::exception || s == State::cancelled;
7!
102
}
103

104
bool TaskResult::has_exception() const {
781✔
105
    return static_cast<State>(state_.load(std::memory_order_acquire)) ==
781✔
106
           State::exception;
107
}
108

109
bool TaskResult::is_cancelled() const {
×
110
    return static_cast<State>(state_.load(std::memory_order_acquire)) ==
×
111
           State::cancelled;
112
}
113

114
TaskResult::State TaskResult::state() const {
×
115
    return static_cast<State>(state_.load(std::memory_order_acquire));
×
116
}
117

118
// WhenReadyAwaitable
119
bool TaskResult::WhenReadyAwaitable::await_ready() const noexcept {
×
120
    return result.is_ready();
×
121
}
122

123
bool TaskResult::WhenReadyAwaitable::await_suspend(std::coroutine_handle<> h) {
×
124
    std::lock_guard<std::mutex> lock(result.mutex_);
×
125
    // Double-check under lock -- result may have been published
126
    // between await_ready() and await_suspend().
127
    if (result.is_ready()) {
×
128
        return false;  // Don't suspend, resume immediately
×
129
    }
130
    result.continuations_.push_back(h);
×
131
    return true;       // Suspend
×
132
}
×
133

134
void TaskResult::WhenReadyAwaitable::await_resume() {
×
135
    if (result.has_exception()) {
×
136
        std::rethrow_exception(result.exception_);
×
137
    }
138
}
×
139

140
}  // namespace dftracer::utils
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc