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.
74 lines
1.8 KiB
C++
74 lines
1.8 KiB
C++
#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, 32> 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;
|
|
while(epilogue_queue FOR_CURRENT_CORE.consume(next)){
|
|
Core::Interrupt::enable();
|
|
next(global_vault);
|
|
Core::Interrupt::disable();
|
|
}
|
|
epi_flag FOR_CURRENT_CORE = false;
|
|
global_lock.unlock();
|
|
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);
|
|
global_lock.unlock();
|
|
}
|
|
epilogue_queue->consume(handler);
|
|
|
|
}
|
|
|
|
const Vault &Guard::unsafeConstAccess() { return global_vault; }
|
|
|
|
|