[cpp]struct RWLock { // Attributes Byte Writers; Byte Lock; Byte Readers; Byte Unused; // Methods Void FASTCALL AquireWrite(); Void FASTCALL AquireRead(); Void FASTCALL ReleaseWrite(); Void FASTCALL ReleaseRead(); }; NAKED Void FASTCALL RWLock::AquireWrite() { __asm { // Signal readers to wait. add byte ptr [ecx], 1 // Aquire lock, no readers. mov edx, 1 ALIGN 16 SPIN: xor eax, eax pause lock cmpxchg word ptr [ecx+1], dx jnz short SPIN // Decrement writer-pending count. sub byte ptr [ecx], 1 // Aquired. ret } } NAKED Void FASTCALL RWLock::AquireRead() { __asm { // Aquire lock. mov edx, 1 ALIGN 16 SPIN: xor eax, eax pause lock cmpxchg word ptr [ecx], dx jnz short SPIN // Increment reader count. lock add byte ptr [ecx+2], 1 // Free lock. mov byte ptr [ecx+1], 0 // Aquired. ret } } FORCEINLINE Void FASTCALL RWLock::ReleaseRead() { // Decrement reader count. this->Readers--; } FORCEINLINE Void FASTCALL RWLock::ReleaseWrite() { // Free lock. this->Lock = 0; }[/cpp]
[cpp]/* * AquireWrite() */ // Signal readers to wait. Writers++; // Aquire lock when no writers or readers are present. while(Lock != 0 && Readers != 0); Lock=1; // Decrement writer-pending count. Writers--; /* * AquireRead() */ // Aquire lock when no writers are either present or pending. while(Writers != 0 && Lock != 0); Lock=1; // Increment reader count. Readers++; // Free lock Lock=0; [/cpp]
Link Copied
[cpp]NAKED Void FASTCALL RWLock::AquireRead()
{
__asm
{
// Aquire lock.
mov edx, 1
ALIGN 16
SPIN:
xor eax, eax
pause
lock cmpxchg word ptr [ecx], dx
[/cpp]
Intel 64 and IA-32 Architectures Software Developer's Manual Volume
3A: System Programming Guide, Part 1
7.1.2.2 Software Controlled Bus Locking
Software should access semaphores (shared memory used for signalling
between multiple processors) using identical addresses *and operand lengths*.
For example, if one processor accesses a semaphore using a word access, other
processors should not access the semaphore using a byte access.
[cpp]NAKED Void FASTCALL RWLock::AquireWrite()
{
__asm
{
// Signal readers to wait.
add byte ptr [ecx], 1
// Aquire lock, no readers.
mov edx, 1
ALIGN 16
SPIN:
xor eax, eax
pause
lock cmpxchg word ptr [ecx+1], dx
jnz short SPIN
// Decrement writer-pending count.
sub byte ptr [ecx], 1
// Aquired.
ret
}
}
[/cpp]
[cpp]
FORCEINLINE Void FASTCALL RWLock::ReleaseRead()
{
// Decrement reader count.
this->Readers--;
}
[/cpp]
For more complete information about compiler optimizations, see our Optimization Notice.