GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 1 / 0 / 1
Functions: 100.0% 1 / 0 / 1
Branches: -% 0 / 0 / 0

src/util/ThreadPool.h
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #pragma once
4
5 #include <condition_variable>
6 #include <cstddef>
7 #include <exception>
8 #include <functional>
9 #include <mutex>
10 #include <queue>
11 #include <thread>
12 #include <vector>
13
14 namespace spice::compiler {
15
16 /**
17 * Fixed-size pool of worker threads, used to run independent compiler passes concurrently.
18 *
19 * The pool is intentionally minimal: work is submitted as void() tasks and the submitter blocks in waitForAll() until
20 * the whole batch is done. Two properties matter for the compiler:
21 *
22 * - Compiler passes report failures by throwing (LexerError, SemanticError, CompilerError, ...). An exception escaping
23 * a task would terminate the process, so tasks are wrapped and the exception is re-thrown on the waiting thread.
24 * - Diagnostics must not depend on thread scheduling. Every task carries the index it was submitted with and, if
25 * multiple tasks fail, the one with the lowest index wins. The user therefore always sees the same error, no matter
26 * which worker happened to get there first.
27 *
28 * As soon as one task has failed, queued tasks that have not started yet are dropped, so a broken build fails fast.
29 */
30 class ThreadPool final {
31 public:
32 // Constructors
33 explicit ThreadPool(size_t threadCount);
34
35 // Prevent copy
36 ThreadPool(const ThreadPool &) = delete;
37 ThreadPool &operator=(const ThreadPool &) = delete;
38
39 // Destructor
40 ~ThreadPool();
41
42 // Public methods
43 void submit(std::function<void()> task);
44 void waitForAll();
45 1 [[nodiscard]] size_t getThreadCount() const { return workers.size(); }
46
47 private:
48 // Structs
49 struct Task {
50 size_t index = 0;
51 std::function<void()> job;
52 };
53
54 // Private methods
55 void workerLoop();
56
57 // Members
58 std::vector<std::thread> workers;
59 std::queue<Task> tasks;
60 std::mutex mutex;
61 std::condition_variable taskAvailable;
62 std::condition_variable allTasksDone;
63 std::exception_ptr firstException;
64 size_t firstExceptionTaskIndex = 0;
65 size_t nextTaskIndex = 0;
66 size_t pendingCount = 0;
67 bool canceled = false;
68 bool shuttingDown = false;
69 };
70
71 } // namespace spice::compiler
72