blob: 203317e54257bab9cf83ac1525716b6dc7e7d001 [file] [log] [blame]
// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT
#include "consumer.h"
#include <debug.hh>
#include <fail-simulator-on-error.h>
#include <futex.h>
#include <queue.h>
#include <timeout.hh>
#include <token.h>
using Debug = ConditionalDebug<true, "Consumer">;
// The queue that we will wait on.
SObj queue;
/**
* Set the queue that the thread in this compartment will use.
*/
void set_queue(SObj newQueue)
{
// Check that this is a valid queue
size_t items;
if (queue_items_remaining_sealed(newQueue, &items) != 0)
{
return;
}
// Set it in the global and allow the thread to start.
queue = newQueue;
Debug::log("Queue set to {}", queue);
futex_wake(reinterpret_cast<uint32_t *>(&queue), 1);
}
/**
* Run loop for the consumer thread.
*/
void __cheri_compartment("consumer") run()
{
// Use the queue pointer as a futex. It is initialised to 0, if the other
// thread has stored a valid pointer here then it will not be zero and so
// futex_wait will return immediately.
futex_wait(reinterpret_cast<uint32_t *>(&queue), 0);
Debug::log("Waiting for messages");
// Get a message from the queue and print it. This blocks indefinitely.
int value = 0;
Timeout t{UnlimitedTimeout};
while ((value != 199) && (queue_receive_sealed(&t, queue, &value) == 0))
{
Debug::log("Read {} from queue", value);
}
}