Changeset 135


Ignore:
Timestamp:
Jan 23, 2011, 8:04:49 PM (13 years ago)
Author:
george
Message:
  • Added: Showing MicroThread list.
  • Added: Measuring execution time.
  • Added: Do not free micro thread on finish flag.
Location:
Microthreading
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • Microthreading/Demo/Demo.lpi

    r134 r135  
    5050        <TopLine Value="1"/>
    5151        <CursorPos X="1" Y="15"/>
    52         <UsageCount Value="34"/>
     52        <UsageCount Value="35"/>
    5353      </Unit0>
    5454      <Unit1>
     
    5858        <ResourceBaseClass Value="Form"/>
    5959        <UnitName Value="UMainForm"/>
    60         <IsVisibleTab Value="True"/>
    6160        <EditorIndex Value="0"/>
    6261        <WindowIndex Value="0"/>
    63         <TopLine Value="125"/>
    64         <CursorPos X="7" Y="149"/>
    65         <UsageCount Value="34"/>
     62        <TopLine Value="66"/>
     63        <CursorPos X="1" Y="83"/>
     64        <UsageCount Value="35"/>
    6665        <Loaded Value="True"/>
    6766        <LoadedDesigner Value="True"/>
     
    7069        <Filename Value="../umicrothreading.pas"/>
    7170        <UnitName Value="UMicroThreading"/>
     71        <IsVisibleTab Value="True"/>
    7272        <EditorIndex Value="7"/>
    7373        <WindowIndex Value="0"/>
    74         <TopLine Value="146"/>
    75         <CursorPos X="9" Y="155"/>
    76         <UsageCount Value="17"/>
     74        <TopLine Value="84"/>
     75        <CursorPos X="14" Y="101"/>
     76        <UsageCount Value="18"/>
    7777        <Loaded Value="True"/>
    7878      </Unit2>
     
    124124        <TopLine Value="56"/>
    125125        <CursorPos X="24" Y="77"/>
    126         <UsageCount Value="17"/>
     126        <UsageCount Value="18"/>
    127127        <Loaded Value="True"/>
    128128        <DefaultSyntaxHighlighter Value="Delphi"/>
     
    135135        <TopLine Value="264"/>
    136136        <CursorPos X="37" Y="141"/>
    137         <UsageCount Value="17"/>
     137        <UsageCount Value="18"/>
    138138        <Loaded Value="True"/>
    139139        <DefaultSyntaxHighlighter Value="Delphi"/>
     
    160160        <TopLine Value="1046"/>
    161161        <CursorPos X="34" Y="1053"/>
    162         <UsageCount Value="17"/>
     162        <UsageCount Value="18"/>
    163163        <Loaded Value="True"/>
    164164      </Unit12>
     
    183183        <TopLine Value="2271"/>
    184184        <CursorPos X="4" Y="2274"/>
    185         <UsageCount Value="11"/>
     185        <UsageCount Value="12"/>
    186186        <Loaded Value="True"/>
    187187      </Unit15>
     
    193193        <TopLine Value="290"/>
    194194        <CursorPos X="51" Y="287"/>
    195         <UsageCount Value="17"/>
     195        <UsageCount Value="18"/>
    196196        <Loaded Value="True"/>
    197197      </Unit16>
     
    230230        <TopLine Value="8"/>
    231231        <CursorPos X="11" Y="25"/>
    232         <UsageCount Value="11"/>
     232        <UsageCount Value="12"/>
    233233        <Loaded Value="True"/>
    234234      </Unit21>
     
    237237      <Position1>
    238238        <Filename Value="../umicrothreading.pas"/>
    239         <Caret Line="250" Column="1" TopLine="222"/>
     239        <Caret Line="49" Column="59" TopLine="17"/>
    240240      </Position1>
    241241      <Position2>
    242         <Filename Value="../umicrothreading.pas"/>
    243         <Caret Line="251" Column="1" TopLine="223"/>
     242        <Filename Value="umainform.pas"/>
     243        <Caret Line="166" Column="53" TopLine="75"/>
    244244      </Position2>
    245245      <Position3>
    246         <Filename Value="../umicrothreading.pas"/>
    247         <Caret Line="255" Column="1" TopLine="225"/>
     246        <Filename Value="umainform.pas"/>
     247        <Caret Line="79" Column="1" TopLine="73"/>
    248248      </Position3>
    249249      <Position4>
    250250        <Filename Value="../umicrothreading.pas"/>
    251         <Caret Line="82" Column="1" TopLine="65"/>
     251        <Caret Line="146" Column="1" TopLine="129"/>
    252252      </Position4>
    253253      <Position5>
    254         <Filename Value="umainform.pas"/>
    255         <Caret Line="150" Column="1" TopLine="125"/>
     254        <Filename Value="../umicrothreading.pas"/>
     255        <Caret Line="147" Column="1" TopLine="129"/>
    256256      </Position5>
    257257      <Position6>
    258         <Filename Value="umainform.pas"/>
    259         <Caret Line="151" Column="1" TopLine="125"/>
     258        <Filename Value="../umicrothreading.pas"/>
     259        <Caret Line="158" Column="1" TopLine="140"/>
    260260      </Position6>
    261261      <Position7>
    262262        <Filename Value="../umicrothreading.pas"/>
    263         <Caret Line="240" Column="1" TopLine="223"/>
     263        <Caret Line="184" Column="1" TopLine="177"/>
    264264      </Position7>
    265265      <Position8>
    266266        <Filename Value="../umicrothreading.pas"/>
    267         <Caret Line="163" Column="37" TopLine="137"/>
     267        <Caret Line="185" Column="1" TopLine="177"/>
    268268      </Position8>
    269269      <Position9>
    270270        <Filename Value="../umicrothreading.pas"/>
    271         <Caret Line="155" Column="9" TopLine="137"/>
     271        <Caret Line="186" Column="1" TopLine="177"/>
    272272      </Position9>
    273273      <Position10>
    274274        <Filename Value="../umicrothreading.pas"/>
    275         <Caret Line="162" Column="52" TopLine="137"/>
     275        <Caret Line="187" Column="1" TopLine="177"/>
    276276      </Position10>
    277277      <Position11>
    278278        <Filename Value="../umicrothreading.pas"/>
    279         <Caret Line="161" Column="29" TopLine="145"/>
     279        <Caret Line="188" Column="1" TopLine="177"/>
    280280      </Position11>
    281281      <Position12>
    282282        <Filename Value="../umicrothreading.pas"/>
    283         <Caret Line="155" Column="14" TopLine="145"/>
     283        <Caret Line="189" Column="1" TopLine="177"/>
    284284      </Position12>
    285285      <Position13>
    286286        <Filename Value="../umicrothreading.pas"/>
    287         <Caret Line="143" Column="20" TopLine="135"/>
     287        <Caret Line="192" Column="1" TopLine="177"/>
    288288      </Position13>
    289289      <Position14>
    290290        <Filename Value="../umicrothreading.pas"/>
    291         <Caret Line="216" Column="50" TopLine="196"/>
     291        <Caret Line="205" Column="1" TopLine="177"/>
    292292      </Position14>
    293293      <Position15>
    294294        <Filename Value="../umicrothreading.pas"/>
    295         <Caret Line="158" Column="12" TopLine="144"/>
     295        <Caret Line="206" Column="1" TopLine="178"/>
    296296      </Position15>
    297297      <Position16>
    298298        <Filename Value="../umicrothreading.pas"/>
    299         <Caret Line="164" Column="22" TopLine="144"/>
     299        <Caret Line="209" Column="1" TopLine="181"/>
    300300      </Position16>
    301301      <Position17>
    302302        <Filename Value="../umicrothreading.pas"/>
    303         <Caret Line="157" Column="12" TopLine="144"/>
     303        <Caret Line="212" Column="1" TopLine="184"/>
    304304      </Position17>
    305305      <Position18>
    306306        <Filename Value="../umicrothreading.pas"/>
    307         <Caret Line="164" Column="1" TopLine="144"/>
     307        <Caret Line="215" Column="1" TopLine="197"/>
    308308      </Position18>
    309309      <Position19>
    310310        <Filename Value="../umicrothreading.pas"/>
    311         <Caret Line="165" Column="1" TopLine="144"/>
     311        <Caret Line="216" Column="1" TopLine="197"/>
    312312      </Position19>
    313313      <Position20>
    314314        <Filename Value="../umicrothreading.pas"/>
    315         <Caret Line="166" Column="1" TopLine="144"/>
     315        <Caret Line="217" Column="1" TopLine="197"/>
    316316      </Position20>
    317317      <Position21>
    318318        <Filename Value="../umicrothreading.pas"/>
    319         <Caret Line="167" Column="1" TopLine="144"/>
     319        <Caret Line="218" Column="1" TopLine="197"/>
    320320      </Position21>
    321321      <Position22>
    322322        <Filename Value="../umicrothreading.pas"/>
    323         <Caret Line="168" Column="1" TopLine="144"/>
     323        <Caret Line="219" Column="1" TopLine="197"/>
    324324      </Position22>
    325325      <Position23>
    326326        <Filename Value="../umicrothreading.pas"/>
    327         <Caret Line="173" Column="1" TopLine="145"/>
     327        <Caret Line="221" Column="1" TopLine="197"/>
    328328      </Position23>
    329329      <Position24>
    330330        <Filename Value="../umicrothreading.pas"/>
    331         <Caret Line="174" Column="1" TopLine="146"/>
     331        <Caret Line="257" Column="35" TopLine="236"/>
    332332      </Position24>
    333333      <Position25>
    334334        <Filename Value="../umicrothreading.pas"/>
    335         <Caret Line="161" Column="1" TopLine="146"/>
     335        <Caret Line="80" Column="38" TopLine="55"/>
    336336      </Position25>
    337337      <Position26>
    338         <Filename Value="../umicrothreading.pas"/>
    339         <Caret Line="164" Column="1" TopLine="146"/>
     338        <Filename Value="umainform.pas"/>
     339        <Caret Line="83" Column="31" TopLine="66"/>
    340340      </Position26>
    341341      <Position27>
    342342        <Filename Value="../umicrothreading.pas"/>
    343         <Caret Line="165" Column="1" TopLine="146"/>
     343        <Caret Line="104" Column="1" TopLine="74"/>
    344344      </Position27>
    345345      <Position28>
    346346        <Filename Value="../umicrothreading.pas"/>
    347         <Caret Line="166" Column="1" TopLine="146"/>
     347        <Caret Line="90" Column="28" TopLine="73"/>
    348348      </Position28>
    349349      <Position29>
    350350        <Filename Value="../umicrothreading.pas"/>
    351         <Caret Line="167" Column="1" TopLine="146"/>
     351        <Caret Line="9" Column="70" TopLine="1"/>
    352352      </Position29>
    353353      <Position30>
    354354        <Filename Value="../umicrothreading.pas"/>
    355         <Caret Line="168" Column="1" TopLine="146"/>
     355        <Caret Line="10" Column="27" TopLine="1"/>
    356356      </Position30>
    357357    </JumpHistory>
     
    378378  </CompilerOptions>
    379379  <Debugging>
    380     <BreakPoints Count="6">
     380    <BreakPoints Count="5">
    381381      <Item1>
    382382        <Source Value="../Coroutine.pas"/>
     
    389389      <Item3>
    390390        <Source Value="umainform.pas"/>
    391         <Line Value="50"/>
     391        <Line Value="52"/>
    392392      </Item3>
    393393      <Item4>
     
    399399        <Line Value="145"/>
    400400      </Item5>
    401       <Item6>
    402         <Source Value="umainform.pas"/>
    403         <Line Value="146"/>
    404       </Item6>
    405401    </BreakPoints>
    406402    <Exceptions Count="3">
  • Microthreading/Demo/umainform.lfm

    r133 r135  
    4040      item
    4141        Caption = 'State'
    42         Width = 165
     42        Width = 60
     43      end   
     44      item
     45        Caption = 'Execution time'
     46        Width = 105
    4347      end>
    4448    ReadOnly = True
     
    8185    TabOrder = 4
    8286  end
     87  object Timer1: TTimer
     88    Interval = 100
     89    OnTimer = Timer1Timer
     90    left = 399
     91    top = 87
     92  end
    8393end
  • Microthreading/Demo/umainform.pas

    r134 r135  
    77uses
    88  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
    9   ComCtrls, UMicroThreading, Coroutine;
     9  ComCtrls, ExtCtrls, UMicroThreading, Coroutine, DateUtils;
    1010
    1111type
     
    2626    ListView1: TListView;
    2727    Memo1: TMemo;
     28    Timer1: TTimer;
    2829    procedure Button1Click(Sender: TObject);
    2930    procedure Button2Click(Sender: TObject);
     
    3132    procedure FormCreate(Sender: TObject);
    3233    procedure FormDestroy(Sender: TObject);
     34    procedure Timer1Timer(Sender: TObject);
    3335  private
    3436    procedure Worker(MicroThread: TMicroThread);
     
    6567begin
    6668  Scheduler := TMicroThreadScheduler.Create;
     69  Scheduler.FreeMicroThreadOnFinish := False;
    6770  Test := TTest.Create;
    6871end;
     
    7477  for I := 0 to 1 do
    7578    Scheduler.Add('Worker', Worker);
    76   Scheduler.Start;
     79  repeat
     80    Scheduler.Start;
     81    Application.ProcessMessages;
     82    Sleep(1);
     83  until Scheduler.MicroThreadCount = 0;
    7784end;
    7885
     
    141148end;
    142149
     150procedure TForm1.Timer1Timer(Sender: TObject);
     151var
     152  I: Integer;
     153  NewItem: TListItem;
     154begin
     155  try
     156    ListView1.BeginUpdate;
     157    ListView1.Clear;
     158    Scheduler.Lock.Acquire;
     159    for I := 0 to Scheduler.MicroThreads.Count - 1 do
     160    with TMicroThread(Scheduler.MicroThreads[I]) do begin
     161      NewItem := ListView1.Items.Add;
     162      NewItem.Caption := IntToStr(Id);
     163      NewItem.SubItems.Add(Name);
     164      NewItem.SubItems.Add('');
     165      NewItem.SubItems.Add(IntToStr(Priority));
     166      NewItem.SubItems.Add(MicroThreadStateText[State]);
     167      NewItem.SubItems.Add(FloatToStr(ExecutionTime));
     168    end;
     169  finally
     170    Scheduler.Lock.Release;
     171    ListView1.EndUpdate;
     172  end;
     173end;
     174
    143175procedure TForm1.Worker(MicroThread: TMicroThread);
    144176var
     
    149181    for I := 0 to 10 do begin
    150182      Memo1.Lines.Add(InttoStr(Id) + ': ' + IntToStr(I));
    151       SysUtils.Sleep(10 * Id);
    152       Yield;
     183      Sleep(100 * Id * OneMillisecond);
    153184    end;
    154185  end;
  • Microthreading/umicrothreading.pas

    r134 r135  
    77
    88uses
    9   Classes, SysUtils, Contnrs, SyncObjs;
     9  Classes, SysUtils, Contnrs, SyncObjs, DateUtils,
     10  BaseUnix, UnixUtil, Unix;
    1011
    1112type
     
    2122  end;
    2223
    23   TMicroThreadState = (tsReady, tsRunning, tsSleeping, tsBlocked, tsSuspended);
     24  TMicroThreadState = (tsReady, tsRunning, tsWaiting, tsBlocked, tsSuspended,
     25    tsSleeping, tsFinished);
    2426
    2527  { TMicroThread }
     
    3234    FExecutionStartTime: TDateTime;
    3335    FExecutionEndTime: TDateTime;
     36    FExecutionTime: TDateTime;
    3437    FStackPointer: Pointer;
    3538    FBasePointer: Pointer;
     
    4649    destructor Destroy; override;
    4750    property Method: TStartEvent read FMethod write FMethod;
     51    property ExecutionTime: TDateTime read FExecutionTime;
    4852  end;
    4953
     
    5660  TMicroThreadScheduler = class
    5761  private
     62    FFreeMicroThreadOnFinish: Boolean;
    5863    ThreadPool: TThreadPool;
    59     MicroThreads: TObjectList; // TList<TMicroThread>
    60     Lock: TCriticalSection;
    6164    RoundRobinIndex: Integer;
    6265    LastId: Integer;
     
    6568    FSelected: TMicroThread;
    6669    FTempPointer: Pointer;
     70    function GetMicroThreadCount: Integer;
    6771    procedure Yield(MicroThread: TMicroThread);
    6872  public
     73    MicroThreads: TObjectList; // TList<TMicroThread>
     74    Lock: TCriticalSection;
    6975    function Add(Name: string; Method: TStartEvent): TMicroThread;
    7076    constructor Create;
    7177    destructor Destroy; override;
    7278    procedure Start;
    73   end;
     79    property MicroThreadCount: Integer read GetMicroThreadCount;
     80    property FreeMicroThreadOnFinish: Boolean read FFreeMicroThreadOnFinish
     81      write FFreeMicroThreadOnFinish;
     82  end;
     83
     84const
     85  MicroThreadStateText: array[TMicroThreadState] of string = ('Ready', 'Running',
     86    'Waiting', 'Blocked', 'Suspended', 'Sleeping', 'Finished');
    7487
    7588implementation
    7689
     90
     91function SystemTicks: Int64;
     92{$IFDEF Windows}
     93begin
     94  QueryPerformanceCounter(Result);
     95  //Result := Int64(TimeStampToMSecs(DateTimeToTimeStamp(Now)) * 1000) // an alternative Win32 timebase
     96{$ELSE}
     97var t : timeval;
     98begin
     99  fpgettimeofday(@t,nil);
     100   // Build a 64 bit microsecond tick from the seconds and microsecond longints
     101  Result := (Int64(t.tv_sec) * 1000000) + t.tv_usec;
     102{$ENDIF}
     103end;
     104
     105
    77106{ TMicroThread }
    78107
     
    84113procedure TMicroThread.Sleep(Duration: TDateTime);
    85114begin
    86   FWakeupTime := Now + Duration;
    87   State := tsBlocked;
     115  FWakeUpTime := Now + Duration;
     116  State := tsSleeping;
    88117  Yield;
    89118end;
     
    124153  MicroThreads := TObjectList.Create;
    125154  ThreadPool := TThreadPool.Create;
     155  FFreeMicroThreadOnFinish := True;
    126156end;
    127157
     
    149179begin
    150180  if Assigned(MicroThread) then begin
    151     MicroThread.FExecutionStartTime := Now;
    152     MicroThread.State := tsSleeping;
     181    MicroThread.FExecutionEndTime := Now;
     182    MicroThread.FExecutionTime := MicroThread.FExecutionTime +
     183      (MicroThread.FExecutionEndTime - MicroThread.FExecutionStartTime);
     184    if MicroThread.State = tsRunning then
     185      MicroThread.State := tsWaiting;
    153186    asm
    154187      // Store microthread stack
     
    179212      RoundRobinIndex := 0;
    180213    while (I < MicroThreads.Count) and (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsReady) and
    181 (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsSleeping) do begin
    182       Inc(I);
    183       Inc(RoundRobinIndex);
    184       if RoundRobinIndex >= MicroThreads.Count then
    185         RoundRobinIndex := 0;
     214(TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsWaiting) do begin
     215      // WakeUp sleeping threads
     216      if (TMicroThread(MicroThreads[RoundRobinIndex]).State = tsSleeping) and
     217        (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < Now) then
     218          TMicroThread(MicroThreads[RoundRobinIndex]).State := tsWaiting else
     219      begin
     220        // Go to next thread
     221        Inc(I);
     222        Inc(RoundRobinIndex);
     223        if RoundRobinIndex >= MicroThreads.Count then
     224          RoundRobinIndex := 0;
     225      end;
    186226    end;
    187227    if I < MicroThreads.Count then begin
     
    229269        mov ebp, edx
    230270      end;
    231       // Microthread is finished, remove it from queue
    232       try
    233         Lock.Acquire;
    234         MicroThreads.Delete(MicroThreads.IndexOf(FSelected));
    235       finally
    236         Lock.Release;
    237       end;
     271      if FFreeMicroThreadOnFinish then begin
     272        // Microthread is finished, remove it from queue
     273        try
     274          Lock.Acquire;
     275          MicroThreads.Delete(MicroThreads.IndexOf(FSelected));
     276        finally
     277          Lock.Release;
     278        end;
     279      end else FSelected.State := tsFinished;
    238280    end else
    239     if FSelected.State = tsSleeping then begin
     281    if FSelected.State = tsWaiting then begin
    240282      // Execute selected thread
    241283      FSelected.State := tsRunning;
     
    258300end;
    259301
     302function TMicroThreadScheduler.GetMicroThreadCount: Integer;
     303begin
     304  try
     305    Lock.Acquire;
     306    Result := MicroThreads.Count;
     307  finally
     308    Lock.Release;
     309  end;
     310end;
     311
    260312end.
    261313
Note: See TracChangeset for help on using the changeset viewer.