You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
1.8 KiB
C++

/*! \file
* \brief Contains the class Ticketlock
*/
#pragma once
#include "../arch/core.h"
#include "../arch/cache.h"
/*! \brief Using Ticketlocks, it is possible to serialize blocks of code
* that might otherwise run in parallel on multiple CPU cores,
* or be interleaved due to interrupts or scheduling.
*
* \ingroup sync
*
* Synchronization is implemented using a lock and a ticket variable.
* Once a thread tries to enter the critical area, it obtains a ticket by
* atomically incrementing the ticket variable and waiting until the lock
* counter reaches this ticket, if it is not there already.
* When a thread leaves the critical area, it increments the lock variable by
* one and thereby allows the next thread to enter the critical area.
*
* If you want that things just work, choose __ATOMIC_SEQ_CST as memorder.
* This is not the most efficient memory order but works reasonably well.
*
* <a
* href="https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html">Atomic
* Builtins in GCC manual</a>
*/
class Ticketlock {
// Prevent copies and assignments
Ticketlock(const Ticketlock& copy) = delete;
Ticketlock& operator=(const Ticketlock&) = delete;
private:
volatile uint64_t ticket_current;
volatile uint64_t ticket_count;
public:
/*! \brief Constructor
*
* \todo(12) Complete Constructor (for \MPStuBS)
*/
consteval Ticketlock() : ticket_current(0), ticket_count(0) {}
/*! \brief Enters the critical area. In case the area is already locked,
* \ref lock() will actively wait until the area can be entered.
*
* \see \ref Core::pause()
* \todo(12) Implement Method (for \MPStuBS)
*/
void lock();
/*! \brief Unblocks the critical area.
*
* \todo(12) Implement Method (for \MPStuBS)
*/
void unlock();
};