I’ve been reviewing the WRK, and ReactOS to see how interlocked SLIST works. I’m trying to tidy up my XLIST. I see that on entry to these functions, in 32 bit mode, the sequence PUSHFD, _disable(), grab spinlock, do work, POPFD. The spinlock is grabbed in the same way as if you had called KeAcquireSpinlockAtDpcLevel(); IRQL is not raised, &c. So, I threw together this bit of code:
#define EFLAGS_IF_MASK 0x00000200
#define EFLAGS_IF_SHIFT 9
PXLIST_ENTRY InterlockedInsertTailXList(PXLIST_HEADER List,
PXLIST_ENTRY Entry, PKSPIN_LOCK Lock) {
#if (1)
unsigned int Flags = GetCallersEflags();
_disable();
KeAcquireSpinLockAtDpcLevel(Lock);
#else
KLOCK_QUEUE_HANDLE LockHandle;
KeAcquireInStackQueuedSpinLock(Lock, &LockHandle);
#endif
InsertTailXList(List, Entry);
#if (1)
KeReleaseSpinLockFromDpcLevel(Lock);
if (Flags & EFLAGS_IF_MASK) {
_enable();
}
#else
KeReleaseInStackQueuedSpinLock(&LockHandle);
#endif
return Entry;
}
I know that there are amd64 interlocked instructions for just about everything (xor, &c.), and I’ll get around to that at some point if they are practical. I am just tinkering at the moment. Although pushfq and popfq are valid in 64 bit, Visual Studio coughs at __asm pushfq and __asm popfq. In 32 bit mode, all is OK using __asm pushfd and __asm popfd. I threw the above code together.
How bad is this?