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

llnl / dftracer-utils / 23529483807

25 Mar 2026 07:17AM UTC coverage: 48.515% (-1.6%) from 50.098%
23529483807

Pull #57

github

web-flow
Merge 5b1e117ad into 38f9f3616
Pull Request #57: feat(comparator): add pairwise traces comparator

18829 of 49412 branches covered (38.11%)

Branch coverage included in aggregate %.

1584 of 1933 new or added lines in 14 files covered. (81.95%)

3552 existing lines in 135 files now uncovered.

18474 of 27477 relevant lines covered (67.23%)

241072.53 hits per line

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

50.0
/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) {
686✔
8
    value_ = std::move(value);
686✔
9
    publish(State::value);
686✔
10
}
686✔
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() {
699✔
20
    auto expected = static_cast<std::uint8_t>(State::pending);
699✔
21
    state_.compare_exchange_strong(
699✔
22
        expected, static_cast<std::uint8_t>(State::running),
23
        std::memory_order_release, std::memory_order_relaxed);
24
}
699✔
25

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

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

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

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

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

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