utcinterlocked.pp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. unit utcinterlocked;
  2. {$mode Objfpc}
  3. interface
  4. uses punit;
  5. Procedure RegisterTests;
  6. implementation
  7. uses
  8. SysUtils, SyncObjs, Classes;
  9. function testlongint : TTestString;
  10. var
  11. i32: Longint;
  12. New32, Old32: Longint;
  13. changed : Boolean;
  14. begin
  15. Result:='';
  16. {* test all kinds of Longint usage *}
  17. i32 := 12;
  18. New32 := TInterlocked.Increment(i32);
  19. if New32 <> 13 then Exit('Error 1');
  20. if i32 <> 13 then Exit('Error 2');
  21. New32 := TInterlocked.Decrement(i32);
  22. if New32 <> 12 then Exit('Error 3');
  23. if i32 <> 12 then Exit('Error 4');
  24. New32 := TInterlocked.Add(i32, 12);
  25. if New32 <> 24 then Exit('Error 5');
  26. if i32 <> 24 then Exit('Error 6');
  27. Old32 := TInterlocked.CompareExchange(i32, 36, 24);
  28. if Old32 <> 24 then Exit('Error 7');
  29. if i32 <> 36 then Exit('Error 8');
  30. Old32 := TInterlocked.CompareExchange(i32, 48, 36, Changed);
  31. if Old32 <> 36 then Exit('Error 9');
  32. if Changed <> True then Exit('Error 10');
  33. if i32 <> 48 then Exit('Error 11');
  34. Old32 := TInterlocked.CompareExchange(i32, 123, 96, Changed);
  35. if Old32 <> 48 then Exit('Error 12');
  36. if Changed <> False then Exit('Error 13');
  37. if i32 <> 48 then Exit('Error 14');
  38. Old32 := TInterlocked.Exchange(i32, 96);
  39. if Old32 <> 48 then Exit('Error 15');
  40. if i32 <> 96 then Exit('Error 15');
  41. end;
  42. Function TestSingle : TTestString;
  43. var
  44. s1, s2, sOld: Single;
  45. begin
  46. Result:='';
  47. {* test all kinds of Single usage *}
  48. s1 := Single(3.14);
  49. s2 := Single(6.28);
  50. sOld := TInterlocked.CompareExchange(s1, s2, s1);
  51. if sOld <> Single(3.14) then Exit('Error 53');
  52. if s1 = Single(3.14) then Exit('Error 54');
  53. if s1 <> s2 then Exit('Error 55');
  54. sOld := TInterlocked.CompareExchange(s1, sOld, s2);
  55. if sOld <> Single(6.28) then Exit('Error 56');
  56. if s1 <> Single(3.14) then Exit('Error 57');
  57. if s1 = s2 then Exit('Error 58');
  58. sOld := TInterlocked.Exchange(s2, s1);
  59. if sOld <> Single(6.28) then Exit('Error 59');
  60. if s1 <> Single(3.14) then Exit('Error 60');
  61. if s1 <> s2 then Exit('Error 61');
  62. end;
  63. {$ifdef cpu64}
  64. function testint64 : TTestString;
  65. var
  66. i64: Int64;
  67. New64, Old64: Int64;
  68. begin
  69. {* test all kinds of Int64 usage *}
  70. i64 := 12;
  71. New64 := TInterlocked.Increment(i64);
  72. if New64 <> 13 then Exit('Error 20');
  73. if i64 <> 13 then Exit('Error 21');
  74. New64 := TInterlocked.Decrement(i64);
  75. if New64 <> 12 then Exit('Error 22');
  76. if i64 <> 12 then Exit('Error 23');
  77. New64 := TInterlocked.Add(i64, 12);
  78. if New64 <> 24 then Exit('Error 24');
  79. if i64 <> 24 then Exit('Error 25');
  80. Old64 := TInterlocked.CompareExchange(i64, 36, 24);
  81. if Old64 <> 24 then Exit('Error 26');
  82. if i64 <> 36 then Exit('Error 27');
  83. Old64 := TInterlocked.Exchange(i64, 48);
  84. if Old64 <> 36 then Exit('Error 28');
  85. if i64 <> 48 then Exit('Error 29');
  86. Old64 := TInterlocked.Read(i64);
  87. if Old64 <> 48 then Exit('Error 30');
  88. if i64 <> 48 then Exit('Error 31');
  89. end;
  90. Function TestDouble : TTestString;
  91. var
  92. d1, d2, dOld: Double;
  93. begin
  94. Result:='';
  95. {* test all kinds of Double usage *}
  96. d1 := Double(3.14);
  97. d2 := Double(6.28);
  98. dOld := TInterlocked.CompareExchange(d1, d2, d1);
  99. if dOld <> Double(3.14) then Exit('Error 44');
  100. if d1 = Double(3.14) then Exit('Error 45');
  101. if d1 <> d2 then Exit('Error 46');
  102. d1 := dOld;
  103. dOld := TInterlocked.Exchange(d1, d2);
  104. if dOld <> Double(3.14) then Exit('Error 47');
  105. if d1 <> Double(6.28) then Exit('Error 48');
  106. if d1 <> d2 then Exit('Error 49');
  107. dOld := TInterlocked.CompareExchange(d1, dOld, d2);
  108. if dOld <> Double(6.28) then Exit('Error 50');
  109. if d1 <> Double(3.14) then Exit('Error 51');
  110. if d1 = d2 then Exit('Error 52');
  111. end;
  112. {$endif}
  113. function TestObject : TTeststring;
  114. var
  115. list1, list2, oldlist: TStringList;
  116. begin
  117. Result:='';
  118. {* test all kinds of TObject and generic class usage *}
  119. List2:=nil;
  120. list1 := TStringList.Create;
  121. try
  122. list2 := TStringList.Create;
  123. list1.Add('A');
  124. list2.Add('B');
  125. list2.Add('C');
  126. { TObject }
  127. oldlist := TStringList(TInterlocked.CompareExchange(TObject(list1), TObject(list2), TObject(list1)));
  128. if list1 <> list2 then Exit('Error 32');
  129. if oldlist.Count = list1.Count then Exit('Error 33');
  130. if oldlist.Count = list2.Count then Exit('Error 34');
  131. oldlist := TStringList(TInterlocked.Exchange(TObject(list1), TObject(oldlist)));
  132. if oldlist <> list2 then Exit('Error 35');
  133. if list1.Count <> 1 then Exit('Error 36');
  134. if list2.Count <> 2 then Exit('Error 37');
  135. finally
  136. list1.Free;
  137. list2.Free;
  138. end;
  139. end;
  140. function TestGeneric : TTeststring;
  141. var
  142. list1, list2, oldlist: TStringList;
  143. begin
  144. Result:='';
  145. List2:=nil;
  146. list1 := TStringList.Create;
  147. try
  148. list2 := TStringList.Create;
  149. list1.Add('A');
  150. list2.Add('B');
  151. list2.Add('C');
  152. { generic class }
  153. oldlist := TInterlocked.specialize CompareExchange<TStringList>(list1, list2, list1);
  154. if list1 <> list2 then Exit('Error 38');
  155. if oldlist.Count = list1.Count then Exit('Error 39');
  156. if oldlist.Count = list2.Count then Exit('Error 40');
  157. oldlist := TInterlocked.specialize Exchange<TStringList>(list1, oldlist);
  158. if oldlist <> list2 then Exit('Error 41');
  159. if list1.Count <> 1 then Exit('Error 42');
  160. if list2.Count <> 2 then Exit('Error 43');
  161. finally
  162. list1.Free;
  163. list2.Free;
  164. end;
  165. end;
  166. Function TestBitTestAndClear : TTestString;
  167. var
  168. i32: Longint;
  169. New32, Old32: Longint;
  170. i64: Int64;
  171. New64, Old64: Int64;
  172. Changed, OldBitValue: Boolean;
  173. list1, list2, oldlist: TStringList;
  174. d1, d2, dOld: Double;
  175. s1, s2, sOld: Single;
  176. begin
  177. {* test BitTestAndClear usage *}
  178. i32 := 96;
  179. OldBitValue := TInterlocked.BitTestAndClear(i32, 6);
  180. if OldBitValue <> True then Exit('Error 62');
  181. if i32 <> 32 then Exit('Error 63');
  182. OldBitValue := TInterlocked.BitTestAndClear(i32, 6);
  183. if OldBitValue <> False then Exit('Error 64');
  184. if i32 <> 32 then Exit('Error 65');
  185. {* test BitTestAndSet usage *}
  186. OldBitValue := TInterlocked.BitTestAndSet(i32, 6);
  187. if OldBitValue <> False then Exit('Error 66');
  188. if i32 <> 96 then Exit('Error 67');
  189. OldBitValue := TInterlocked.BitTestAndSet(i32, 6);
  190. if OldBitValue <> True then Exit('Error 68');
  191. if i32 <> 96 then Exit('Error 69');
  192. end;
  193. Procedure RegisterTests;
  194. var
  195. lSuite : PSuite;
  196. begin
  197. lSuite:=AddSuite('TInterlocked');
  198. AddTest('Longint',@TestLongint,lSuite);
  199. {$IFDEF CPU64}
  200. AddTest('Int64',@TestInt64,lSuite);
  201. AddTest('Double',@TestDouble,lSuite);
  202. {$ENDIF}
  203. AddTest('Single',@TestSingle,lSuite);
  204. AddTest('Object',@TestObject,lSuite);
  205. AddTest('Generic',@TestGeneric,lSuite);
  206. AddTest('BitTestAndClear',@TestBitTestAndClear,lSuite);
  207. end;
  208. end.