Ignore:
Timestamp:
Feb 21, 2011, 2:00:03 PM (14 years ago)
Author:
george
Message:
  • Added: Support for logging critical section lifetime.
  • Fixed: Wrong MicroThread registraction in WaitFor internal list.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • MicroThreading/UMicroThreading.pas

    r169 r170  
    5353  TMicroThreadCriticalSection = class
    5454  private
     55    FId: Integer;
    5556    FMicroThreads: TObjectList;
    56     Lock: TCriticalSection;
     57    //Lock: TCriticalSection;
    5758    FCounter: Integer;
    5859  public
     
    6162    constructor Create;
    6263    destructor Destroy; override;
     64    property Id: Integer read FId;
    6365  end;
    6466
     
    208210    FThreadPoolSize: Integer;
    209211    FRoundRobinIndex: Integer;
    210     FLastId: Integer;
     212    FMicroThreadLastId: Integer;
     213    FCriticalSectionLastId: Integer;
    211214    FMainThreadTerminated: Boolean;
    212215    FMicroThreads: TObjectList; // TList<TMicroThread>
     
    232235    procedure MainThreadStart(Sender: TObject);
    233236    procedure MainThreadTick(Data: PtrInt);
     237    function GetCriticalSectionId: Integer;
    234238  public
    235239    BurstCount: Integer;
    236240    function Add(MicroThread: TMicroThread): Integer;
    237     function AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean = True): Integer;
     241    function AddMethod(Method: TProcedureOfObject;
     242      WaitForFinish: Boolean = True; ThreadName: string = ''): Integer;
    238243    procedure Remove(MicroThread: TMicroThread; Free: Boolean = True);
    239244    constructor Create;
     
    282287const
    283288  LogFileName: string = 'Log.txt';
     289  LogEnabled: Boolean = False;
    284290
    285291implementation
     
    350356  LogFile: TextFile;
    351357begin
     358  if LogEnabled then
    352359  try
    353360    LogLock.Acquire;
     
    373380  try
    374381    MainScheduler.FMicroThreadsLock.Acquire;
    375     Lock.Acquire;
     382    {$IFDEF DebugCriticalSection}
     383    Log('CriticalSection(' + IntToStr(FId) + ') Acquire start, MicroThread: ' + IntToStr(MT.Id) + '(' + MT.Name + ')');
     384    {$ENDIF}
     385    //Lock.Acquire;
    376386    Inc(FCounter);
     387    {$IFDEF DebugCriticalSection}
     388    Log('CriticalSection(' + IntToStr(FId) + ') Acquire Counter: ' + IntToStr(FCounter));
     389    {$ENDIF}
    377390    if FCounter > 1 then begin
    378391      FMicroThreads.Add(MT);
     
    380393      MT.FStatePending := tsBlocked;
    381394      try
    382         Lock.Release;
     395        //Lock.Release;
    383396        MainScheduler.FMicroThreadsLock.Release;
    384397        MT.Yield;
    385398      finally
    386399        MainScheduler.FMicroThreadsLock.Acquire;
    387         Lock.Acquire;
     400        //Lock.Acquire;
    388401      end;
    389402    end;
    390403  finally
    391     Lock.Release;
     404    {$IFDEF DebugCriticalSection}
     405    Log('CriticalSection(' + IntToStr(FId) + ') Acquire end: Id:' + IntToStr(MT.Id) + ' Name:' + MT.Name);
     406    {$ENDIF}
     407    //Lock.Release;
    392408    MainScheduler.FMicroThreadsLock.Release;
    393409  end else
     
    396412
    397413procedure TMicroThreadCriticalSection.Release;
     414var
     415  MT: TMicroThread;
    398416begin
    399417  try
    400418    MainScheduler.FMicroThreadsLock.Acquire;
    401     Lock.Acquire;
     419    {$IFDEF DebugCriticalSection}
     420    MT := GetCurrentMicroThread;
     421    if Assigned(MT) then
     422      Log('CriticalSection(' + IntToStr(FId) + ') Release start: Id:' + IntToStr(MT.Id) + ' Name:' + MT.Name)
     423      else Log('CriticalSection(' + IntToStr(FId) + ') Release start: no microthread');
     424    {$ENDIF}
     425    //Lock.Acquire;
    402426    Dec(FCounter);
     427    {$IFDEF DebugCriticalSection}
     428    Log('CriticalSection(' + IntToStr(FId) + ') Release Counter: ' + IntToStr(FCounter));
     429    {$ENDIF}
    403430    if FMicroThreads.Count > 0 then begin
    404431      // Release one waiting micro thread
     
    410437      raise EMicroThreadError.Create(SCriticalSectionDecrement);
    411438  finally
    412     Lock.Release;
     439    {$IFDEF DebugCriticalSection}
     440    Log('CriticalSection(' + IntToStr(FId) + ') Release end: Id:' + IntToStr(MT.Id) + ' Name:' + MT.Name);
     441    {$ENDIF}
     442    //Lock.Release;
    413443    MainScheduler.FMicroThreadsLock.Release;
    414444  end;
     
    417447constructor TMicroThreadCriticalSection.Create;
    418448begin
    419   Lock := TCriticalSection.Create;
     449  //Lock := TCriticalSection.Create;
    420450  FMicroThreads := TObjectList.Create;
    421451  FMicroThreads.OwnsObjects := False;
     452  FId := MainScheduler.GetCriticalSectionId;
    422453end;
    423454
     
    426457  try
    427458    MainScheduler.FMicroThreadsLock.Acquire;
    428     Lock.Acquire;
     459    //Lock.Acquire;
    429460
    430461    while FMicroThreads.Count > 0 do begin
     
    434465    end;
    435466  finally
    436     Lock.Release;
     467    //Lock.Release;
    437468    MainScheduler.FMicroThreadsLock.Release;
    438469  end;
    439470  FMicroThreads.Free;
    440   Lock.Free;
     471  //Lock.Free;
    441472  inherited Destroy;
    442473end;
     
    488519        Exit;
    489520      end;
    490       FMicroThreads.Add(Self);
     521      FMicroThreads.Add(MT);
    491522      MT.FBlockTime := NowPrecise + Duration;
    492523      MT.FBlockState := tbsWaitFor;
     
    798829procedure TMicroThread.Yield;
    799830begin
    800 //  if not Assigned(FManager) then
    801 //    raise EMicroThreadError.Create(SManagerReferenceLost);
     831  if not Assigned(FManager) then
     832    raise EMicroThreadError.Create(SManagerReferenceLost);
    802833  if FStatePending = tsNone then
    803834    FStatePending := tsWaiting;
     
    896927  try
    897928    FMicroThreadsLock.Acquire;
    898     Inc(FLastId);
     929    Inc(FMicroThreadLastId);
     930    MicroThread.FId := FMicroThreadLastId;
    899931    MicroThread.FScheduler := Self;
    900     MicroThread.FId := FLastId;
    901932    Result := FMicroThreads.Add(MicroThread);
    902933  finally
     
    905936end;
    906937
    907 function TMicroThreadScheduler.AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean): Integer;
     938function TMicroThreadScheduler.AddMethod(Method: TProcedureOfObject;
     939  WaitForFinish: Boolean = True; ThreadName: string = ''): Integer;
    908940var
    909941  NewMicroThread: TMicroThreadSimple;
     
    912944  try
    913945    NewMicroThread := TMicroThreadSimple.Create(True);
     946    NewMicroThread.Name := ThreadName;
    914947    NewMicroThread.Method := Method;
    915948    NewMicroThread.FScheduler := Self;
     
    10831116//  end;
    10841117  FMainThreadOutsideStart := NowPrecise;
     1118end;
     1119
     1120function TMicroThreadScheduler.GetCriticalSectionId: Integer;
     1121begin
     1122  Inc(FCriticalSectionLastId);
     1123  Result := FCriticalSectionLastId;
    10851124end;
    10861125
Note: See TracChangeset for help on using the changeset viewer.