Implement RAII guard for memory pool synchronization
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <mm/alloc.hh>
|
#include <mm/alloc.hh>
|
||||||
#include <mm/colors.hh>
|
#include <mm/colors.hh>
|
||||||
|
#include <mm/guard.hh>
|
||||||
#include <mm/hlpool.hh>
|
#include <mm/hlpool.hh>
|
||||||
#include <mm/kpool.hh>
|
#include <mm/kpool.hh>
|
||||||
#include <mm/mmgr.hh>
|
#include <mm/mmgr.hh>
|
||||||
|
|||||||
88
xtoskrnl/includes/mm/guard.hh
Normal file
88
xtoskrnl/includes/mm/guard.hh
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/includes/mm/guard.hh
|
||||||
|
* DESCRIPTION: Memory Manager synchronization guard
|
||||||
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_MM_GUARD_HH
|
||||||
|
#define __XTOSKRNL_MM_GUARD_HH
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
#include <ke/runlevel.hh>
|
||||||
|
#include <ke/spinlock.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* Memory Manager */
|
||||||
|
namespace MM
|
||||||
|
{
|
||||||
|
class PoolLockGuard
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
BOOLEAN Locked;
|
||||||
|
MMPOOL_TYPE LockPoolType;
|
||||||
|
KRUNLEVEL PreviousRunLevel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PoolLockGuard(IN MMPOOL_TYPE PoolType)
|
||||||
|
{
|
||||||
|
LockPoolType = PoolType;
|
||||||
|
|
||||||
|
/* Determine the appropriate synchronization mechanism based on the requested pool type */
|
||||||
|
if(LockPoolType == NonPagedPool)
|
||||||
|
{
|
||||||
|
/* Elevate the runlevel to DISPATCH_LEVEL */
|
||||||
|
PreviousRunLevel = KE::RunLevel::RaiseRunLevel(DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
/* Acquire the global queued spinlock protecting the non-paged pool */
|
||||||
|
KE::SpinLock::AcquireQueuedSpinLock(NonPagedPoolLock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Paged pool requires a mutex, currently unimplemented */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark the guard as actively holding the lock */
|
||||||
|
Locked = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
~PoolLockGuard(VOID)
|
||||||
|
{
|
||||||
|
/* Automatically release the held lock upon going out of scope */
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolLockGuard(const PoolLockGuard&) = delete;
|
||||||
|
PoolLockGuard& operator=(const PoolLockGuard&) = delete;
|
||||||
|
|
||||||
|
VOID Release(VOID)
|
||||||
|
{
|
||||||
|
/* Check if the guard is currently holding a lock */
|
||||||
|
if(!Locked)
|
||||||
|
{
|
||||||
|
/* Return, to prevent a double-free */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the appropriate synchronization mechanism based on the requested pool type */
|
||||||
|
if(LockPoolType == NonPagedPool)
|
||||||
|
{
|
||||||
|
/* Release the non-paged pool spinlock and subsequently restore the original runlevel */
|
||||||
|
KE::SpinLock::ReleaseQueuedSpinLock(NonPagedPoolLock);
|
||||||
|
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Paged pool requires a mutex, currently unimplemented */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the internal state, indicating that the lock is no longer held */
|
||||||
|
Locked = FALSE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __XTOSKRNL_MM_GUARD_HH */
|
||||||
Reference in New Issue
Block a user