#include "guard.h" #include "../arch/core.h" #include "../debug/output.h" #include "../object/bbuffer.h" #include "../sync/ticketlock.h" #include "../arch/core_interrupt.h" #include "epilogues.h" #define FOR_CURRENT_CORE [Core::getID()] //! \brief The protected data for the epilogue level static Vault global_vault; // lists of pending epilogues static BBuffer epilogue_queue[Core::MAX] = {}; // Big Kernel Lock (BKL) for the epilogue level constinit Ticketlock global_lock; constinit bool epi_flag[Core::MAX] = {false}; Vault::Vault() { } Guarded::~Guarded() { Guard::leave(); } Guarded Guard::enter() { epi_flag FOR_CURRENT_CORE = true; //Core::Interrupt::enable(); global_lock.lock(); return Guarded(global_vault); } void Guard::leave() { bool istate = Core::Interrupt::disable(); Epilogue next; global_lock.unlock(); while(epilogue_queue FOR_CURRENT_CORE.consume(next)){ Core::Interrupt::enable(); global_lock.lock(); next(global_vault); global_lock.unlock(); Core::Interrupt::disable(); } epi_flag FOR_CURRENT_CORE = false; Core::Interrupt::restore(istate); } void Guard::relay(Epilogue handler) { //if(!epilogue_queue FOR_CURRENT_CORE.produce(handler)) // return; // enqueue, but dont execute //if(!epi_flag FOR_CURRENT_CORE){ // enter(); // Core::Interrupt::enable(); // handler(global_vault); // leave(); //} Core::Interrupt::enable(); // goto level 0.5 if(epi_flag FOR_CURRENT_CORE){ epilogue_queue->produce(handler); } else{ epi_flag FOR_CURRENT_CORE = true; global_lock.lock(); handler(global_vault); leave(); } //epilogue_queue->consume(handler); } const Vault &Guard::unsafeConstAccess() { return global_vault; }