diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/replicant/nu/win-x86/LockFreeLIFO.asm | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz |
Merge pull request #5 from WinampDesktop/community
Merge to main
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 + |