From 9afe2020782cbfcc6912bf28ae79f22d3c6a8b4f Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 13 May 2025 14:35:58 +0200 Subject: [PATCH] ticketlock foo --- main.cc | 4 ++-- sync/ticketlock.cc | 12 ++++++++++++ sync/ticketlock.h | 13 ++++++++++--- user/app1/appl.cc | 10 ++++++++-- 4 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 sync/ticketlock.cc diff --git a/main.cc b/main.cc index 3caccec..fa2d0ae 100644 --- a/main.cc +++ b/main.cc @@ -13,7 +13,7 @@ #include "device/ps2controller.h" #include "arch/ioapic.h" #include "user/app1/appl.h" - +#include "sync/ticketlock.h" TextStream kout = TextStream(0, 80, 0, 10, true); //TextStream dout[8] = { @@ -47,6 +47,7 @@ CopyStream copystream[Core::MAX]{ {&dout[6], &sout}, {&dout[7], &sout}, }; +Ticketlock ticketlock; OutputStream* copyout[Core::MAX]{ &dout[0], @@ -99,7 +100,6 @@ extern "C" int main() { PS2Controller::drainBuffer(); Application{}.action(); - while (true){ } diff --git a/sync/ticketlock.cc b/sync/ticketlock.cc new file mode 100644 index 0000000..680932e --- /dev/null +++ b/sync/ticketlock.cc @@ -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); +} diff --git a/sync/ticketlock.h b/sync/ticketlock.h index 5414ebe..9a517d1 100644 --- a/sync/ticketlock.h +++ b/sync/ticketlock.h @@ -4,6 +4,8 @@ #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. @@ -29,12 +31,17 @@ class Ticketlock { 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() {} + 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. @@ -42,11 +49,11 @@ class Ticketlock { * \see \ref Core::pause() * \todo(12) Implement Method (for \MPStuBS) */ - void lock() {} + void lock(); /*! \brief Unblocks the critical area. * * \todo(12) Implement Method (for \MPStuBS) */ - void unlock() {} + void unlock(); }; diff --git a/user/app1/appl.cc b/user/app1/appl.cc index 75e9d50..3fcdba8 100644 --- a/user/app1/appl.cc +++ b/user/app1/appl.cc @@ -4,7 +4,8 @@ #include "../../device/ps2controller.h" #include "../../object/outputstream.h" #include "../../device/textstream.h" - +#include "../../sync/ticketlock.h" +#include "../../arch/core.h" char text[] = "Ich mag\n\ Saftige Pflaumen voller Aroma\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"; extern TextStream kout; - +extern Ticketlock ticketlock; void activeWaitDelay(uint64_t cycles) { uint64_t counter = 0; // Use volatile to prevent optimization for (uint64_t i = 0; i < cycles; ++i) { @@ -31,6 +32,8 @@ void activeWaitDelay(uint64_t cycles) { void Application::action() { // NOLINT uint16_t cnt = 0; while (1) { + Core::Interrupt::disable(); + ticketlock.lock(); while(text[cnt++] != '\n'){ kout << text[cnt-1]; } @@ -39,5 +42,8 @@ void Application::action() { // NOLINT activeWaitDelay(1000000000); if(cnt >= sizeof(text)-1) cnt=0; + + ticketlock.unlock(); + Core::Interrupt::enable(); } }