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

Legend:

Unmodified
Added
Removed
  • 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.