diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/replicant/nu/win-x86/LockFreeLIFO.asm | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/replicant/nu/win-x86/LockFreeLIFO.asm')
-rw-r--r-- | Src/replicant/nu/win-x86/LockFreeLIFO.asm | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/Src/replicant/nu/win-x86/LockFreeLIFO.asm b/Src/replicant/nu/win-x86/LockFreeLIFO.asm new file mode 100644 index 00000000..dd67e5b1 --- /dev/null +++ b/Src/replicant/nu/win-x86/LockFreeLIFO.asm @@ -0,0 +1,50 @@ +.686 +.model FLAT + +PUBLIC _lifo_push +_TEXT SEGMENT +lifo = 4 ; size = 4 +entry = 8 ; size = 4 +_lifo_push PROC + mov ecx, DWORD PTR 4[esp] ; ecx holds lifo + mov edx, DWORD PTR 8[esp] ; edx holds the new entry +again: + mov eax, DWORD PTR [ecx] ; eax holds the old head + mov DWORD PTR[edx], eax ; new node's 'next' is set to the old head + lock cmpxchg DWORD PTR [ecx], edx + jnz again + ret 0 +_lifo_push ENDP + +PUBLIC _lifo_pop +_TEXT SEGMENT +lifo = 4 ; size = 4 +_lifo_pop PROC + push esi + push ebx + mov esi, DWORD PTR 12[esp] ; esi holds lifo +again: + ; if re-ordered loads become an issue, we could use cmpxchg8b to read in (after zeroing ebx/ecx) or maybe use movq + mov edx, DWORD PTR [esi+4] ; counter + ; or we could put an LFENCE here + mov eax, DWORD PTR [esi] ; pointer + test eax, eax + jz bail + + mov ecx, edx ; counter + mov ebx, DWORD PTR [eax] ; pointer->next + inc ecx + + lock cmpxchg8b QWORD PTR [esi] + jnz again + +bail: + pop ebx + pop esi + ret 0 +_lifo_pop ENDP + +_TEXT ENDS + +END + |