Handout
This commit is contained in:
79
kernel/sync/bellringer.h
Normal file
79
kernel/sync/bellringer.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*! \file
|
||||
* \brief \ref Bellringer that manages and activates time-triggered activities.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../object/queue.h"
|
||||
#include "../thread/thread.h"
|
||||
#include "../types.h"
|
||||
|
||||
struct Vault;
|
||||
|
||||
/*! \brief Manages and activates time-triggered activities.
|
||||
* \ingroup ipc
|
||||
*
|
||||
* The Bellringer is regularly activated and checks whether any of the bells
|
||||
* should ring. The bells are stored in a Queue<Bell> that is managed by the
|
||||
* Bellringer. A clever implementation avoids iterating through the whole list
|
||||
* for every iteration by keeping the bells sorted and storing delta times. This
|
||||
* approach leads to a complexity of O(1) for the method called by the timer
|
||||
* interrupt in case no bells need to be rung.
|
||||
*/
|
||||
class Bellringer {
|
||||
// Prevent copies and assignments
|
||||
Bellringer(const Bellringer&) = delete;
|
||||
Bellringer& operator=(const Bellringer&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Contains a Thread and its remaining waiting time in timer ticks
|
||||
*
|
||||
*/
|
||||
struct Bell {
|
||||
// link pointer to the next bell in the bellringer's bell list
|
||||
Bell* queue_link = nullptr;
|
||||
|
||||
Thread* thread;
|
||||
size_t counter;
|
||||
};
|
||||
|
||||
/*! \brief List of bells currently managed.
|
||||
*
|
||||
* This list contains non-expired bells enqueued by job().
|
||||
* These bells will be checked on every call to check().
|
||||
*
|
||||
* All elements that should be inserted into a Queue instance
|
||||
* are required to be derived from Queue<Bell>::Node.
|
||||
*/
|
||||
Queue<Bell> bells;
|
||||
|
||||
public:
|
||||
// constructor
|
||||
Bellringer() {}
|
||||
|
||||
/*! \brief Checks whether there are bells to be rung.
|
||||
*
|
||||
* Every call to check elapses a tick. Once such a tick reduces a bell's
|
||||
* remaining time to zero, the bell will be rung (i.e., its thread is
|
||||
* ready).
|
||||
*
|
||||
* \param vault The vault containing the bellringer instance
|
||||
*
|
||||
*/
|
||||
void check(Vault& vault);
|
||||
|
||||
/*! \brief Puts the calling thread to sleep for `ms` milliseconds by
|
||||
* enqueuing a \ref Bell.
|
||||
*
|
||||
* \param vault The vault containing the bellringer instance
|
||||
* \param ms Number of milliseconds that should be waited before
|
||||
* ringing the bell
|
||||
*
|
||||
*/
|
||||
void sleep(Vault& vault, unsigned int ms);
|
||||
|
||||
/*! \brief Checks whether there are enqueued bells.
|
||||
* \return true if there are enqueued bells, false otherwise
|
||||
*
|
||||
*/
|
||||
bool bellPending() const;
|
||||
};
|
||||
Reference in New Issue
Block a user