/*! \file * \brief \ref Bellringer that manages and activates time-triggered activities. */ #pragma once #include "../object/queue.h" #include "../types.h" struct Vault; struct Bell; /*! \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 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 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::Node. */ Queue bells; //! Link pointer for bells static Bell** bell_link(Bell& obj, unsigned link_index); public: // constructor Bellringer() : bells(0, bell_link) {} /*! \brief Checks whether there are bells to be rung. * * Every call to check elapses a tick. Once such a tick reduces a bells * remaining time to zero, the bell will be rung. * * \todo(16) Implement Method */ void check(Vault& vault); /*! \brief Passes a `bell` to the bellringer to be rung after `ms` * milliseconds. * \param bell Bell that should be rung after `ms` milliseconds * \param ms number of milliseconds that should be waited before * ringing the bell * * \todo(16) Implement Method */ void sleep(Vault& vault, unsigned int ms); /*! \brief Checks whether there are enqueued bells. * \return true if there are enqueued bells, false otherwise * * \todo(16) Implement Method */ bool bellPending() const; };