HyperDbg Debugger
Loading...
Searching...
No Matches
Spinlock.c File Reference

This is the implementation for custom spinlock. More...

#include "pch.h"

Functions

BOOLEAN SpinlockTryLock (volatile LONG *Lock)
 Tries to get the lock otherwise returns.
 
void SpinlockLock (volatile LONG *Lock)
 Tries to get the lock and won't return until successfully get the lock.
 
void SpinlockInterlockedCompareExchange (LONG volatile *Destination, LONG Exchange, LONG Comperand)
 Interlocked spinlock that tries to change the value and makes sure that it changed the target value.
 
void SpinlockLockWithCustomWait (volatile LONG *Lock, unsigned MaximumWait)
 Tries to get the lock and won't return until successfully get the lock.
 
void SpinlockUnlock (volatile LONG *Lock)
 Release the lock.
 
BOOLEAN SpinlockCheckLock (volatile LONG *Lock)
 Check the lock without changing the state.
 

Detailed Description

This is the implementation for custom spinlock.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)

This implementation is derived from Hvpp by Petr Benes

  • https://github.com/wbenny/hvpp Based on my benchmarks, this simple implementation beats other (often more complex) spinlock implementations - such as queue spinlocks, ticket spinlocks, MCS locks. The only difference between this implementation and completely naive spinlock is the "backoff".

Also, benefit of this implementation is that we can use it with STL lock guards, e.g.: std::lock_guard.

Look here for more information:

Version
0.1
Date
2020-04-10

Function Documentation

◆ SpinlockCheckLock()

BOOLEAN SpinlockCheckLock ( volatile LONG * Lock)

Check the lock without changing the state.

Parameters
LONGLock variable
170{
171 if (*Lock)
172 {
173 return TRUE;
174 }
175 else
176 {
177 return FALSE;
178 }
179}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54

◆ SpinlockInterlockedCompareExchange()

void SpinlockInterlockedCompareExchange ( LONG volatile * Destination,
LONG Exchange,
LONG Comperand )

Interlocked spinlock that tries to change the value and makes sure that it changed the target value.

Parameters
DestinationA pointer to the destination value
ExchangeThe exchange value
ComperandThe value to compare to Destination
92{
93 unsigned wait = 1;
94
95 while (InterlockedCompareExchange(Destination, Exchange, Comperand) != Comperand)
96 {
97 for (unsigned i = 0; i < wait; ++i)
98 {
99 _mm_pause();
100 }
101
102 //
103 // Don't call "pause" too many times. If the wait becomes too big,
104 // clamp it to the MaxWait.
105 //
106
107 if (wait * 2 > MaxWait)
108 {
109 wait = MaxWait;
110 }
111 else
112 {
113 wait = wait * 2;
114 }
115 }
116}

◆ SpinlockLock()

void SpinlockLock ( volatile LONG * Lock)

Tries to get the lock and won't return until successfully get the lock.

Parameters
LONGLock variable
53{
54 unsigned wait = 1;
55
56 while (!SpinlockTryLock(Lock))
57 {
58 for (unsigned i = 0; i < wait; ++i)
59 {
60 _mm_pause();
61 }
62
63 //
64 // Don't call "pause" too many times. If the wait becomes too big,
65 // clamp it to the MaxWait.
66 //
67
68 if (wait * 2 > MaxWait)
69 {
70 wait = MaxWait;
71 }
72 else
73 {
74 wait = wait * 2;
75 }
76 }
77}
BOOLEAN SpinlockTryLock(volatile LONG *Lock)
Tries to get the lock otherwise returns.
Definition Spinlock.c:41

◆ SpinlockLockWithCustomWait()

void SpinlockLockWithCustomWait ( volatile LONG * Lock,
unsigned MaximumWait )

Tries to get the lock and won't return until successfully get the lock.

Parameters
LONGLock variable
LONGMaxWait Maximum wait (pause) count
126{
127 unsigned wait = 1;
128
129 while (!SpinlockTryLock(Lock))
130 {
131 for (unsigned i = 0; i < wait; ++i)
132 {
133 _mm_pause();
134 }
135
136 //
137 // Don't call "pause" too many times. If the wait becomes too big,
138 // clamp it to the MaxWait.
139 //
140
141 if (wait * 2 > MaximumWait)
142 {
143 wait = MaximumWait;
144 }
145 else
146 {
147 wait = wait * 2;
148 }
149 }
150}

◆ SpinlockTryLock()

BOOLEAN SpinlockTryLock ( volatile LONG * Lock)

Tries to get the lock otherwise returns.

Parameters
LONGLock variable
Returns
BOOLEAN If it was successful on getting the lock
42{
43 return (!(*Lock) && !_interlockedbittestandset(Lock, 0));
44}

◆ SpinlockUnlock()

void SpinlockUnlock ( volatile LONG * Lock)

Release the lock.

Parameters
LONGLock variable
159{
160 *Lock = 0;
161}