AtomicInt.hx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package haxe.atomic;
  2. import java.util.concurrent.atomic.AtomicInteger;
  3. #if doc_gen
  4. @:coreApi
  5. @:coreType
  6. abstract AtomicInt {
  7. public function new(value:Int):Void;
  8. public function add(b:Int):Int;
  9. public function sub(b:Int):Int;
  10. public function and(b:Int):Int;
  11. public function or(b:Int):Int;
  12. public function xor(b:Int):Int;
  13. public function compareExchange(expected:Int, replacement:Int):Int;
  14. public function exchange(value:Int):Int;
  15. public function load():Int;
  16. public function store(value:Int):Int;
  17. }
  18. #else
  19. abstract AtomicInt(AtomicInteger) {
  20. public inline function new(value:Int) {
  21. this = new AtomicInteger(value);
  22. }
  23. private inline function cas_loop(value:Int, op:(a:Int, b:Int) -> Int):Int {
  24. var val;
  25. do {
  26. val = this.get();
  27. } while (!this.compareAndSet(val, op(val, value)));
  28. return val;
  29. }
  30. public inline function add(b:Int):Int {
  31. return this.getAndAdd(b);
  32. }
  33. public inline function sub(b:Int):Int {
  34. return this.getAndAdd(-b);
  35. }
  36. public inline function and(b:Int):Int {
  37. return cas_loop(b, (a:Int, b:Int) -> a & b);
  38. }
  39. public inline function or(b:Int):Int {
  40. return cas_loop(b, (a:Int, b:Int) -> a | b);
  41. }
  42. public inline function xor(b:Int):Int {
  43. return cas_loop(b, (a:Int, b:Int) -> a ^ b);
  44. }
  45. public inline function compareExchange(expected:Int, replacement:Int):Int {
  46. // Java's compareAndSet returns a boolean, so do a CAS loop to be able to return the original value without a potential race condition
  47. var original;
  48. var real_replacement;
  49. do {
  50. original = this.get();
  51. real_replacement = original == expected ? replacement : original;
  52. } while (!this.compareAndSet(original, real_replacement));
  53. return original;
  54. }
  55. public inline function exchange(value:Int):Int {
  56. return this.getAndSet(value);
  57. }
  58. public inline function load():Int {
  59. return this.get();
  60. }
  61. public inline function store(value:Int):Int {
  62. this.set(value);
  63. return value;
  64. }
  65. }
  66. #end