Ignore:
Timestamp:
Jan 26, 2011, 8:06:25 AM (13 years ago)
Author:
george
Message:
  • Added: Now multiple thread managers are running within single scheduler.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • MicroThreading/UMicroThreading.pas

    r146 r147  
    3434    FStackSize: Integer;
    3535    FBasePointer: Pointer;
    36     FWakeupTime: TDateTime;
     36    FWakeUpTime: TDateTime;
    3737    FTerminated: Boolean;
    3838    FExecuted: Boolean; // At first go through Execute method, then switch context
    3939    FFinished: Boolean;
     40    FSuspended: Boolean;
     41    FState: TMicroThreadState;
     42    FScheduler: TMicroThreadScheduler;
     43    FManager: TMicroThreadManager;
     44    FId: Integer;
    4045  public
    41     Id: Integer;
    4246    Name: string;
    4347    Priority: Integer;
    44     State: TMicroThreadState;
    45     Manager: TMicroThreadManager;
    46     Scheduler: TMicroThreadScheduler;
    4748    Completion: Single; // Can be used for progress information in range <0, 1>
    4849    procedure Execute; virtual;
    4950
    50     // Internal execution
    5151    procedure Yield;
    5252    procedure Sleep(Duration: TDateTime);
    5353    function WaitForSignal(Signal: TEvent): TWaitResult;
    54 
    55     // External execution
    5654    procedure WaitFor;
    5755    procedure Terminate;
    5856    procedure Start;
    59     procedure Stop;
     57    procedure Resume;
     58    procedure Suspend;
    6059
    6160    constructor Create(CreateSuspended: Boolean;
    6261      const StackSize: SizeUInt = DefaultStackSize);
    6362    destructor Destroy; override;
     63    property Id: Integer read FId;
     64    property State: TMicroThreadState read FState;
    6465    property ExecutionTime: TDateTime read FExecutionTime;
    6566    property FreeOnTerminate: Boolean read FFreeOnTerminate
    6667      write FFreeOnTerminate;
    6768    property Terminated: Boolean read FTerminated;
     69    property Scheduler: TMicroThreadScheduler read FScheduler;
     70    property Manager: TMicroThreadManager read FManager;
    6871  end;
    6972
     
    8083
    8184  TMicroThreadSchedulerPoolThread = class(TThread)
    82     Scheduler: TMicroThreadScheduler;
    8385    Manager: TMicroThreadManager;
    8486    procedure Execute; override;
     87    constructor Create(CreateSuspended: Boolean;
     88      const StackSize: SizeUInt = DefaultStackSize);
     89    destructor Destroy; override;
    8590  end;
    8691
    8792  TThreadPool = class(TObjectList)
    88 
    8993  end;
    9094
     
    116120    ThreadPool: TThreadPool;
    117121    RoundRobinIndex: Integer;
    118     LastId: Integer;
     122    FLastId: Integer;
    119123    FFrequency: Int64;
    120     FThreadPoolSize: Integer;
    121124    FTerminated: Boolean;
    122125    function GetMicroThreadCount: Integer;
     
    171174        TMicroThread(MicroThreads[I]).FStackSize))) do Inc(I);
    172175      if I < MicroThreads.Count then begin
    173         Result := TMicroThread(MicroThreads[I]).Id;
     176        Result := TMicroThread(MicroThreads[I]).FId;
    174177      end else Result := -1;
    175178    finally
     
    194197var
    195198  I: Integer;
    196   Time: TDateTime;
    197 begin
    198   Time := Scheduler.GetNow;
     199  CurrentTime: TDateTime;
     200begin
     201  CurrentTime := Scheduler.GetNow;
    199202  if Assigned(CurrentMicroThread) then begin
    200     CurrentMicroThread.FExecutionEndTime := Time;
     203    CurrentMicroThread.FExecutionEndTime := CurrentTime;
    201204    CurrentMicroThread.FExecutionTime := CurrentMicroThread.FExecutionTime +
    202205      (CurrentMicroThread.FExecutionEndTime - CurrentMicroThread.FExecutionStartTime);
    203     if CurrentMicroThread.State = tsRunning then
    204       CurrentMicroThread.State := tsWaiting;
     206    if CurrentMicroThread.FState = tsRunning then
     207      CurrentMicroThread.FState := tsWaiting;
    205208    StaticMicroThread := CurrentMicroThread;
    206209    asm
     
    212215      mov [eax].TMicroThread.FBasePointer, edx
    213216    end;
    214     StaticManager := CurrentMicroThread.Manager;
     217    StaticManager := CurrentMicroThread.FManager;
    215218    asm
    216219      // Restore scheduler stack
     
    221224      mov ebp, edx
    222225    end;
    223     CurrentMicroThread.Manager := nil;
     226    CurrentMicroThread.FManager := nil;
    224227    CurrentMicroThread := nil;
    225228  end;
     
    228231
    229232  if Assigned(CurrentMicroThread) and (FExecutedCount < FExecuteCount) then begin
    230     CurrentMicroThread.Manager := Self;
     233    CurrentMicroThread.FManager := Self;
    231234    Inc(FExecutedCount);
    232235    asm
     
    240243    if not CurrentMicroThread.FExecuted then begin
    241244      CurrentMicroThread.FExecuted := True;
    242       CurrentMicroThread.State := tsRunning;
    243       CurrentMicroThread.FExecutionStartTime := Time;
     245      CurrentMicroThread.FState := tsRunning;
     246      CurrentMicroThread.FExecutionStartTime := CurrentTime;
    244247      StaticMicroThread := CurrentMicroThread;
    245248      asm
     
    257260      end;
    258261      //FSelected.Method(FSelected);
    259       StaticManager := CurrentMicroThread.Manager;
     262      StaticManager := CurrentMicroThread.FManager;
    260263      asm
    261264        // Restore scheduler stack
     
    266269        mov ebp, edx
    267270      end;
    268       CurrentMicroThread.Manager := nil;
    269       CurrentMicroThread.FExecutionEndTime := Time;
     271      CurrentMicroThread.FManager := nil;
     272      CurrentMicroThread.FExecutionEndTime := CurrentTime;
    270273      CurrentMicroThread.FExecutionTime := CurrentMicroThread.FExecutionTime +
    271274       (CurrentMicroThread.FExecutionEndTime - CurrentMicroThread.FExecutionStartTime);
     
    285288    if CurrentMicroThread.State = tsWaiting then begin
    286289      // Execute selected thread
    287       CurrentMicroThread.State := tsRunning;
    288       CurrentMicroThread.FExecutionStartTime := Time;
     290      CurrentMicroThread.FState := tsRunning;
     291      CurrentMicroThread.FExecutionStartTime := CurrentTime;
    289292      FTempPointer := CurrentMicroThread.FStackPointer;
    290293      asm
     
    334337end;
    335338
     339constructor TMicroThreadSchedulerPoolThread.Create(CreateSuspended: Boolean;
     340  const StackSize: SizeUInt);
     341begin
     342  inherited;
     343  Manager := TMicroThreadManager.Create;
     344end;
     345
     346destructor TMicroThreadSchedulerPoolThread.Destroy;
     347begin
     348  Manager.Free;
     349  inherited Destroy;
     350end;
     351
    336352{ TMicroThreadMethod }
    337353
     
    352368procedure TMicroThread.Yield;
    353369begin
    354   Manager.Yield;
     370  FManager.Yield;
    355371end;
    356372
     
    365381procedure TMicroThread.Sleep(Duration: TDateTime);
    366382begin
    367   FWakeUpTime := Scheduler.GetNow + Duration;
    368   State := tsSleeping;
     383  FWakeUpTime := FScheduler.GetNow + Duration;
     384  FState := tsSleeping;
    369385  Yield;
    370386end;
     
    387403  FExecutionTime := 0;
    388404  FTerminated := False;
    389   if CreateSuspended then
    390     State := tsSuspended;
     405  if CreateSuspended then begin
     406    FState := tsSuspended;
     407    FSuspended := True;
     408  end else FSuspended := False;
    391409  FFreeOnTerminate := True;
    392410end;
     
    395413begin
    396414  FTerminated := True;
     415end;
     416
     417procedure TMicroThread.Start;
     418begin
     419  FState := tsWaiting;
    397420end;
    398421
     
    405428end;
    406429
    407 procedure TMicroThread.Start;
    408 begin
    409   State := tsWaiting;
    410 end;
    411 
    412 procedure TMicroThread.Stop;
    413 begin
    414   State := tsSuspended;
     430procedure TMicroThread.Resume;
     431begin
     432  FSuspended := False;
     433  if FState = tsSuspended then
     434    FState := tsWaiting;
     435end;
     436
     437procedure TMicroThread.Suspend;
     438begin
     439  FSuspended := True;
     440  //Yield;
    415441end;
    416442
     
    440466function TMicroThreadScheduler.Add(MicroThread: TMicroThread): Integer;
    441467begin
    442   Inc(LastId);
    443   MicroThread.Scheduler := Self;
    444   MicroThread.Id := LastId;
     468  Inc(FLastId);
     469  MicroThread.FScheduler := Self;
     470  MicroThread.FId := FLastId;
    445471  Result := MicroThreads.Add(MicroThread);
    446472end;
     
    452478  NewMicroThread := TMicroThreadMethod.Create(False);
    453479  NewMicroThread.Method := Method;
    454   NewMicroThread.Scheduler := Self;
     480  NewMicroThread.FScheduler := Self;
    455481  Result := Add(NewMicroThread);
    456482end;
     
    482508var
    483509  Executed: Integer;
     510  I: Integer;
    484511begin
    485512  FTerminated := False;
     513  for I := 0 to ThreadPool.Count - 1 do
     514    TMicroThreadSchedulerPoolThread(ThreadPool[I]).Start;
    486515  repeat
    487516    Executed := MainThreadManager.Execute(10);
     
    492521
    493522procedure TMicroThreadScheduler.Stop;
    494 begin
     523var
     524  I: Integer;
     525begin
     526  for I := 0 to ThreadPool.Count - 1 do
     527    TMicroThreadSchedulerPoolThread(ThreadPool[I]).Terminate;
    495528  FTerminated := True;
    496529end;
     
    499532var
    500533  I: Integer;
    501 begin
     534  CurrentTime: TDateTime;
     535begin
     536  CurrentTime := GetNow;
    502537  Result := nil;
    503538  try
     
    510545     (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsWaiting) do begin
    511546      // WakeUp sleeping threads
    512       if (TMicroThread(MicroThreads[RoundRobinIndex]).State = tsSleeping) and
    513         (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < Time) then
    514           TMicroThread(MicroThreads[RoundRobinIndex]).State := tsWaiting else
     547      if (TMicroThread(MicroThreads[RoundRobinIndex]).FState = tsSleeping) and
     548        (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < CurrentTime) then
     549          TMicroThread(MicroThreads[RoundRobinIndex]).FState := tsWaiting else
    515550      begin
    516551        // Go to next thread
     
    541576function TMicroThreadScheduler.GetThreadPoolSize: Integer;
    542577begin
    543   Result := FThreadPoolSize;
     578  Result := ThreadPool.Count;
    544579end;
    545580
    546581procedure TMicroThreadScheduler.SetThreadPoolSize(const AValue: Integer);
    547 begin
    548   FThreadPoolSize := AValue;
     582var
     583  I: Integer;
     584  NewThread: TMicroThreadSchedulerPoolThread;
     585begin
     586  if AValue > ThreadPool.Count then begin
     587    ThreadPool.Capacity := AValue;
     588    while ThreadPool.Count < AValue do begin
     589      NewThread := TMicroThreadSchedulerPoolThread.Create(True);
     590      NewThread.Manager.Scheduler := Self;
     591      ThreadPool.Add(NewThread);
     592    end;
     593  end else
     594  ThreadPool.Count := AValue;
    549595end;
    550596
Note: See TracChangeset for help on using the changeset viewer.