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

NREL / SolTrace / 20976121514

13 Jan 2026 11:18PM UTC coverage: 87.958% (+0.1%) from 87.815%
20976121514

Pull #96

github

web-flow
Merge fc02507e1 into e78d2bfb0
Pull Request #96: 95 implement embree runner

569 of 752 new or added lines in 16 files covered. (75.66%)

13 existing lines in 6 files now uncovered.

6238 of 7092 relevant lines covered (87.96%)

7203591.18 hits per line

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

84.15
/coretrace/simulation_runner/native_runner/thread_manager.cpp
1
#include "thread_manager.hpp"
2

3
#include <chrono>
4
#include <future>
5
#include <sstream>
6
#include <thread>
7

8
namespace SolTrace::NativeRunner
9
{
10

11
    ThreadManager::ThreadManager(trace_logger_ptr log) : logger(log)
26✔
12
    {
13
        this->initialize();
26✔
14
        return;
26✔
15
    }
×
16

17
    ThreadManager::~ThreadManager()
26✔
18
    {
19
        this->threads.clear();
26✔
20
        this->progress.clear();
26✔
21
        return;
26✔
22
    }
26✔
23

24
    unsigned int ThreadManager::manage(unsigned int id, future f)
25✔
25
    {
26
        assert(this->threads.find(id) == this->threads.end());
25✔
27

28
        this->threads[id] = std::move(f);
25✔
29
        this->progress[id] = 0.0;
25✔
30
        return id;
25✔
31
    }
32

33
    ThreadManager::ThreadStatus ThreadManager::monitor_until_completion()
25✔
34
    {
35
        ThreadStatus sts = ThreadStatus::SUCCESS;
25✔
36
        bool canceled = false;
25✔
37

38
        while (!this->threads.empty())
7,532✔
39
        {
40
            auto iter = this->threads.begin();
7,507✔
41
            while (iter != this->threads.end())
15,014✔
42
            {
43
                if (iter->second.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
7,507✔
44
                {
45
                    ThreadStatus thread_status = iter->second.get();
25✔
46
                    if (thread_status == ThreadStatus::SUCCESS)
25✔
47
                    {
48
                        ; // Intentional no-op
49
                    }
50
                    else if (thread_status == ThreadStatus::ERROR)
1✔
51
                    {
52
                        // Something went wrong -- shut everything down
53
                        this->cancel();
×
54
                        // Return ERROR status
55
                        sts = ThreadStatus::ERROR;
×
56
                        canceled = true;
×
57
                    }
58
                    else if (thread_status == ThreadStatus::CANCEL)
1✔
59
                    {
60
                        // Return CANCEL if threads were canceled
61
                        // by an external call to cancel()
62
                        sts = canceled ? sts : thread_status;
1✔
63
                    }
64
                    else
65
                    {
66
                        // Thread terminated with something other than
67
                        // SUCCESS, ERROR, or CANCEL. This is unexpected.
68
                        std::stringstream ss;
×
69
                        ss << "Thread " << iter->first
×
70
                           << " returned status "
71
                           << status_string(thread_status)
×
72
                           << ". This is an error.";
×
NEW
73
                        this->logger->error_log(ss.str());
×
74

75
                        // Unexpected behavior so we terminate
76
                        this->cancel();
×
77
                        sts = ThreadStatus::ERROR;
×
78
                        canceled = true;
×
79
                    }
×
80
                    // Task is complete so we stop tracking it.
81
                    // Also increments to the next spot
82
                    iter = this->threads.erase(iter);
25✔
83
                }
84
                else
85
                {
86
                    ++iter;
7,482✔
87
                }
88
            }
89

90
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
7,507✔
91
        }
92

93
        return sts;
25✔
94
    }
95

96
    void ThreadManager::progress_update(unsigned int id, double prog)
11,759✔
97
    {
98
        // std::cout << "Update from thread " << id << " reporting "
99
        //           << prog << " complete." << std::endl;
100
        std::lock_guard<std::mutex> lk(this->progress_mutex);
11,759✔
101
        this->progress[id] = prog;
11,759✔
102
        return;
23,518✔
103
    }
11,759✔
104

105
    bool ThreadManager::terminate(unsigned int id)
11,759✔
106
    {
107
        std::lock_guard<std::mutex> lk(this->state_mutex);
11,759✔
108
        return this->state != ThreadStatus::RUNNING;
11,759✔
109
    }
11,759✔
110

111
    ThreadManager::ThreadStatus ThreadManager::status(double *progress) const
3✔
112
    {
113
        ThreadStatus sts = ThreadStatus::ERROR;
3✔
114
        // Create isolated scope for lock guard
115
        {
116
            std::lock_guard<std::mutex> lk(this->state_mutex);
3✔
117
            sts = this->state;
3✔
118
        }
3✔
119

120
        if (progress != nullptr)
3✔
121
        {
122
            int k = 0;
1✔
123
            double avg = 0.0;
1✔
124
            std::lock_guard<std::mutex> lk(this->progress_mutex);
1✔
125
            for (auto it = this->progress.cbegin();
1✔
126
                 it != this->progress.cend();
2✔
127
                 ++it)
1✔
128
            {
129
                // std::cout << "Thread " << k
130
                //           << " progress " << it->second
131
                //           << std::endl;
132
                ++k;
1✔
133
                avg += (it->second - avg) / k;
1✔
134
            }
135
            *progress = avg;
1✔
136
        }
1✔
137

138
        return sts;
3✔
139
    }
140

141
    void ThreadManager::cancel() const
1✔
142
    {
143
        std::lock_guard<std::mutex> lk(this->state_mutex);
1✔
144
        this->state = ThreadStatus::CANCEL;
1✔
145
        return;
2✔
146
    }
1✔
147

148
    void ThreadManager::initialize()
26✔
149
    {
150
        // Must call prior to manage and not while running!!
151
        // this->next_id = 0;
152
        {
153
            std::lock_guard<std::mutex> lk(this->state_mutex);
26✔
154
            this->state = ThreadStatus::RUNNING;
26✔
155
        }
26✔
156
        {
157
            std::lock_guard<std::mutex> lk(this->progress_mutex);
26✔
158
            this->progress.clear();
26✔
159
            this->threads.clear();
26✔
160
        }
26✔
161
        return;
26✔
162
    }
163

164
} // namespace SolTrace::NativeRunner
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