LockFreeLIFO.asm 989 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. .686
  2. .model FLAT
  3. PUBLIC _lifo_push
  4. _TEXT SEGMENT
  5. lifo = 4 ; size = 4
  6. entry = 8 ; size = 4
  7. _lifo_push PROC
  8. mov ecx, DWORD PTR 4[esp] ; ecx holds lifo
  9. mov edx, DWORD PTR 8[esp] ; edx holds the new entry
  10. again:
  11. mov eax, DWORD PTR [ecx] ; eax holds the old head
  12. mov DWORD PTR[edx], eax ; new node's 'next' is set to the old head
  13. lock cmpxchg DWORD PTR [ecx], edx
  14. jnz again
  15. ret 0
  16. _lifo_push ENDP
  17. PUBLIC _lifo_pop
  18. _TEXT SEGMENT
  19. lifo = 4 ; size = 4
  20. _lifo_pop PROC
  21. push esi
  22. push ebx
  23. mov esi, DWORD PTR 12[esp] ; esi holds lifo
  24. again:
  25. ; if re-ordered loads become an issue, we could use cmpxchg8b to read in (after zeroing ebx/ecx) or maybe use movq
  26. mov edx, DWORD PTR [esi+4] ; counter
  27. ; or we could put an LFENCE here
  28. mov eax, DWORD PTR [esi] ; pointer
  29. test eax, eax
  30. jz bail
  31. mov ecx, edx ; counter
  32. mov ebx, DWORD PTR [eax] ; pointer->next
  33. inc ecx
  34. lock cmpxchg8b QWORD PTR [esi]
  35. jnz again
  36. bail:
  37. pop ebx
  38. pop esi
  39. ret 0
  40. _lifo_pop ENDP
  41. _TEXT ENDS
  42. END