Ignore:
Timestamp:
Feb 7, 2011, 7:04:23 AM (13 years ago)
Author:
george
Message:
  • Added: Microthread context switching need to change exception stack as well. This need patch thread unit witch is part of system unit to make exception stack thread vars accesible.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • MicroThreading/UMicroThreading.pas

    r160 r161  
    2828  SNilThreadReference = 'Can''t release nil thread.';
    2929  SManagerMicroThreadRunning = 'Manager already have running microthread';
     30  SManagerReferenceLost = 'Reference to manager lost';
     31  SCantDetermineThreadID = 'Can''t determine thread for id %d';
     32  SNotInThread = 'Not in thread';
     33
    3034
    3135type
     
    6973    FStackSize: Integer;
    7074    FBasePointer: Pointer;
     75    FExceptObjectStack: PExceptObject;
     76    FExceptAddrStack: PExceptAddr;
    7177    FExecuted: Boolean; // At first go through Execute method, then switch context
    7278    FBlockState: TMicroThreadBlockState;
     
    146152    FStackPointer: Pointer;
    147153    FBasePointer: Pointer;
     154    FExceptObjectStack: PExceptObject;
     155    FExceptAddrStack: PExceptAddr;
    148156    FExecuteCount: Integer;
    149157    FExecutedCount: Integer;
     
    302310    Thread := TThreadEx.CurrentThread;
    303311    if Assigned(Thread) then TThread.Synchronize(Thread, Method)
    304       else raise Exception.Create('Can''t determine thread for id ' + IntToStr(GetCurrentThreadId));
     312      else raise Exception.Create(Format(SCantDetermineThreadID, [GetCurrentThreadId]));
    305313  end else Method;
    306314end;
     
    312320  MT := GetCurrentMicroThread;
    313321  if Assigned(MT) then Result := MT.WaitForEvent(Event, Duration)
    314     else raise Exception.Create('Not in thread');
     322    else raise Exception.Create(SNotInThread);
    315323//    else Result := Event.WaitFor(Trunc(Duration / OneMillisecond));
    316324end;
     
    428436    FCurrentMicroThread.FExecutionTime := FCurrentMicroThread.FExecutionTime +
    429437      (FCurrentMicroThread.FExecutionEndTime - FCurrentMicroThread.FExecutionStartTime);
     438
     439    FCurrentMicroThread.FExceptObjectStack := GetExceptionObjectStack;
     440    FCurrentMicroThread.FExceptAddrStack := GetExceptionAddrStack;
    430441    asm
    431442      // Store microthread stack
     
    443454      mov ebp, ebx
    444455    end;
     456    SetExceptionObjectStack(FExceptObjectStack);
     457    SetExceptionAddrStack(FExceptAddrStack);
    445458    FCurrentMicroThread.CheckStack;
    446459    FScheduler.ReleaseMicroThread(FCurrentMicroThread);
     
    452465      Inc(FExecutedCount);
    453466      FCurrentMicroThread.FExecutionStartTime := NowPrecise;
     467      FExceptObjectStack := GetExceptionObjectStack;
     468      FExceptAddrStack := GetExceptionAddrStack;
    454469      asm
    455470        // Store manager stack
     
    463478        // First time micro thread execution
    464479        FCurrentMicroThread.FExecuted := True;
     480        SetExceptionObjectStack(FCurrentMicroThread.FExceptObjectStack);
     481        SetExceptionAddrStack(FCurrentMicroThread.FExceptAddrStack);
    465482        asm
    466483          // Restore microthread stack
     
    484501          mov ebp, ebx
    485502        end;
     503        SetExceptionObjectStack(FExceptObjectStack);
     504        SetExceptionAddrStack(FExceptAddrStack);
    486505        FCurrentMicroThread.CheckStack;
    487506        FCurrentMicroThread.FExecutionEndTime := NowPrecise;
    488507        FCurrentMicroThread.FExecutionTime := FCurrentMicroThread.FExecutionTime +
    489          (FCurrentMicroThread.FExecutionEndTime - FCurrentMicroThread.FExecutionStartTime);
     508        (FCurrentMicroThread.FExecutionEndTime - FCurrentMicroThread.FExecutionStartTime);
    490509        FCurrentMicroThread.FStatePending := tsBlocked;
    491510        FCurrentMicroThread.FBlockState := tbsTerminated;
     
    496515            FMicroThreadsLock.Acquire;
    497516            FMicroThreads.Delete(FMicroThreads.IndexOf(FCurrentMicroThread));
     517            FCurrentMicroThread.Manager := nil;
    498518          finally
    499519            FMicroThreadsLock.Release;
     
    509529        // Regular selected microthread execution
    510530        FCurrentMicroThread.CheckStack;
     531        SetExceptionObjectStack(FCurrentMicroThread.FExceptObjectStack);
     532        SetExceptionAddrStack(FCurrentMicroThread.FExceptAddrStack);
    511533        asm
    512534          // Restore microthread stack
     
    635657begin
    636658  if not Assigned(FManager) then
    637     raise Exception.Create('Manager reference lost');
     659    raise Exception.Create(SManagerReferenceLost);
    638660  if FStatePending = tsNone then
    639661    FStatePending := tsWaiting;
     
    879901  Executed: Integer;
    880902begin
    881   Executed := FMainThreadManager.Execute(1);
    882   if Executed = 0 then Sleep(1);
    883   // If not terminated then queue next tick else terminate
    884   if (FState = ssRunning) and FUseMainThread then
    885     Application.QueueAsyncCall(MainThreadTick, 0)
    886     else FMainThreadTerminated := True;
     903//  try
     904    Executed := FMainThreadManager.Execute(1);
     905    if Executed = 0 then Sleep(1);
     906    // If not terminated then queue next tick else terminate
     907    if (FState = ssRunning) and FUseMainThread then
     908      Application.QueueAsyncCall(MainThreadTick, 0)
     909      else FMainThreadTerminated := True;
     910//  except
     911//    FMainThreadTerminated := True;
     912//    raise;
     913//  end;
    887914end;
    888915
Note: See TracChangeset for help on using the changeset viewer.