#pragma once #include #include #include #include #include #include #include #include #include namespace prism_engineering { inline constexpr std::size_t max_jobs = 32; inline constexpr std::size_t max_samples_per_job = 4096; inline constexpr std::size_t max_workers = 8; // A deterministic admission gate, useful for testing cancellation before work. // shared_ptr ownership in Options keeps the gate alive until every worker // joins. class WorkGate { public: bool arrive_and_wait(std::stop_token stop); bool wait_for_arrivals(std::size_t count, std::stop_token stop = {}); void open(); private: std::mutex mutex_; std::condition_variable_any changed_; std::size_t arrivals_{}; bool open_{}; }; struct Job { std::uint64_t generation{}; std::vector samples; // Queued payload owns its storage. bool inject_failure{}; // Explicit experiment seam, not an external callback. }; enum class Status { pending, succeeded, cancelled, failed }; struct Result { std::uint64_t generation{}; Status status{Status::pending}; std::uint64_t checksum{}; }; struct Options { std::size_t workers{2}; std::shared_ptr gate; // Test seam: simulate failure before launching worker N (zero-based). // The default launches normally; values >= workers do not trigger it. std::optional fail_launch_after{}; }; struct Report { std::vector results; // One fixed slot per accepted job, no growing result queue. std::size_t peak_active{}; }; enum class Error { invalid_worker_count, too_many_jobs, payload_too_large, allocation, thread_start, worker_runtime }; // The caller transfers a bounded batch into this function. Workers execute // asynchronously, but this orchestration call returns ONLY after joining them. // Cancellation is cooperative; it does not interrupt arbitrary blocking I/O. [[nodiscard]] std::expected run_batch(std::vector owned_jobs, Options options = {}, std::stop_token cancellation = {}); // A generation check is a policy on values, not a claim that cancellation // undoes work. The caller applies it before publishing a result to the current // asset. [[nodiscard]] bool accepts(const Result &result, std::uint64_t current_generation) noexcept; } // namespace prism_engineering