20#include "pedigree/kernel/utilities/ProducerConsumer.h"
22#if PRODUCERCONSUMER_ASYNCHRONOUS
23#include "pedigree/kernel/LockGuard.h"
24#include "pedigree/kernel/Log.h"
25#include "pedigree/kernel/utilities/pocketknife.h"
28ProducerConsumer::ProducerConsumer() =
default;
30ProducerConsumer::~ProducerConsumer() {
31#if PRODUCERCONSUMER_ASYNCHRONOUS
32 if (m_pThreadHandle) {
34 "ProducerConsumer destroyed before its most-derived destructor "
35 "stopped the worker.");
40 for (
auto it : m_Tasks) {
47#if PRODUCERCONSUMER_ASYNCHRONOUS
57 void* threadHandle = m_pThreadHandle;
58 m_pThreadHandle =
nullptr;
63 FATAL(
"ProducerConsumer could not join its worker during teardown.");
68 for (
auto it : m_Tasks) {
75bool ProducerConsumer::initialise() {
76#if PRODUCERCONSUMER_ASYNCHRONOUS
89 if (!m_pThreadHandle) {
100void ProducerConsumer::produce(uint64_t p0, uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4,
101 uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8) {
102#if PRODUCERCONSUMER_ASYNCHRONOUS
103 Task* task =
new Task;
120 m_Tasks.pushBack(task);
124 consume(p0, p1, p2, p3, p4, p5, p6, p7, p8);
128void ProducerConsumer::consumerThread() {
132 while (m_Running && !m_Tasks.size()) {
133 ConditionVariable::Error error = ConditionVariable::NoError;
134 if (!m_Condition.
wait(m_Lock, error)) {
146 Task* task = m_Tasks.popFront();
151 consume(task->p0, task->p1, task->p2, task->p3, task->p4, task->p5, task->p6, task->p7,
160int ProducerConsumer::thread(
void* p) {
162 pc->consumerThread();
MUST_USE_RESULT bool wait(Mutex &mutex, Time::Timestamp &timeout, Error &error, WaitQueue::StackDiscardCleanup onStackDiscard=nullptr, void *stackDiscardContext=nullptr)
static bool mutexAcquired(Error error)
bool acquire(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
EXPORTED_PUBLIC bool attachToForCompletion(void *handle)
EXPORTED_PUBLIC void * runConcurrentlyAttached(int(*func)(void *), void *param)