My Project
Loading...
Searching...
No Matches
rundown.c
Go to the documentation of this file.
1#include "../../includes/me.h"
2
3#define TEARDOWN_ACTIVE (1ULL << 63)
4#define REFERENCE_COUNT (0x7FFFFFFFFFFFFFFF)
5
6bool
8 IN PRUNDOWN_REF rundown
9)
10
11/*++
12
13 Routine description : Safely acquires rundown protection on a shared resource to prevent it from being deleted or "rundown" while in use.
14
15 Arguments:
16
17 Pointer to RUNDOWN_REF Object.
18
19 Return Values:
20
21 True - The rundown protection acquisition has succeeded, the object is safe from memory deletion.
22 False - Teardown has started on the object, handle gracefully.
23
24--*/
25
26{
27 uint64_t old_count, new_count;
28 do {
29 old_count = rundown->Count;
30 if (old_count & TEARDOWN_ACTIVE) {
31 // Teardown has started, refuse to acquire.
32 return false;
33 }
34 new_count = old_count + 1;
35 } while (!InterlockedCompareExchangeU64(&rundown->Count, new_count, old_count));
36 return true;
37}
38
39void
41 IN PRUNDOWN_REF rundown
42)
43
44/*++
45
46 Routine description : Releases rundown protection from the object.
47
48 Arguments:
49
50 Pointer to RUNDOWN_REF Object.
51
52 Return Values:
53
54 None.
55
56--*/
57
58{
59 InterlockedDecrementU64(&rundown->Count);
60}
61
62// Wait for rundown (teardown)
64 IN PRUNDOWN_REF rundown
65)
66
67/*++
68
69 Routine description : Waits until all rundown protections have been released from the object, then starts Teardown.
70 Use this when you want to gurantee an object will not be used after free.
71
72 Arguments:
73
74 Pointer to RUNDOWN_REF Object.
75
76 Return Values:
77
78 None.
79
80--*/
81
82{
83 uint64_t old_count;
84 do {
85 old_count = rundown->Count;
86 } while (!InterlockedCompareExchangeU64(&rundown->Count, old_count | TEARDOWN_ACTIVE, old_count));
87
88 // Spin until count reaches zero (TODO RUNDOWN REF WAKE SLEEP (use the 0-62 bits for a pointer )
89 while ((rundown->Count & REFERENCE_COUNT) != 0) {
90 __pause();
91 }
92}
#define IN
Definition annotations.h:7
FORCEINLINE uint64_t InterlockedCompareExchangeU64(volatile uint64_t *target, uint64_t value, uint64_t comparand)
Definition atomic.h:86
FORCEINLINE uint64_t InterlockedDecrementU64(volatile uint64_t *target)
Definition atomic.h:122
FORCEINLINE void __pause(void)
Definition intrin.h:224
struct _RUNDOWN_REF * PRUNDOWN_REF
#define REFERENCE_COUNT
Definition rundown.c:4
#define TEARDOWN_ACTIVE
Definition rundown.c:3
bool MsAcquireRundownProtection(IN PRUNDOWN_REF rundown)
Definition rundown.c:7
void MsReleaseRundownProtection(IN PRUNDOWN_REF rundown)
Definition rundown.c:40
void MsWaitForRundownProtectionRelease(IN PRUNDOWN_REF rundown)
Definition rundown.c:63