Browse Source

+ AtomicIncrement/Decrement overloads
* tests extended

florian 9 months ago
parent
commit
092ff254f1
4 changed files with 189 additions and 48 deletions
  1. 132 41
      rtl/inc/system.inc
  2. 12 0
      rtl/inc/systemh.inc
  3. 22 2
      tests/test/tatomicmt.pp
  4. 23 5
      tests/test/tatomicmtdword.pp

+ 132 - 41
rtl/inc/system.inc

@@ -2227,83 +2227,131 @@ end;
 
 
 {$ifdef cpu16}
 {$ifdef cpu16}
 function AtomicIncrement (var Target: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedIncrement(Target);
   Result:=InterlockedIncrement(Target);
 end;
 end;
 
 
 
 
 function AtomicDecrement (var Target: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedDecrement(Target);
   Result:=InterlockedDecrement(Target);
 end;
 end;
 
 
+function AtomicIncrement (var Target: smallint; Value: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: smallint;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp+Value,tmp)=tmp;
+end;
 
 
-function AtomicCmpExchange(var Target: smallint; NewValue, Comperand: smallint): smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 
 
+function AtomicDecrement (var Target: smallint; Value: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: smallint;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp-Value,tmp)=tmp;
+end;
+
+
+function AtomicCmpExchange(var Target: smallint; NewValue, Comperand: smallint): smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 begin
 begin
   Result:=InterlockedCompareExchange(Target,NewValue,Comperand);
   Result:=InterlockedCompareExchange(Target,NewValue,Comperand);
 end;
 end;
 
 
 
 
 function AtomicExchange (var Target: smallint;Source : smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: smallint;Source : smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedExchange(Target,Source);
   Result:=InterlockedExchange(Target,Source);
 end;
 end;
 
 
 function AtomicIncrement (var Target: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedIncrement(Target);
   Result:=InterlockedIncrement(Target);
 end;
 end;
 
 
 
 
 function AtomicDecrement (var Target: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedDecrement(Target);
   Result:=InterlockedDecrement(Target);
 end;
 end;
 
 
 
 
-function AtomicCmpExchange(var Target: word; NewValue, Comperand: word): word; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: word; Value: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: word;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp+Value,tmp)=tmp;
+end;
+
 
 
+function AtomicDecrement (var Target: word; Value: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: word;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp-Value,tmp)=tmp;
+end;
+
+
+function AtomicCmpExchange(var Target: word; NewValue, Comperand: word): word; {$ifdef SYSTEMINLINE}inline;{$endif}
 begin
 begin
   Result:=InterlockedCompareExchange(Target, NewValue, Comperand);
   Result:=InterlockedCompareExchange(Target, NewValue, Comperand);
 end;
 end;
 
 
 
 
 function AtomicExchange (var Target: word;Source : word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: word;Source : word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedExchange(Target,Source);
   Result:=InterlockedExchange(Target,Source);
 end;
 end;
 {$endif cpu16}
 {$endif cpu16}
 
 
-function AtomicIncrement (var Target: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 
 
+function AtomicIncrement (var Target: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 begin
 begin
   Result:=InterlockedIncrement(Target);
   Result:=InterlockedIncrement(Target);
 end;
 end;
 
 
 
 
 function AtomicDecrement (var Target: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedDecrement(Target);
   Result:=InterlockedDecrement(Target);
 end;
 end;
 
 
 
 
-function AtomicCmpExchange(var Target: longint; NewValue, Comperand: longint): longint; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: longint; Value: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: longint;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp+Value,tmp)=tmp;
+end;
+
 
 
+function AtomicDecrement (var Target: longint; Value: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: longint;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp-Value,tmp)=tmp;
+end;
+
+
+function AtomicCmpExchange(var Target: longint; NewValue, Comperand: longint): longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 begin
 begin
   Result:=InterlockedCompareExchange(Target,NewValue, Comperand);
   Result:=InterlockedCompareExchange(Target,NewValue, Comperand);
 end;
 end;
 
 
 
 
 function AtomicExchange (var Target: longint;Source : longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: longint;Source : longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedExchange(Target,Source);
   Result:=InterlockedExchange(Target,Source);
 end;
 end;
@@ -2311,30 +2359,45 @@ end;
 
 
 {$ifdef cpu64}
 {$ifdef cpu64}
 function AtomicIncrement (var Target: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedIncrement64(Target);
   Result:=InterlockedIncrement64(Target);
 end;
 end;
 
 
 
 
 function AtomicDecrement (var Target: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=InterlockedDecrement64(Target);
   Result:=InterlockedDecrement64(Target);
 end;
 end;
 
 
 
 
-function AtomicCmpExchange(var Target: int64; NewValue, Comperand: int64): int64; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: int64; Value: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: int64;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp+Value,tmp)=tmp;
+end;
+
+
+function AtomicDecrement (var Target: int64; Value: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: int64;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp-Value,tmp)=tmp;
+end;
 
 
+
+function AtomicCmpExchange(var Target: int64; NewValue, Comperand: int64): int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 begin
 begin
   Result:=InterlockedCompareExchange64(Target,NewValue, Comperand);
   Result:=InterlockedCompareExchange64(Target,NewValue, Comperand);
 end;
 end;
 
 
 
 
 function AtomicExchange (var Target: int64;Source : int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: int64;Source : int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
-
   Result:=InterlockedExchange64(Target,Source);
   Result:=InterlockedExchange64(Target,Source);
 end;
 end;
 {$endif cpu64}
 {$endif cpu64}
@@ -2345,29 +2408,27 @@ end;
 {$ifndef FPC_SYSTEM_DISABLE_INTERLOCK_POINTER_OVERLOAD}
 {$ifndef FPC_SYSTEM_DISABLE_INTERLOCK_POINTER_OVERLOAD}
 
 
 function AtomicIncrement (var Target: pointer) : pointer; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: pointer) : pointer; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
 {$IFDEF CPU64}
 {$IFDEF CPU64}
   Result:=Pointer(InterlockedIncrement64(int64(Target)));
   Result:=Pointer(InterlockedIncrement64(int64(Target)));
-{$ELSE}  
+{$ELSE}
 {$IFDEF CPU16}
 {$IFDEF CPU16}
   Result:=Pointer(InterlockedIncrement(smallint(Target)));
   Result:=Pointer(InterlockedIncrement(smallint(Target)));
-{$ELSE}  
+{$ELSE}
   Result:=Pointer(InterlockedIncrement(Longint(Target)));
   Result:=Pointer(InterlockedIncrement(Longint(Target)));
-{$ENDIF}  
-{$ENDIF}  
+{$ENDIF}
+{$ENDIF}
 end;
 end;
 
 
 
 
 function AtomicDecrement (var Target: pointer) : pointer; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: pointer) : pointer; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
 {$IFDEF CPU64}
 {$IFDEF CPU64}
   Result:=Pointer(InterlockedDecrement64(Int64(Target)));
   Result:=Pointer(InterlockedDecrement64(Int64(Target)));
-{$ELSE}  
+{$ELSE}
 {$IFDEF CPU16}
 {$IFDEF CPU16}
   Result:=Pointer(InterlockedDecrement(smallint(Target)));
   Result:=Pointer(InterlockedDecrement(smallint(Target)));
-{$ELSE}  
+{$ELSE}
    Result:=Pointer(InterlockedDecrement(Longint(Target)));
    Result:=Pointer(InterlockedDecrement(Longint(Target)));
 {$ENDIF}
 {$ENDIF}
 {$ENDIF}
 {$ENDIF}
@@ -2375,29 +2436,27 @@ end;
 
 
 
 
 function AtomicCmpExchange(var Target: pointer; NewValue, Comperand: pointer): pointer; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: pointer; NewValue, Comperand: pointer): pointer; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
 {$IFDEF CPU64}
 {$IFDEF CPU64}
   Result:=Pointer(InterlockedCompareExchange64(Int64(Target),Int64(NewValue), Int64(Comperand)));
   Result:=Pointer(InterlockedCompareExchange64(Int64(Target),Int64(NewValue), Int64(Comperand)));
-{$ELSE}  
+{$ELSE}
 {$IFDEF CPU16}
 {$IFDEF CPU16}
   Result:=Pointer(InterlockedCompareExchange(smallint(Target),smallint(NewValue),smallint(Comperand)));
   Result:=Pointer(InterlockedCompareExchange(smallint(Target),smallint(NewValue),smallint(Comperand)));
-{$ELSE}  
+{$ELSE}
   Result:=Pointer(InterlockedCompareExchange(LongInt(Target),LongInt(NewValue), LongInt(Comperand)));
   Result:=Pointer(InterlockedCompareExchange(LongInt(Target),LongInt(NewValue), LongInt(Comperand)));
-{$ENDIF}  
-{$ENDIF}  
+{$ENDIF}
+{$ENDIF}
 end;
 end;
 
 
 
 
 function AtomicExchange(var Target: pointer;Source : pointer) : pointer; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange(var Target: pointer;Source : pointer) : pointer; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
 {$IFDEF CPU64}
 {$IFDEF CPU64}
   Result:=Pointer(InterlockedExchange64(Int64(Target),Int64(Source)));
   Result:=Pointer(InterlockedExchange64(Int64(Target),Int64(Source)));
-{$ELSE}  
+{$ELSE}
 {$IFDEF CPU16}
 {$IFDEF CPU16}
   Result:=Pointer(InterlockedExchange(smallint(Target),smallint(Source)));
   Result:=Pointer(InterlockedExchange(smallint(Target),smallint(Source)));
-{$ELSE}  
+{$ELSE}
   Result:=Pointer(InterlockedExchange(LongInt(Target),LongInt(Source)));
   Result:=Pointer(InterlockedExchange(LongInt(Target),LongInt(Source)));
 {$ENDIF}
 {$ENDIF}
 {$ENDIF}
 {$ENDIF}
@@ -2406,28 +2465,44 @@ end;
 {$endif FPC_SYSTEM_DISABLE_INTERLOCK_POINTER_OVERLOAD}
 {$endif FPC_SYSTEM_DISABLE_INTERLOCK_POINTER_OVERLOAD}
 
 
 function AtomicIncrement (var Target: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=Cardinal(InterlockedIncrement(Longint(Target)));
   Result:=Cardinal(InterlockedIncrement(Longint(Target)));
 end;
 end;
 
 
 
 
 function AtomicDecrement (var Target: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=Cardinal(InterlockedDecrement(Longint(Target)));
   Result:=Cardinal(InterlockedDecrement(Longint(Target)));
 end;
 end;
 
 
 
 
-function AtomicCmpExchange(var Target: Cardinal; NewValue, Comperand: Cardinal): Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: Cardinal; Value: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: Cardinal;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp+Value,tmp)=tmp;
+end;
+
+
+function AtomicDecrement (var Target: Cardinal; Value: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: Cardinal;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp-Value,tmp)=tmp;
+end;
 
 
+
+function AtomicCmpExchange(var Target: Cardinal; NewValue, Comperand: Cardinal): Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 begin
 begin
   Result:=Cardinal(InterlockedCompareExchange(Longint(Target),Longint(NewValue), Longint(Comperand)));
   Result:=Cardinal(InterlockedCompareExchange(Longint(Target),Longint(NewValue), Longint(Comperand)));
 end;
 end;
 
 
 
 
 function AtomicExchange (var Target: Cardinal;Source : Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: Cardinal;Source : Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=Cardinal(InterlockedExchange(Longint(Target),Longint(Source)));
   Result:=Cardinal(InterlockedExchange(Longint(Target),Longint(Source)));
 end;
 end;
@@ -2435,28 +2510,44 @@ end;
 
 
 {$ifdef cpu64}
 {$ifdef cpu64}
 function AtomicIncrement (var Target: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=QWord(InterlockedIncrement64(Int64(Target)));
   Result:=QWord(InterlockedIncrement64(Int64(Target)));
 end;
 end;
 
 
 
 
 function AtomicDecrement (var Target: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=QWord(InterlockedDecrement64(int64(Target)));
   Result:=QWord(InterlockedDecrement64(int64(Target)));
 end;
 end;
 
 
 
 
-function AtomicCmpExchange(var Target: qword; NewValue, Comperand: qword): qword; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: qword; Value: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: qword;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp+Value,tmp)=tmp;
+end;
 
 
+
+function AtomicDecrement (var Target: qword; Value: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
+var
+  tmp: qword;
+begin
+  repeat
+    tmp:=Target;
+  until AtomicCmpExchange(Target,tmp-Value,tmp)=tmp;
+end;
+
+
+function AtomicCmpExchange(var Target: qword; NewValue, Comperand: qword): qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 begin
 begin
   Result:=QWord(InterlockedCompareExchange64(Int64(Target),Int64(NewValue), Int64(Comperand)));
   Result:=QWord(InterlockedCompareExchange64(Int64(Target),Int64(NewValue), Int64(Comperand)));
 end;
 end;
 
 
 
 
 function AtomicExchange (var Target: qword;Source : qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: qword;Source : qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
-
 begin
 begin
   Result:=QWord(InterlockedExchange64(Int64(Target),Int64(Source)));
   Result:=QWord(InterlockedExchange64(Int64(Target),Int64(Source)));
 end;
 end;

+ 12 - 0
rtl/inc/systemh.inc

@@ -1565,6 +1565,8 @@ Function GetThreadID:TThreadID;{$ifdef SYSTEMINLINE}inline;{$endif}
 {$ifdef cpu16}
 {$ifdef cpu16}
 function AtomicIncrement (var Target: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: smallint; Value: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicDecrement (var Target: smallint; Value: smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: smallint; NewValue, Comperand: smallint): smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: smallint; NewValue, Comperand: smallint): smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: smallint;Source : smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: smallint;Source : smallint) : smallint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function InterlockedIncrement (var Target: smallint) : smallint; public name 'FPC_INTERLOCKEDINCREMENT16';
 function InterlockedIncrement (var Target: smallint) : smallint; public name 'FPC_INTERLOCKEDINCREMENT16';
@@ -1575,6 +1577,8 @@ function InterlockedCompareExchange(var Target: smallint; NewValue: smallint; Co
 {$endif cpu16}
 {$endif cpu16}
 function AtomicIncrement (var Target: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: longint; Value: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicDecrement (var Target: longint; Value: longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: longint; NewValue, Comperand: longint): longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: longint; NewValue, Comperand: longint): longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: longint;Source : longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: longint;Source : longint) : longint; {$ifdef SYSTEMINLINE}inline;{$endif}
 function InterlockedIncrement (var Target: longint) : longint; public name 'FPC_INTERLOCKEDINCREMENT';
 function InterlockedIncrement (var Target: longint) : longint; public name 'FPC_INTERLOCKEDINCREMENT';
@@ -1585,6 +1589,8 @@ function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comp
 {$ifdef cpu64}
 {$ifdef cpu64}
 function AtomicIncrement (var Target: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: int64; Value: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicDecrement (var Target: int64; Value: int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: int64; NewValue, Comperand: int64): int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: int64; NewValue, Comperand: int64): int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: int64;Source : int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: int64;Source : int64) : int64; {$ifdef SYSTEMINLINE}inline;{$endif}
 function InterlockedIncrement64 (var Target: int64) : int64; public name 'FPC_INTERLOCKEDINCREMENT64';
 function InterlockedIncrement64 (var Target: int64) : int64; public name 'FPC_INTERLOCKEDINCREMENT64';
@@ -1636,6 +1642,8 @@ function InterlockedCompareExchangePointer(var Target: Pointer; NewValue: Pointe
 {$ifdef cpu16}
 {$ifdef cpu16}
 function AtomicIncrement (var Target: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: word; Value: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicDecrement (var Target: word; Value: word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: word; NewValue, Comperand: word): word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: word; NewValue, Comperand: word): word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: word;Source : word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: word;Source : word) : word; {$ifdef SYSTEMINLINE}inline;{$endif}
 function InterlockedIncrement (var Target: word) : word; external name 'FPC_INTERLOCKEDINCREMENT16';
 function InterlockedIncrement (var Target: word) : word; external name 'FPC_INTERLOCKEDINCREMENT16';
@@ -1646,6 +1654,8 @@ function InterlockedCompareExchange(var Target: word; NewValue: word; Comperand:
 {$endif cpu16}
 {$endif cpu16}
 function AtomicIncrement (var Target: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: Cardinal; Value: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicDecrement (var Target: Cardinal; Value: Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: Cardinal; NewValue, Comperand: Cardinal): Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: Cardinal; NewValue, Comperand: Cardinal): Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: Cardinal;Source : Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: Cardinal;Source : Cardinal) : Cardinal; {$ifdef SYSTEMINLINE}inline;{$endif}
 function InterlockedIncrement (var Target: cardinal) : cardinal; external name 'FPC_INTERLOCKEDINCREMENT';
 function InterlockedIncrement (var Target: cardinal) : cardinal; external name 'FPC_INTERLOCKEDINCREMENT';
@@ -1656,6 +1666,8 @@ function InterlockedCompareExchange(var Target: cardinal; NewValue: cardinal; Co
 {$ifdef cpu64}
 {$ifdef cpu64}
 function AtomicIncrement (var Target: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicIncrement (var Target: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicDecrement (var Target: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicIncrement (var Target: qword; Value: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
+function AtomicDecrement (var Target: qword; Value: qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: qword; NewValue, Comperand: qword): qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicCmpExchange(var Target: qword; NewValue, Comperand: qword): qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: qword;Source : qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function AtomicExchange (var Target: qword;Source : qword) : qword; {$ifdef SYSTEMINLINE}inline;{$endif}
 function InterlockedIncrement64 (var Target: qword) : qword; external name 'FPC_INTERLOCKEDINCREMENT64';
 function InterlockedIncrement64 (var Target: qword) : qword; external name 'FPC_INTERLOCKEDINCREMENT64';

+ 22 - 2
tests/test/tatomicmt.pp

@@ -15,7 +15,7 @@ uses
   SysUtils, Classes;
   SysUtils, Classes;
 
 
 type
 type
-  TOperation = (opAdd, opDec, opExchange, opExchangeAdd, opExchangeDec, opCompareExchange);
+  TOperation = (opAdd, opDec, opAdd7, opDec7, opExchange, opExchangeAdd, opExchangeDec, opCompareExchange);
 
 
   TWorker = class(TThread)
   TWorker = class(TThread)
   private
   private
@@ -29,7 +29,7 @@ type
   end;
   end;
 
 
 const
 const
-  TotalThreadCount : longint = 50;
+  TotalThreadCount : longint = 60;
   TestCount = 1000000;
   TestCount = 1000000;
   WaitTime = 60;
   WaitTime = 60;
 
 
@@ -83,6 +83,22 @@ begin
             break;
             break;
         end;
         end;
       end;
       end;
+    opAdd7:
+      begin
+        for i:=1 to FCount do begin
+          AtomicIncrement(Counter,7);
+          if AbortThread then
+            break;
+        end;
+      end;
+    opDec7:
+      begin
+        for i:=1 to FCount do begin
+          AtomicDecrement(Counter,7);
+          if AbortThread then
+            break;
+        end;
+      end;
     opExchange:
     opExchange:
       begin
       begin
         for i:=1 to FCount do begin
         for i:=1 to FCount do begin
@@ -195,6 +211,10 @@ begin
     Inc(j);
     Inc(j);
     workers[j]:=New_TWorker_Thread(TestCount, opDec);
     workers[j]:=New_TWorker_Thread(TestCount, opDec);
     Inc(j);
     Inc(j);
+    workers[j]:=New_TWorker_Thread(TestCount, opAdd7);
+    Inc(j);
+    workers[j]:=New_TWorker_Thread(TestCount, opDec7);
+    Inc(j);
     workers[j]:=New_TWorker_Thread(TestCount div 3, opExchange);
     workers[j]:=New_TWorker_Thread(TestCount div 3, opExchange);
     Inc(j);
     Inc(j);
     workers[j]:=New_TWorker_Thread(TestCount, opExchangeAdd);
     workers[j]:=New_TWorker_Thread(TestCount, opExchangeAdd);

+ 23 - 5
tests/test/tatomicmtdword.pp

@@ -15,7 +15,7 @@ uses
   SysUtils, Classes;
   SysUtils, Classes;
 
 
 type
 type
-  TOperation = (opAdd, opDec, opExchange, opExchangeAdd, opExchangeDec, opCompareExchange);
+  TOperation = (opAdd, opDec, opAdd7, opDec7, opExchange, opExchangeAdd, opExchangeDec, opCompareExchange);
 
 
   TWorker = class(TThread)
   TWorker = class(TThread)
   private
   private
@@ -29,7 +29,7 @@ type
   end;
   end;
 
 
 const
 const
-  TotalThreadCount : longint = 50;
+  TotalThreadCount : longint = 70;
   TestCount = 1000000;
   TestCount = 1000000;
   WaitTime = 60;
   WaitTime = 60;
 
 
@@ -83,6 +83,22 @@ begin
             break;
             break;
         end;
         end;
       end;
       end;
+    opAdd7:
+      begin
+        for i:=1 to FCount do begin
+          AtomicIncrement(Counter,7);
+          if AbortThread then
+            break;
+        end;
+      end;
+    opDec7:
+      begin
+        for i:=1 to FCount do begin
+          AtomicDecrement(Counter,7);
+          if AbortThread then
+            break;
+        end;
+      end;
     opExchange:
     opExchange:
       begin
       begin
         for i:=1 to FCount do begin
         for i:=1 to FCount do begin
@@ -92,7 +108,6 @@ begin
             break;
             break;
         end;
         end;
       end;
       end;
-{
     opExchangeAdd:
     opExchangeAdd:
       begin
       begin
         for i:=1 to FCount do begin
         for i:=1 to FCount do begin
@@ -104,12 +119,11 @@ begin
     opExchangeDec:
     opExchangeDec:
       begin
       begin
         for i:=1 to FCount do begin
         for i:=1 to FCount do begin
-          InterlockedExchangeAdd(Counter, -3);
+          InterlockedExchangeAdd(Counter, DWord(-3));
           if AbortThread then
           if AbortThread then
             break;
             break;
         end;
         end;
       end;
       end;
-}
     opCompareExchange:
     opCompareExchange:
       begin
       begin
         opt:=FOption and 1;
         opt:=FOption and 1;
@@ -197,6 +211,10 @@ begin
     Inc(j);
     Inc(j);
     workers[j]:=New_TWorker_Thread(TestCount, opDec);
     workers[j]:=New_TWorker_Thread(TestCount, opDec);
     Inc(j);
     Inc(j);
+    workers[j]:=New_TWorker_Thread(TestCount, opAdd7);
+    Inc(j);
+    workers[j]:=New_TWorker_Thread(TestCount, opDec7);
+    Inc(j);
     workers[j]:=New_TWorker_Thread(TestCount div 3, opExchange);
     workers[j]:=New_TWorker_Thread(TestCount div 3, opExchange);
     Inc(j);
     Inc(j);
 {
 {