Ignore:
Timestamp:
Jan 24, 2011, 8:39:52 AM (14 years ago)
Author:
george
Message:
  • Fixed: Execution time measurement.
  • Modified: MicroThread state list changed to virtual list.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • MicroThreading/UMicroThreading.pas

    r137 r140  
    11unit UMicroThreading;
    22
    3 {$mode objfpc}{$H+}
     3{$mode Delphi}{$H+}
    44{$asmmode intel}
    55
     
    77
    88uses
    9   Classes, SysUtils, Contnrs, SyncObjs, DateUtils,
    10   BaseUnix, UnixUtil, Unix;
     9  {$IFDEF Windows}Windows,{$ENDIF}
     10  {$IFDEF Linux}BaseUnix, UnixUtil, Unix,{$ENDIF}
     11  Classes, SysUtils, Contnrs, SyncObjs, DateUtils, Dialogs;
    1112
    1213type
     
    1516
    1617  TStartEvent = procedure(MicroThread: TMicroThread) of object;
    17 
    18   TCallerAddr = packed record
    19     case Boolean of
    20       True: (A: TStartEvent;);
    21       False: (B, C: Pointer;);
    22   end;
    2318
    2419  TMicroThreadState = (tsReady, tsRunning, tsWaiting, tsBlocked, tsSuspended,
     
    6863    FSelected: TMicroThread;
    6964    FTempPointer: Pointer;
     65    FFrequency: Int64;
     66    FExecuteCount: Integer;
     67    FExecutedCount: Integer;
    7068    function GetMicroThreadCount: Integer;
    7169    procedure Yield(MicroThread: TMicroThread);
     
    7371    MicroThreads: TObjectList; // TList<TMicroThread>
    7472    Lock: TCriticalSection;
     73    function GetNow: TDateTime;
    7574    function Add(Name: string; Method: TStartEvent): TMicroThread;
    7675    constructor Create;
    7776    destructor Destroy; override;
    78     procedure Start;
     77    function Execute(Count: Integer): Integer;
    7978    property MicroThreadCount: Integer read GetMicroThreadCount;
    8079    property FreeMicroThreadOnFinish: Boolean read FFreeMicroThreadOnFinish
     
    8988
    9089
    91 function SystemTicks: Int64;
    92 {$IFDEF Windows}
    93 begin
    94   QueryPerformanceCounter(Result);
    95   //Result := Int64(TimeStampToMSecs(DateTimeToTimeStamp(Now)) * 1000) // an alternative Win32 timebase
    96 {$ELSE}
    97 var t : timeval;
    98 begin
    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}
    103 end;
    104 
    105 
    10690{ TMicroThread }
    10791
     
    11397procedure TMicroThread.Sleep(Duration: TDateTime);
    11498begin
    115   FWakeUpTime := Now + Duration;
     99  FWakeUpTime := Scheduler.GetNow + Duration;
    116100  State := tsSleeping;
    117101  Yield;
     
    124108  FBasePointer := FStack + FStackSize;
    125109  FStackPointer := FBasePointer - 20;
     110  FExecutionTime := 0;
    126111end;
    127112
     
    132117end;
    133118
     119
    134120{ TMicroThreadScheduler }
     121
     122function TMicroThreadScheduler.GetNow: TDateTime;
     123var
     124  {$IFDEF Linux}T: TimeVal;{$ENDIF}
     125  {$IFDEF Windows}TimerValue: Int64;{$ENDIF}
     126begin
     127  {$IFDEF Windows}
     128  QueryPerformanceCounter(TimerValue);
     129  //Result := Int64(TimeStampToMSecs(DateTimeToTimeStamp(Now)) * 1000) // an alternative Win32 timebase
     130  Result := TimerValue / FFrequency;
     131  {$ENDIF}
     132  {$IFDEF Linux}
     133  fpgettimeofday(@t, nil);
     134   // Build a 64 bit microsecond tick from the seconds and microsecond longints
     135  Result := (Int64(t.tv_sec) * 1000000) + t.tv_usec;
     136  {$ENDIF}
     137
     138  Result := (Trunc(Now / OneSecond) + Frac(Result)) * OneSecond;
     139end;
    135140
    136141function TMicroThreadScheduler.Add(Name: string; Method: TStartEvent
     
    154159  ThreadPool := TThreadPool.Create;
    155160  FFreeMicroThreadOnFinish := True;
     161  {$IFDEF Windows}
     162  QueryPerformanceFrequency(FFrequency);
     163  {$ENDIF}
     164  RoundRobinIndex := -1;
    156165end;
    157166
     
    164173end;
    165174
    166 procedure TMicroThreadScheduler.Start;
    167 begin
    168   RoundRobinIndex := -1;
     175function TMicroThreadScheduler.Execute(Count: Integer): Integer;
     176begin
     177  FExecuteCount := Count;
     178  FExecutedCount := 0;
    169179  Yield(nil);
     180  Result := FExecutedCount;
    170181end;
    171182
     
    177188var
    178189  I: Integer;
    179 begin
     190  Time: TDateTime;
     191begin
     192  Time := GetNow;
    180193  if Assigned(MicroThread) then begin
    181     MicroThread.FExecutionEndTime := Now;
     194    MicroThread.FExecutionEndTime := Time;
    182195    MicroThread.FExecutionTime := MicroThread.FExecutionTime +
    183196      (MicroThread.FExecutionEndTime - MicroThread.FExecutionStartTime);
     
    215228      // WakeUp sleeping threads
    216229      if (TMicroThread(MicroThreads[RoundRobinIndex]).State = tsSleeping) and
    217         (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < Now) then
     230        (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < Time) then
    218231          TMicroThread(MicroThreads[RoundRobinIndex]).State := tsWaiting else
    219232      begin
     
    232245  end;
    233246
    234   if Assigned(FSelected) then begin
     247  if Assigned(FSelected) and (FExecutedCount < FExecuteCount) then begin
     248    Inc(FExecutedCount);
    235249    asm
    236250      // Store scheduler stack
     
    243257    if FSelected.State = tsReady then begin
    244258      FSelected.State := tsRunning;
    245       FSelected.FExecutionStartTime := Now;
     259      FSelected.FExecutionStartTime := Time;
    246260      FTempPointer := FSelected.FStackPointer;
    247261      asm
     
    269283        mov ebp, edx
    270284      end;
     285      FSelected.FExecutionEndTime := Time;
     286      FSelected.FExecutionTime := FSelected.FExecutionTime +
     287       (FSelected.FExecutionEndTime - FSelected.FExecutionStartTime);
    271288      if FFreeMicroThreadOnFinish then begin
    272289        // Microthread is finished, remove it from queue
     
    282299      // Execute selected thread
    283300      FSelected.State := tsRunning;
    284       FSelected.FExecutionStartTime := Now;
     301      FSelected.FExecutionStartTime := Time;
    285302      FTempPointer := FSelected.FStackPointer;
    286303      asm
Note: See TracChangeset for help on using the changeset viewer.