Advertisement
Guest User

Untitled

a guest
Jun 30th, 2015
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.04 KB | None | 0 0
  1. 1)Lock-Free
  2. 2)Wait-Free
  3. 3)Wait-Freedom
  4.  
  5. function TgjRingBuffer.InsertLeft(const link: pointer): integer;
  6. var
  7. AtStartReference: cardinal;
  8. CPUTimeStamp : int64;
  9. CurrentLeft : pointer;
  10. CurrentReference: cardinal;
  11. NewLeft : PReferencedPtr;
  12. Reference : cardinal;
  13. label
  14. TryAgain;
  15. begin
  16. Reference := GetThreadId + 1; //Reference.bit0 := 1
  17. with rbRingBuffer^ do begin
  18. TryAgain:
  19. //Set Left.Reference with respect to all other cores :)
  20. CPUTimeStamp := GetCPUTimeStamp + LoopTicks;
  21. AtStartReference := Left.Reference OR 1; //Reference.bit0 := 1
  22. repeat
  23. CurrentReference := Left.Reference;
  24. until (CurrentReference AND 1 = 0)or (GetCPUTimeStamp - CPUTimeStamp > 0);
  25. //No threads present in ring buffer or current thread timeout
  26. if ((CurrentReference AND 1 <> 0) and (AtStartReference <> CurrentReference)) or
  27. not CAS32(CurrentReference, Reference, Left.Reference) then
  28. goto TryAgain;
  29. //Calculate RingBuffer NewLeft address
  30. CurrentLeft := Left.Link;
  31. NewLeft := pointer(cardinal(CurrentLeft) - SizeOf(TReferencedPtr));
  32. if cardinal(NewLeft) < cardinal(@Buffer) then
  33. NewLeft := EndBuffer;
  34. //Calcolate distance
  35. result := integer(Right.Link) - Integer(NewLeft);
  36. //Check buffer full
  37. if result = 0 then //Clear Reference if task still own reference
  38. if CAS32(Reference, 0, Left.Reference) then
  39. Exit else
  40. goto TryAgain;
  41. //Set NewLeft.Reference
  42. NewLeft^.Reference := Reference;
  43. SFence;
  44. //Try to set link and try to exchange NewLeft and clear Reference if task own reference
  45. if (Reference <> Left.Reference) or
  46. not CAS64(NewLeft^.Link, Reference, link, Reference, NewLeft^) or
  47. not CAS64(CurrentLeft, Reference, NewLeft, 0, Left) then
  48. goto TryAgain;
  49. //Calcolate result
  50. if result < 0 then
  51. result := Length - integer(cardinal(not Result) div SizeOf(TReferencedPtr)) else
  52. result := cardinal(result) div SizeOf(TReferencedPtr);
  53. end; //with
  54. end; { TgjRingBuffer.InsertLeft }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement