ticketlock foo
This commit is contained in:
4
main.cc
4
main.cc
@@ -13,7 +13,7 @@
|
|||||||
#include "device/ps2controller.h"
|
#include "device/ps2controller.h"
|
||||||
#include "arch/ioapic.h"
|
#include "arch/ioapic.h"
|
||||||
#include "user/app1/appl.h"
|
#include "user/app1/appl.h"
|
||||||
|
#include "sync/ticketlock.h"
|
||||||
TextStream kout = TextStream(0, 80, 0, 10, true);
|
TextStream kout = TextStream(0, 80, 0, 10, true);
|
||||||
|
|
||||||
//TextStream dout[8] = {
|
//TextStream dout[8] = {
|
||||||
@@ -47,6 +47,7 @@ CopyStream copystream[Core::MAX]{
|
|||||||
{&dout[6], &sout},
|
{&dout[6], &sout},
|
||||||
{&dout[7], &sout},
|
{&dout[7], &sout},
|
||||||
};
|
};
|
||||||
|
Ticketlock ticketlock;
|
||||||
|
|
||||||
OutputStream* copyout[Core::MAX]{
|
OutputStream* copyout[Core::MAX]{
|
||||||
&dout[0],
|
&dout[0],
|
||||||
@@ -99,7 +100,6 @@ extern "C" int main() {
|
|||||||
PS2Controller::drainBuffer();
|
PS2Controller::drainBuffer();
|
||||||
|
|
||||||
Application{}.action();
|
Application{}.action();
|
||||||
|
|
||||||
while (true){
|
while (true){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
sync/ticketlock.cc
Normal file
12
sync/ticketlock.cc
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#include "sync/ticketlock.h"
|
||||||
|
|
||||||
|
void Ticketlock::lock() {
|
||||||
|
uint64_t ticket = __atomic_fetch_add(&ticket_count, 1, __ATOMIC_SEQ_CST);
|
||||||
|
while (ticket != ticket_current) {
|
||||||
|
Core::pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ticketlock::unlock() {
|
||||||
|
__atomic_fetch_add(&ticket_current, 1, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "arch/core.h"
|
||||||
|
#include "arch/cache.h"
|
||||||
/*! \brief Using Ticketlocks, it is possible to serialize blocks of code
|
/*! \brief Using Ticketlocks, it is possible to serialize blocks of code
|
||||||
* that might otherwise run in parallel on multiple CPU cores,
|
* that might otherwise run in parallel on multiple CPU cores,
|
||||||
* or be interleaved due to interrupts or scheduling.
|
* or be interleaved due to interrupts or scheduling.
|
||||||
@@ -29,12 +31,17 @@ class Ticketlock {
|
|||||||
Ticketlock(const Ticketlock& copy) = delete;
|
Ticketlock(const Ticketlock& copy) = delete;
|
||||||
Ticketlock& operator=(const Ticketlock&) = delete;
|
Ticketlock& operator=(const Ticketlock&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
volatile uint64_t ticket_current;
|
||||||
|
volatile uint64_t ticket_count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! \brief Constructor
|
/*! \brief Constructor
|
||||||
*
|
*
|
||||||
* \todo(12) Complete Constructor (for \MPStuBS)
|
* \todo(12) Complete Constructor (for \MPStuBS)
|
||||||
*/
|
*/
|
||||||
consteval Ticketlock() {}
|
consteval Ticketlock() : ticket_current(0), ticket_count(0) {}
|
||||||
|
|
||||||
/*! \brief Enters the critical area. In case the area is already locked,
|
/*! \brief Enters the critical area. In case the area is already locked,
|
||||||
* \ref lock() will actively wait until the area can be entered.
|
* \ref lock() will actively wait until the area can be entered.
|
||||||
@@ -42,11 +49,11 @@ class Ticketlock {
|
|||||||
* \see \ref Core::pause()
|
* \see \ref Core::pause()
|
||||||
* \todo(12) Implement Method (for \MPStuBS)
|
* \todo(12) Implement Method (for \MPStuBS)
|
||||||
*/
|
*/
|
||||||
void lock() {}
|
void lock();
|
||||||
|
|
||||||
/*! \brief Unblocks the critical area.
|
/*! \brief Unblocks the critical area.
|
||||||
*
|
*
|
||||||
* \todo(12) Implement Method (for \MPStuBS)
|
* \todo(12) Implement Method (for \MPStuBS)
|
||||||
*/
|
*/
|
||||||
void unlock() {}
|
void unlock();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
#include "../../device/ps2controller.h"
|
#include "../../device/ps2controller.h"
|
||||||
#include "../../object/outputstream.h"
|
#include "../../object/outputstream.h"
|
||||||
#include "../../device/textstream.h"
|
#include "../../device/textstream.h"
|
||||||
|
#include "../../sync/ticketlock.h"
|
||||||
|
#include "../../arch/core.h"
|
||||||
char text[] = "Ich mag\n\
|
char text[] = "Ich mag\n\
|
||||||
Saftige Pflaumen voller Aroma\n\
|
Saftige Pflaumen voller Aroma\n\
|
||||||
Ich knuddel jede Oma ins Koma\n\
|
Ich knuddel jede Oma ins Koma\n\
|
||||||
@@ -19,7 +20,7 @@ Und wacht sie aus'm Koma auf, kriegt sie von mir 'n Sticker\n\
|
|||||||
\n";
|
\n";
|
||||||
|
|
||||||
extern TextStream kout;
|
extern TextStream kout;
|
||||||
|
extern Ticketlock ticketlock;
|
||||||
void activeWaitDelay(uint64_t cycles) {
|
void activeWaitDelay(uint64_t cycles) {
|
||||||
uint64_t counter = 0; // Use volatile to prevent optimization
|
uint64_t counter = 0; // Use volatile to prevent optimization
|
||||||
for (uint64_t i = 0; i < cycles; ++i) {
|
for (uint64_t i = 0; i < cycles; ++i) {
|
||||||
@@ -31,6 +32,8 @@ void activeWaitDelay(uint64_t cycles) {
|
|||||||
void Application::action() { // NOLINT
|
void Application::action() { // NOLINT
|
||||||
uint16_t cnt = 0;
|
uint16_t cnt = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
Core::Interrupt::disable();
|
||||||
|
ticketlock.lock();
|
||||||
while(text[cnt++] != '\n'){
|
while(text[cnt++] != '\n'){
|
||||||
kout << text[cnt-1];
|
kout << text[cnt-1];
|
||||||
}
|
}
|
||||||
@@ -39,5 +42,8 @@ void Application::action() { // NOLINT
|
|||||||
activeWaitDelay(1000000000);
|
activeWaitDelay(1000000000);
|
||||||
if(cnt >= sizeof(text)-1)
|
if(cnt >= sizeof(text)-1)
|
||||||
cnt=0;
|
cnt=0;
|
||||||
|
|
||||||
|
ticketlock.unlock();
|
||||||
|
Core::Interrupt::enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user