+ AtomicIncrement/Decrement overloads

* tests extended
This commit is contained in:
florian 2024-11-10 14:56:10 +01:00
parent 42c5e368bd
commit 092ff254f1
4 changed files with 189 additions and 48 deletions

View File

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

View File

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

View File

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

View File

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