Concurrent data processing
This commit is contained in:
+37
-1
@@ -4,7 +4,8 @@ interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
Myc.Signals;
|
||||
Myc.Signals,
|
||||
System.Contnrs;
|
||||
|
||||
type
|
||||
TTaskManager = record
|
||||
@@ -38,6 +39,16 @@ type
|
||||
procedure WaitFor(const State: TState); inline;
|
||||
end;
|
||||
|
||||
TQueue = record
|
||||
strict private
|
||||
[volatile]
|
||||
FQueueLock: Integer;
|
||||
FState: TState;
|
||||
public
|
||||
function Enqueue(const Func: TFunc<TState>): TState;
|
||||
class operator Initialize(out Dest: TQueue);
|
||||
end;
|
||||
|
||||
var
|
||||
TaskManager: TTaskManager;
|
||||
|
||||
@@ -174,4 +185,29 @@ begin
|
||||
Result := A.FTaskManager;
|
||||
end;
|
||||
|
||||
function TQueue.Enqueue(const Func: TFunc<TState>): TState;
|
||||
begin
|
||||
var state := TaskManager.RunTask(FState, Func);
|
||||
|
||||
repeat
|
||||
if FQueueLock > 0 then
|
||||
begin
|
||||
YieldProcessor;
|
||||
continue;
|
||||
end;
|
||||
until AtomicCmpExchange(FQueueLock, 1, 0) = 0;
|
||||
|
||||
try
|
||||
Result := FState;
|
||||
FState := state;
|
||||
finally
|
||||
AtomicDecrement(FQueueLock);
|
||||
end;
|
||||
end;
|
||||
|
||||
class operator TQueue.Initialize(out Dest: TQueue);
|
||||
begin
|
||||
Dest.FQueueLock := 0;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user