Implement ExAcquireRundownProtection() and ExReleaseRundownProtection() routines
All checks were successful
ci/woodpecker/push/build Pipeline was successful
All checks were successful
ci/woodpecker/push/build Pipeline was successful
This commit is contained in:
parent
1f8026db2f
commit
2827bb400f
28
sdk/xtdk/exfuncs.h
Normal file
28
sdk/xtdk/exfuncs.h
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/exfuncs.h
|
||||
* DESCRIPTION: Kernel executive routines
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_EXFUNCS_H
|
||||
#define __XTDK_EXFUNCS_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
XTFASTCALL
|
||||
BOOLEAN
|
||||
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
|
||||
|
||||
XTFASTCALL
|
||||
VOID
|
||||
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
|
||||
|
||||
XTFASTCALL
|
||||
VOID
|
||||
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
|
||||
|
||||
#endif /* __XTDK_EXFUNCS_H */
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xttypes.h>
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* Executive rundown protection structure definition */
|
||||
@ -23,4 +24,11 @@ typedef struct _EX_RUNDOWN_REFERENCE
|
||||
};
|
||||
} EX_RUNDOWN_REFERENCE, *PEX_RUNDOWN_REFERENCE;
|
||||
|
||||
/* Executive rundown wait block definition */
|
||||
typedef struct _EX_RUNDOWN_WAIT_BLOCK
|
||||
{
|
||||
ULONG_PTR Count;
|
||||
KEVENT WakeEvent;
|
||||
} EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;
|
||||
|
||||
#endif /* __XTDK_EXTYPES_H */
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include ARCH_HEADER(mmtypes.h)
|
||||
|
||||
/* XT routines */
|
||||
#include <exfuncs.h>
|
||||
#include <hlfuncs.h>
|
||||
#include <kefuncs.h>
|
||||
#include <mmfuncs.h>
|
||||
|
@ -9,6 +9,54 @@
|
||||
#include <xtos.h>
|
||||
|
||||
|
||||
/**
|
||||
* Acquires the rundown protection for given descriptor.
|
||||
*
|
||||
* @param Descriptor
|
||||
* Supplies a pointer to the rundown block descriptor.
|
||||
*
|
||||
* @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.
|
||||
*
|
||||
* @since NT 5.1
|
||||
*/
|
||||
XTFASTCALL
|
||||
BOOLEAN
|
||||
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
{
|
||||
ULONG_PTR CurrentValue, NewValue;
|
||||
|
||||
/* Get current value */
|
||||
CurrentValue = Descriptor->Count;
|
||||
|
||||
/* Main loop execution */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Make sure protection is not active yet */
|
||||
if(CurrentValue & 0x1)
|
||||
{
|
||||
/* Already active, nothing to do */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Attempt to increment the usage count */
|
||||
NewValue = CurrentValue + 2;
|
||||
|
||||
/* Exchange the value */
|
||||
NewValue = (ULONG_PTR)RtlInterlockedCompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue,
|
||||
(PVOID)CurrentValue);
|
||||
|
||||
/* Make sure protection acquired */
|
||||
if(NewValue == CurrentValue)
|
||||
{
|
||||
/* Successfully acquired protection */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Update value and try once again */
|
||||
CurrentValue = NewValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the rundown protection descriptor.
|
||||
*
|
||||
@ -26,3 +74,54 @@ ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
/* Reset descriptor counter */
|
||||
Descriptor->Count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the rundown protection for given descriptor.
|
||||
*
|
||||
* @param Descriptor
|
||||
* Supplies a pointer to the descriptor to be initialized.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
{
|
||||
ULONG_PTR CurrentValue, NewValue;
|
||||
PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
|
||||
|
||||
CurrentValue = Descriptor->Count;
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
if(CurrentValue & 0x1)
|
||||
{
|
||||
WaitBlock = (PEX_RUNDOWN_WAIT_BLOCK)(CurrentValue & ~0x1);
|
||||
|
||||
if(!RtlInterlockedDecrementLongPtr((PLONG_PTR)&WaitBlock->Count))
|
||||
{
|
||||
KeSetEvent(&WaitBlock->WakeEvent, 0, FALSE);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Attempt to decrement the usage count */
|
||||
NewValue = CurrentValue - 2;
|
||||
|
||||
/* Exchange the value */
|
||||
NewValue = (ULONG_PTR)RtlInterlockedCompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue,
|
||||
(PVOID)CurrentValue);
|
||||
|
||||
if(NewValue == CurrentValue)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentValue = NewValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user