/** * @brief Marks the queue as done, and waits for all * jobs to finish. * * Once the queue is done, producers can no longer add jobs to * the queue, and consumers will be notified when the queue is * empty so they can terminate. */ void finish() { if (!done) { // Notify all threads that the queue is done done = true; queue.disallow_blocking(); // Wait for threads to finish for (auto &thread: threads) thread.join(); } }
/** * @brief Constructor. * * @param[in] scene_ A pointer to the scene to render. Should be fully * finalized for rendering. * @param[out] image_ The image to render to. Should be already * initialized with 3 channels, for rgb. * @param spp_ The number of samples to take per pixel for integration. */ PathTraceIntegrator(Scene *scene_, Film *image_, int spp_, int spp_max_, float variance_max_, uint seed_, int thread_count_=1, std::function<void()> callback_ = std::function<void()>()) { scene = scene_; image = image_; spp = spp_; spp_max = spp_max_; image_variance_max = variance_max_; seed = seed_; thread_count = thread_count_; path_length = 4; callback = callback_; blocks.resize(thread_count_ * 2); }
/** * @brief Constructor. * * By default uses 1 thread and creates a queue 4 times the size * of the thread count. * * @param thread_count Number of consumer threads to spawn for processing jobs. * @param queue_size Size of the job queue buffer. Zero means determine * automatically from number of threads. */ explicit JobQueue(size_t thread_count=1, size_t queue_size=0) { done = false; // Set up queue if (queue_size == 0) queue_size = thread_count * 4; queue.resize(queue_size); // Create and start consumer threads threads.resize(thread_count); for (auto &thread: threads) thread = std::thread(&JobQueue<T>::run_consumer, this); }
/** * @brief Adds a job to the queue. * * @param job The job to add. * * @return True on success, false if the queue is closed. */ bool push(const T &job) { // Add job to queue return queue.push_blocking(job); }
/** * @brief Gets the next job, removing it from the queue. * * @param [out] job The popped job is copied into here. Must be a * pointer to valid memory. * * @return True on success, false if the queue is empty and closed. */ bool pop(T *job) { // Pop the next job return queue.pop_blocking(job); }