Ignore:
Timestamp:
Feb 11, 2011, 2:16:17 PM (13 years ago)
Author:
george
Message:
  • Modified: Reducing some spare methods.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • MicroThreading/UMicroThreading.pas

    r168 r169  
    3535  SReleaseNotAcquiredLock = 'Release on not acquired lock';
    3636  SMethodNotAssigned = 'Method for microthread not assigned';
     37  SCriticalSectionDecrement = 'Critical section counter decremented to negative number';
    3738
    3839
     
    117118    procedure Yield;
    118119    procedure MTSleep(Duration: TDateTime); // No conflicting name to global Sleep procedure
    119     procedure WaitForCriticalSection(CriticalSection: TMicroThreadCriticalSection);
    120     function WaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;
    121120    procedure WaitFor;
    122121    procedure Terminate;
     
    236235    BurstCount: Integer;
    237236    function Add(MicroThread: TMicroThread): Integer;
    238     function AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean = False): Integer;
     237    function AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean = True): Integer;
    239238    procedure Remove(MicroThread: TMicroThread; Free: Boolean = True);
    240239    constructor Create;
     
    278277procedure MTSleep(Duration: TDateTime);
    279278procedure MTSynchronize(Method: TThreadMethod);
    280 function MTWaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;
    281279procedure Log(Text: string);
    282280procedure Register;
     
    345343end;
    346344
    347 function MTWaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;
    348 var
    349   MT: TMicroThread;
    350 begin
    351   MT := GetCurrentMicroThread;
    352   if Assigned(MT) then Result := MT.WaitForEvent(Event, Duration)
    353     else raise EMicroThreadError.Create(SNotInMicroThread);
    354 end;
    355 
    356345var
    357346  LogLock: TCriticalSection;
     
    381370begin
    382371  MT := GetCurrentMicroThread;
    383   if Assigned(MT) then MT.WaitForCriticalSection(Self)
    384     else raise EMicroThreadError.Create(SNotInMicroThread);
     372  if Assigned(MT) then
     373  try
     374    MainScheduler.FMicroThreadsLock.Acquire;
     375    Lock.Acquire;
     376    Inc(FCounter);
     377    if FCounter > 1 then begin
     378      FMicroThreads.Add(MT);
     379      MT.FBlockState := tbsCriticalSection;
     380      MT.FStatePending := tsBlocked;
     381      try
     382        Lock.Release;
     383        MainScheduler.FMicroThreadsLock.Release;
     384        MT.Yield;
     385      finally
     386        MainScheduler.FMicroThreadsLock.Acquire;
     387        Lock.Acquire;
     388      end;
     389    end;
     390  finally
     391    Lock.Release;
     392    MainScheduler.FMicroThreadsLock.Release;
     393  end else
     394    raise EMicroThreadError.Create(SNotInMicroThread);
    385395end;
    386396
     
    394404      // Release one waiting micro thread
    395405      TMicroThread(FMicroThreads[0]).FState := tsWaiting;
     406      TMicroThread(FMicroThreads[0]).FStatePending := tsNone;
    396407      FMicroThreads.Delete(0);
    397408    end;
     409    if FCounter < 0 then
     410      raise EMicroThreadError.Create(SCriticalSectionDecrement);
    398411  finally
    399412    Lock.Release;
     
    468481begin
    469482  MT := GetCurrentMicroThread;
    470   if Assigned(MT) then Result := MT.WaitForEvent(Self, Duration)
    471     else raise EMicroThreadError.Create(SNotInMicroThread);
     483  if Assigned(MT) then begin
     484    try
     485      FMicroThreadsLock.Acquire;
     486      if Signaled then begin
     487        Result := wrSignaled;
     488        Exit;
     489      end;
     490      FMicroThreads.Add(Self);
     491      MT.FBlockTime := NowPrecise + Duration;
     492      MT.FBlockState := tbsWaitFor;
     493      MT.FStatePending := tsBlocked;
     494    finally
     495      FMicroThreadsLock.Release;
     496    end;
     497    MT.Yield;
     498    if (MT.FBlockTime <> 0) and (MT.FBlockTime < NowPrecise) then
     499      Result := wrTimeout else Result := wrSignaled;
     500
     501    try
     502      FMicroThreadsLock.Acquire;
     503      FMicroThreads.Remove(Self);
     504    finally
     505      FMicroThreadsLock.Release;
     506    end
     507  end else
     508    raise EMicroThreadError.Create(SNotInMicroThread);
    472509end;
    473510
     
    773810    // Called from another microthread
    774811    while not ((FState = tsBlocked) and (FBlockState = tbsTerminated)) do begin
    775       MTSleep(1);
     812      MTSleep(1 * OneMillisecond);
    776813    end;
    777814  end else begin
     
    792829end;
    793830
    794 procedure TMicroThread.WaitForCriticalSection(
    795   CriticalSection: TMicroThreadCriticalSection);
    796 begin
    797   try
    798     FScheduler.FMicroThreadsLock.Acquire;
    799     CriticalSection.Lock.Acquire;
    800     Inc(CriticalSection.FCounter);
    801     if CriticalSection.FCounter > 1 then begin
    802       CriticalSection.FMicroThreads.Add(Self);
    803       FBlockState := tbsCriticalSection;
    804       FStatePending := tsBlocked;
    805       try
    806         CriticalSection.Lock.Release;
    807         FScheduler.FMicroThreadsLock.Release;
    808         Yield;
    809       finally
    810         FScheduler.FMicroThreadsLock.Acquire;
    811         CriticalSection.Lock.Acquire;
    812       end;
    813     end;
    814   finally
    815     CriticalSection.Lock.Release;
    816     FScheduler.FMicroThreadsLock.Release;
    817   end;
    818 end;
    819 
    820 function TMicroThread.WaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;
    821 begin
    822   try
    823     Event.FMicroThreadsLock.Acquire;
    824     if Event.Signaled then begin
    825       Result := wrSignaled;
    826       Exit;
    827     end;
    828     Event.FMicroThreads.Add(Self);
    829     FBlockTime := NowPrecise + Duration;
    830     FBlockState := tbsWaitFor;
    831     FStatePending := tsBlocked;
    832   finally
    833     Event.FMicroThreadsLock.Release;
    834   end;
    835   Yield;
    836   if (FBlockTime <> 0) and (FBlockTime < NowPrecise) then Result := wrTimeout
    837     else Result := wrSignaled;
    838 
    839   try
    840     Event.FMicroThreadsLock.Acquire;
    841     Event.FMicroThreads.Remove(Self);
    842   finally
    843     Event.FMicroThreadsLock.Release;
    844   end;
    845 end;
    846 
    847831constructor TMicroThread.Create(CreateSuspended: Boolean;
    848832  const StackSize: SizeUInt = DefaultStackSize);
     
    851835  FStackSize := StackSize;
    852836  FStack := GetMem(FStackSize);
    853   FBasePointer := FStack + FStackSize - SizeOf(Pointer);
    854   FStackPointer := FBasePointer - SizeOf(Pointer);
     837  FBasePointer := 0; // FStack + FStackSize - SizeOf(Pointer);
     838  FStackPointer := FStack + FStackSize - 2 * SizeOf(Pointer);
    855839  FillChar(FStackPointer^, 2 * SizeOf(Pointer), 0);
    856840
Note: See TracChangeset for help on using the changeset viewer.