Changeset 155 for MicroThreading


Ignore:
Timestamp:
Jan 28, 2011, 7:33:14 AM (13 years ago)
Author:
george
Message:
  • Modified: Reworked microthread internal states.
Location:
MicroThreading
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • MicroThreading/Demo/Demo.lpi

    r154 r155  
    4848        <TopLine Value="1"/>
    4949        <CursorPos X="21" Y="18"/>
    50         <UsageCount Value="69"/>
     50        <UsageCount Value="70"/>
    5151        <Loaded Value="True"/>
    5252      </Unit0>
     
    5959        <EditorIndex Value="0"/>
    6060        <WindowIndex Value="0"/>
    61         <TopLine Value="263"/>
    62         <CursorPos X="8" Y="276"/>
    63         <UsageCount Value="69"/>
     61        <TopLine Value="206"/>
     62        <CursorPos X="1" Y="211"/>
     63        <UsageCount Value="70"/>
    6464        <Loaded Value="True"/>
    6565        <LoadedDesigner Value="True"/>
     
    7171        <EditorIndex Value="2"/>
    7272        <WindowIndex Value="0"/>
    73         <TopLine Value="51"/>
    74         <CursorPos X="22" Y="54"/>
     73        <TopLine Value="708"/>
     74        <CursorPos X="24" Y="718"/>
    7575        <UsageCount Value="37"/>
    7676        <Loaded Value="True"/>
     
    543543      <Position1>
    544544        <Filename Value="../UMicroThreading.pas"/>
    545         <Caret Line="250" Column="1" TopLine="228"/>
     545        <Caret Line="718" Column="1" TopLine="701"/>
    546546      </Position1>
    547547      <Position2>
    548548        <Filename Value="../UMicroThreading.pas"/>
    549         <Caret Line="472" Column="1" TopLine="459"/>
     549        <Caret Line="719" Column="1" TopLine="701"/>
    550550      </Position2>
    551551      <Position3>
    552552        <Filename Value="../UMicroThreading.pas"/>
    553         <Caret Line="473" Column="1" TopLine="459"/>
     553        <Caret Line="720" Column="1" TopLine="701"/>
    554554      </Position3>
    555555      <Position4>
    556556        <Filename Value="../UMicroThreading.pas"/>
    557         <Caret Line="474" Column="1" TopLine="459"/>
     557        <Caret Line="718" Column="1" TopLine="701"/>
    558558      </Position4>
    559559      <Position5>
    560560        <Filename Value="../UMicroThreading.pas"/>
    561         <Caret Line="459" Column="1" TopLine="446"/>
     561        <Caret Line="719" Column="1" TopLine="701"/>
    562562      </Position5>
    563563      <Position6>
    564564        <Filename Value="../UMicroThreading.pas"/>
    565         <Caret Line="267" Column="1" TopLine="254"/>
     565        <Caret Line="720" Column="1" TopLine="701"/>
    566566      </Position6>
    567567      <Position7>
    568568        <Filename Value="../UMicroThreading.pas"/>
    569         <Caret Line="268" Column="1" TopLine="254"/>
     569        <Caret Line="718" Column="1" TopLine="701"/>
    570570      </Position7>
    571571      <Position8>
    572         <Filename Value="../UPlatform.pas"/>
    573         <Caret Line="29" Column="1" TopLine="16"/>
     572        <Filename Value="../UMicroThreading.pas"/>
     573        <Caret Line="719" Column="1" TopLine="701"/>
    574574      </Position8>
    575575      <Position9>
    576         <Filename Value="../UPlatform.pas"/>
    577         <Caret Line="31" Column="1" TopLine="16"/>
     576        <Filename Value="../UMicroThreading.pas"/>
     577        <Caret Line="720" Column="1" TopLine="701"/>
    578578      </Position9>
    579579      <Position10>
    580         <Filename Value="../UPlatform.pas"/>
    581         <Caret Line="40" Column="1" TopLine="18"/>
     580        <Filename Value="../UMicroThreading.pas"/>
     581        <Caret Line="670" Column="3" TopLine="664"/>
    582582      </Position10>
    583583      <Position11>
    584         <Filename Value="../UPlatform.pas"/>
    585         <Caret Line="41" Column="1" TopLine="19"/>
     584        <Filename Value="../UMicroThreading.pas"/>
     585        <Caret Line="706" Column="1" TopLine="693"/>
    586586      </Position11>
    587587      <Position12>
    588588        <Filename Value="../UMicroThreading.pas"/>
    589         <Caret Line="269" Column="1" TopLine="254"/>
     589        <Caret Line="771" Column="3" TopLine="767"/>
    590590      </Position12>
    591591      <Position13>
    592592        <Filename Value="../UMicroThreading.pas"/>
    593         <Caret Line="270" Column="1" TopLine="260"/>
     593        <Caret Line="719" Column="12" TopLine="699"/>
    594594      </Position13>
    595595      <Position14>
    596596        <Filename Value="../UMicroThreading.pas"/>
    597         <Caret Line="273" Column="1" TopLine="260"/>
     597        <Caret Line="718" Column="1" TopLine="699"/>
    598598      </Position14>
    599599      <Position15>
    600600        <Filename Value="../UMicroThreading.pas"/>
    601         <Caret Line="274" Column="1" TopLine="260"/>
     601        <Caret Line="719" Column="1" TopLine="699"/>
    602602      </Position15>
    603603      <Position16>
    604604        <Filename Value="../UMicroThreading.pas"/>
    605         <Caret Line="275" Column="1" TopLine="260"/>
     605        <Caret Line="720" Column="1" TopLine="699"/>
    606606      </Position16>
    607607      <Position17>
    608608        <Filename Value="../UMicroThreading.pas"/>
    609         <Caret Line="276" Column="1" TopLine="260"/>
     609        <Caret Line="718" Column="1" TopLine="699"/>
    610610      </Position17>
    611611      <Position18>
    612612        <Filename Value="../UMicroThreading.pas"/>
    613         <Caret Line="277" Column="1" TopLine="260"/>
     613        <Caret Line="719" Column="1" TopLine="699"/>
    614614      </Position18>
    615615      <Position19>
    616616        <Filename Value="../UMicroThreading.pas"/>
    617         <Caret Line="278" Column="1" TopLine="260"/>
     617        <Caret Line="720" Column="1" TopLine="699"/>
    618618      </Position19>
    619619      <Position20>
    620620        <Filename Value="../UMicroThreading.pas"/>
    621         <Caret Line="281" Column="1" TopLine="260"/>
     621        <Caret Line="718" Column="1" TopLine="699"/>
    622622      </Position20>
    623623      <Position21>
    624624        <Filename Value="../UMicroThreading.pas"/>
    625         <Caret Line="282" Column="1" TopLine="260"/>
     625        <Caret Line="719" Column="1" TopLine="699"/>
    626626      </Position21>
    627627      <Position22>
    628628        <Filename Value="../UMicroThreading.pas"/>
    629         <Caret Line="283" Column="1" TopLine="261"/>
     629        <Caret Line="718" Column="1" TopLine="699"/>
    630630      </Position22>
    631631      <Position23>
    632632        <Filename Value="../UMicroThreading.pas"/>
    633         <Caret Line="284" Column="1" TopLine="262"/>
     633        <Caret Line="719" Column="1" TopLine="699"/>
    634634      </Position23>
    635635      <Position24>
    636636        <Filename Value="../UMicroThreading.pas"/>
    637         <Caret Line="286" Column="1" TopLine="264"/>
     637        <Caret Line="720" Column="1" TopLine="699"/>
    638638      </Position24>
    639639      <Position25>
    640         <Filename Value="UMainForm.pas"/>
    641         <Caret Line="276" Column="1" TopLine="263"/>
     640        <Filename Value="../UMicroThreading.pas"/>
     641        <Caret Line="718" Column="1" TopLine="699"/>
    642642      </Position25>
    643643      <Position26>
    644644        <Filename Value="../UMicroThreading.pas"/>
    645         <Caret Line="249" Column="1" TopLine="236"/>
     645        <Caret Line="719" Column="1" TopLine="699"/>
    646646      </Position26>
    647647      <Position27>
    648648        <Filename Value="../UMicroThreading.pas"/>
    649         <Caret Line="250" Column="1" TopLine="236"/>
     649        <Caret Line="4" Column="72" TopLine="1"/>
    650650      </Position27>
    651651      <Position28>
    652         <Filename Value="UMainForm.pas"/>
    653         <Caret Line="276" Column="8" TopLine="263"/>
     652        <Filename Value="../UMicroThreading.pas"/>
     653        <Caret Line="166" Column="26" TopLine="144"/>
    654654      </Position28>
    655655      <Position29>
    656656        <Filename Value="../UMicroThreading.pas"/>
    657         <Caret Line="250" Column="29" TopLine="245"/>
     657        <Caret Line="670" Column="24" TopLine="654"/>
    658658      </Position29>
    659659      <Position30>
    660660        <Filename Value="../UMicroThreading.pas"/>
    661         <Caret Line="64" Column="17" TopLine="51"/>
     661        <Caret Line="783" Column="25" TopLine="766"/>
    662662      </Position30>
    663663    </JumpHistory>
  • MicroThreading/Demo/UMainForm.lfm

    r152 r155  
    77  ClientHeight = 533
    88  ClientWidth = 775
    9   OnClose = FormClose
    109  OnCreate = FormCreate
    1110  OnDestroy = FormDestroy
     
    128127          end       
    129128          item
     129            Caption = 'Block state'
     130          end       
     131          item
    130132            Caption = 'Execution time'
    131133            Width = 70
  • MicroThreading/Demo/UMainForm.pas

    r154 r155  
    5555    procedure ButtonClearMicroThreadsClick(Sender: TObject);
    5656    procedure CheckBoxUseMainThreadChange(Sender: TObject);
    57     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    5857    procedure FormCreate(Sender: TObject);
    5958    procedure FormDestroy(Sender: TObject);
     
    208207end;
    209208
    210 procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
     209procedure TMainForm.FormDestroy(Sender: TObject);
    211210begin
    212211  MainScheduler.Active := False;
    213 end;
    214 
    215 procedure TMainForm.FormDestroy(Sender: TObject);
    216 begin
    217   MainScheduler.Free;
    218212end;
    219213
     
    234228      Item.SubItems.Add(IntToStr(Priority));
    235229      Item.SubItems.Add(MicroThreadStateText[State]);
     230      Item.SubItems.Add(MicroThreadBlockStateText[BlockState]);
    236231      Item.SubItems.Add(FloatToStr(ExecutionTime));
    237232      Item.SubItems.Add(IntToStr(Trunc(Completion * 100)) + '%');
  • MicroThreading/UMicroThreading.pas

    r154 r155  
    2828  TMicroThreadManager = class;
    2929
    30   TMicroThreadState = (tsWaiting, tsRunning, tsBlocked, tsSuspended,
    31     tsSleeping);
     30  TMicroThreadState = (tsWaiting, tsRunning, tsBlocked, tsSuspended);
     31  TMicroThreadBlockState = (tbsNone, tbsSleeping, tbsWaitFor, tbsTerminating,
     32    tbsTerminated);
    3233
    3334  { TMicroThreadEvent }
     
    6162    FStackSize: Integer;
    6263    FBasePointer: Pointer;
    63     FWakeUpTime: TDateTime;
    64     FTerminated: Boolean;
    6564    FExecuted: Boolean; // At first go through Execute method, then switch context
    66     FFinished: Boolean;
    67     FSuspended: Boolean;
    68     FBlocked: Boolean;
     65    FBlockState: TMicroThreadBlockState;
     66    FBlockTime: TDateTime;
    6967    FState: TMicroThreadState;
     68    FStatePending: TMicroThreadState;
    7069    FScheduler: TMicroThreadScheduler;
    7170    FManager: TMicroThreadManager;
    7271    FId: Integer;
    73     FBlockCondition: Boolean;
    7472    procedure CallExecute;
    7573    function GetStackUsed: Integer;
     74    function GetTerminated: Boolean;
    7675    procedure SetScheduler(const AValue: TMicroThreadScheduler);
    7776  public
     
    9695    property Id: Integer read FId;
    9796    property State: TMicroThreadState read FState;
     97    property BlockState: TMicroThreadBlockState read FBlockState;
    9898    property ExecutionTime: TDateTime read FExecutionTime;
    9999    property FreeOnTerminate: Boolean read FFreeOnTerminate
    100100      write FFreeOnTerminate;
    101     property Terminated: Boolean read FTerminated;
     101    property Terminated: Boolean read GetTerminated;
    102102    property Scheduler: TMicroThreadScheduler read FScheduler
    103103      write SetScheduler;
     
    207207const
    208208  MicroThreadStateText: array[TMicroThreadState] of string = ('Waiting',
    209     'Running', 'Blocked', 'Suspended', 'Sleeping');
     209    'Running', 'Blocked', 'Suspended');
     210  MicroThreadBlockStateText: array[TMicroThreadBlockState] of string = ('None',
     211    'Sleeping', 'WaitFor', 'Terminating', 'Terminated');
    210212
    211213function GetCurrentMicroThread: TMicroThread;
     
    289291begin
    290292  for I := 0 to FMicroThreads.Count - 1 do
    291     TMicroThread(FMicroThreads[I]).FBlockCondition := True;
     293    TMicroThread(FMicroThreads[I]).FStatePending := tsWaiting;
    292294  if not FAutoReset then FSignaled := True;
    293295end;
     
    400402        FCurrentMicroThread.FExecutionTime := FCurrentMicroThread.FExecutionTime +
    401403         (FCurrentMicroThread.FExecutionEndTime - FCurrentMicroThread.FExecutionStartTime);
    402         FCurrentMicroThread.FFinished := True;
     404        FCurrentMicroThread.FState := tsBlocked;
     405        FCurrentMicroThread.FBlockState := tbsTerminated;
    403406        if FCurrentMicroThread.FFreeOnTerminate then begin
    404407          // Microthread is finished, remove it from queue
     
    514517end;
    515518
     519function TMicroThread.GetTerminated: Boolean;
     520begin
     521  Result := (FState = tsBlocked) and (FBlockState = tbsTerminated);
     522end;
     523
    516524procedure TMicroThread.SetScheduler(const AValue: TMicroThreadScheduler);
    517525begin
     
    532540begin
    533541  if GetMicroThreadId <> -1 then
    534   while not FFinished do begin
     542  while not ((FState = tsBlocked) and (FBlockState = tbsTerminated)) do begin
    535543    MTSleep(1);
    536544  end;
     
    539547procedure TMicroThread.MTSleep(Duration: TDateTime);
    540548begin
    541   FWakeUpTime := NowPrecise + Duration;
    542   FState := tsSleeping;
     549  FBlockTime := NowPrecise + Duration;
     550  FBlockState := tbsSleeping;
     551  FStatePending := tsBlocked;
    543552  Yield;
    544553end;
     
    552561    Event.FMicroThreadsLock.Release;
    553562  end;
    554   FBlocked := True;
     563  FBlockTime := NowPrecise + Duration;
     564  FBlockState := tbsWaitFor;
     565  FStatePending := tsBlocked;
    555566  Yield;
    556   repeat
    557     if FState = tsBlocked then MTSleep(1);
    558   until Result <> wrTimeout;
    559567  try
    560568    Event.FMicroThreadsLock.Acquire;
     
    573581  FStackPointer := FBasePointer - SizeOf(Pointer);
    574582  FExecutionTime := 0;
    575   FTerminated := False;
     583  FState := tsWaiting;
     584  FStatePending := tsWaiting;
    576585  if CreateSuspended then begin
    577586    FState := tsSuspended;
    578     FSuspended := True;
    579   end else FSuspended := False;
     587    FStatePending := tsSuspended;
     588  end;
    580589  FFreeOnTerminate := True;
    581590end;
     
    583592procedure TMicroThread.Terminate;
    584593begin
    585   FTerminated := True;
     594  FBlockState := tbsTerminated;
     595  FStatePending := tsBlocked;
    586596end;
    587597
     
    601611procedure TMicroThread.Resume;
    602612begin
    603   FSuspended := False;
    604613  if FState = tsSuspended then
    605     FState := tsWaiting;
     614    FStatePending := tsWaiting;
    606615end;
    607616
    608617procedure TMicroThread.Suspend;
    609618begin
    610   FSuspended := True;
     619  FStatePending := tsSuspended;
    611620  //Yield;
    612621end;
     
    684693procedure TMicroThreadScheduler.Start;
    685694begin
    686   FMainThreadTerminated := False;
    687695  UpdateThreadPoolSize;
    688696  FState := ssRunning;
     
    761769begin
    762770  FMainThreadStarter.Enabled := False;
     771  FMainThreadTerminated := False;
    763772  repeat
    764773    Executed := FMainThreadManager.Execute(1);
     
    782791    if FRoundRobinIndex >= FMicroThreads.Count then
    783792      FRoundRobinIndex := 0;
    784     while (I < FMicroThreads.Count) and
    785      (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState <> tsWaiting) do begin
    786       // WakeUp sleeping threads
    787       if (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState = tsSleeping) and
    788         (TMicroThread(FMicroThreads[FRoundRobinIndex]).FWakeupTime < CurrentTime) then
    789           TMicroThread(FMicroThreads[FRoundRobinIndex]).FState := tsWaiting
     793    while (I < FMicroThreads.Count) do
     794    with TMicroThread(FMicroThreads[FRoundRobinIndex]) do begin
     795      FState := FStatePending;
     796      if (FState = tsWaiting) then Break
    790797      else
    791       if (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState = tsBlocked) and
    792         (TMicroThread(FMicroThreads[FRoundRobinIndex]).FBlockCondition) then
    793           TMicroThread(FMicroThreads[FRoundRobinIndex]).FState := tsWaiting
    794       else begin
    795         // Go to next thread
    796         Inc(I);
    797         Inc(FRoundRobinIndex);
    798         if FRoundRobinIndex >= FMicroThreads.Count then
    799           FRoundRobinIndex := 0;
     798      if (FState = tsBlocked) then begin
     799        // Wakeup sleeping threads
     800        if (FBlockState = tbsSleeping) and
     801          (FBlockTime < CurrentTime) then begin
     802            FState := tsWaiting;
     803            FBlockState := tbsNone;
     804            Break;
     805          end
     806        else
     807        // Unblock event waiting threads
     808        if (FBlockState = tbsWaitFor) and
     809          (FBlockTime < CurrentTime) then begin
     810            FState := tsWaiting;
     811            FBlockState := tbsNone;
     812            Break;
     813          end;
    800814      end;
     815      // Go to next thread
     816      Inc(I);
     817      Inc(FRoundRobinIndex);
     818      if FRoundRobinIndex >= FMicroThreads.Count then
     819        FRoundRobinIndex := 0;
    801820    end;
    802821    if I < FMicroThreads.Count then begin
    803822      Result := TMicroThread(FMicroThreads[FRoundRobinIndex]);
    804823      Result.FState := tsRunning;
     824      Result.FStatePending := tsWaiting;
    805825    end;
    806826  finally
     
    813833  try
    814834    FMicroThreadsLock.Acquire;
    815     if MicroThread.FState = tsRunning then begin
    816       MicroThread.FState := tsWaiting;
    817     end;
     835    MicroThread.FState := MicroThread.FStatePending;
    818836  finally
    819837    FMicroThreadsLock.Release;
Note: See TracChangeset for help on using the changeset viewer.