Ignore:
Timestamp:
Jan 25, 2011, 8:51:57 PM (13 years ago)
Author:
george
Message:
  • Modified: Yield method of micro thread manager now does'n accept micro thread as parameter and instead get current running micro thread from own field CurrentMicroThread.
  • Fixed: Calculating high precision time on linux.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • MicroThreading/UMicroThreading.pas

    r144 r145  
    9696    FStackPointer: Pointer;
    9797    FBasePointer: Pointer;
    98     FSelected: TMicroThread;
    9998    FExecuteCount: Integer;
    10099    FExecutedCount: Integer;
     
    105104    Scheduler: TMicroThreadScheduler;
    106105    CurrentMicroThread: TMicroThread;
    107     procedure Yield(MicroThread: TMicroThread);
     106    procedure Yield;
    108107    constructor Create;
    109108    destructor Destroy; override;
     
    154153  StaticMicroThread: TMicroThread;
    155154
    156   function GetMicroThreadId: Integer;
    157   var
    158     I: Integer;
    159     CurrentStack: Pointer;
    160   begin
    161     asm
    162       mov CurrentStack, sp
    163     end;
    164     with MainScheduler do begin
    165       try
    166         Lock.Acquire;
    167         I := 0;
    168         while (I < MicroThreads.Count) and
    169           not ((CurrentStack >= TMicroThread(MicroThreads[I]).FStack) and
    170           (CurrentStack <= (TMicroThread(MicroThreads[I]).FStack +
    171           TMicroThread(MicroThreads[I]).FStackSize))) do Inc(I);
    172         if I < MicroThreads.Count then begin
    173           Result := TMicroThread(MicroThreads[I]).Id;
    174         end else Result := -1;
    175       finally
    176         Lock.Release;
    177       end;
    178     end;
    179   end;
     155function GetMicroThreadId: Integer;
     156var
     157  I: Integer;
     158  CurrentStack: Pointer;
     159begin
     160  asm
     161    mov CurrentStack, sp
     162  end;
     163  with MainScheduler do begin
     164    try
     165      Lock.Acquire;
     166      I := 0;
     167      while (I < MicroThreads.Count) and
     168        not ((CurrentStack >= TMicroThread(MicroThreads[I]).FStack) and
     169        (CurrentStack <= (TMicroThread(MicroThreads[I]).FStack +
     170        TMicroThread(MicroThreads[I]).FStackSize))) do Inc(I);
     171      if I < MicroThreads.Count then begin
     172        Result := TMicroThread(MicroThreads[I]).Id;
     173      end else Result := -1;
     174    finally
     175      Lock.Release;
     176    end;
     177  end;
     178end;
    180179
    181180{ TMicroThreadManager }
     
    187186  FExecuteCount := Count;
    188187  FExecutedCount := 0;
    189   Yield(nil);
     188  Yield;
    190189  Result := FExecutedCount;
    191190end;
    192191
    193 procedure TMicroThreadManager.Yield(MicroThread: TMicroThread);
     192procedure TMicroThreadManager.Yield;
    194193var
    195194  I: Integer;
     
    197196begin
    198197  Time := Scheduler.GetNow;
    199   if Assigned(MicroThread) then begin
    200     MicroThread.Manager := nil;
    201     MicroThread.FExecutionEndTime := Time;
    202     MicroThread.FExecutionTime := MicroThread.FExecutionTime +
    203       (MicroThread.FExecutionEndTime - MicroThread.FExecutionStartTime);
    204     if MicroThread.State = tsRunning then
    205       MicroThread.State := tsWaiting;
     198  if Assigned(CurrentMicroThread) then begin
     199    CurrentMicroThread.FExecutionEndTime := Time;
     200    CurrentMicroThread.FExecutionTime := CurrentMicroThread.FExecutionTime +
     201      (CurrentMicroThread.FExecutionEndTime - CurrentMicroThread.FExecutionStartTime);
     202    if CurrentMicroThread.State = tsRunning then
     203      CurrentMicroThread.State := tsWaiting;
     204    StaticMicroThread := CurrentMicroThread;
    206205    asm
    207206      // Store microthread stack
    208       mov eax, MicroThread
     207      mov eax, StaticMicroThread
    209208      mov edx, esp
    210209      mov [eax].TMicroThread.FStackPointer, edx
     
    212211      mov [eax].TMicroThread.FBasePointer, edx
    213212    end;
    214     StaticManager := MicroThread.Manager;
     213    StaticManager := CurrentMicroThread.Manager;
    215214    asm
    216215      // Restore scheduler stack
     
    221220      mov ebp, edx
    222221    end;
     222    CurrentMicroThread.Manager := nil;
    223223    CurrentMicroThread := nil;
    224224  end;
    225225
    226   FSelected := Scheduler.GetNextMicroThread;
    227 
    228   if Assigned(FSelected) and (FExecutedCount < FExecuteCount) then begin
    229     FSelected.Manager := Self;
     226  CurrentMicroThread := Scheduler.GetNextMicroThread;
     227
     228  if Assigned(CurrentMicroThread) and (FExecutedCount < FExecuteCount) then begin
     229    CurrentMicroThread.Manager := Self;
    230230    Inc(FExecutedCount);
    231     CurrentMicroThread := FSelected;
    232231    asm
    233232      // Store scheduler stack
     
    238237      mov [eax].TMicroThreadManager.FBasePointer, edx
    239238    end;
    240     if not FSelected.FExecuted then begin
    241       FSelected.FExecuted := True;
    242       FSelected.State := tsRunning;
    243       FSelected.FExecutionStartTime := Time;
    244       FTempPointer := FSelected.FStackPointer;
     239    if not CurrentMicroThread.FExecuted then begin
     240      CurrentMicroThread.FExecuted := True;
     241      CurrentMicroThread.State := tsRunning;
     242      CurrentMicroThread.FExecutionStartTime := Time;
     243      StaticMicroThread := CurrentMicroThread;
    245244      asm
    246245        // Restore microthread stack
    247         mov eax, Self
    248         mov edx, [eax].TMicroThreadManager.FTempPointer
     246        mov eax, StaticMicroThread
     247        mov edx, [eax].TMicroThread.FStackPointer
    249248        mov esp, edx
    250       end;
    251       StaticMicroThread := FSelected; // BP will be change and Self pointer will be invalid
    252       FTempPointer := FSelected.FBasePointer;
    253       asm
    254         mov eax, Self
    255         mov edx, [eax].TMicroThreadManager.FTempPointer
     249        mov edx, [eax].TMicroThread.FBasePointer
    256250        mov ebp, edx
    257251      end;
     
    267261        mov ebp, edx
    268262      end;
    269       FSelected.Manager := nil;
    270       FSelected.FExecutionEndTime := Time;
    271       FSelected.FExecutionTime := FSelected.FExecutionTime +
    272        (FSelected.FExecutionEndTime - FSelected.FExecutionStartTime);
    273       FSelected.FFinished := True;
    274       if FSelected.FFreeOnTerminate then begin
    275         FSelected.Free;
    276       end;;
     263      CurrentMicroThread.Manager := nil;
     264      CurrentMicroThread.FExecutionEndTime := Time;
     265      CurrentMicroThread.FExecutionTime := CurrentMicroThread.FExecutionTime +
     266       (CurrentMicroThread.FExecutionEndTime - CurrentMicroThread.FExecutionStartTime);
     267      CurrentMicroThread.FFinished := True;
     268      if CurrentMicroThread.FFreeOnTerminate then begin
     269        CurrentMicroThread.Free;
     270      end;
     271      CurrentMicroThread := nil;
    277272    end else
    278     if FSelected.State = tsWaiting then begin
     273    if CurrentMicroThread.State = tsWaiting then begin
    279274      // Execute selected thread
    280       FSelected.State := tsRunning;
    281       FSelected.FExecutionStartTime := Time;
    282       FTempPointer := FSelected.FStackPointer;
     275      CurrentMicroThread.State := tsRunning;
     276      CurrentMicroThread.FExecutionStartTime := Time;
     277      FTempPointer := CurrentMicroThread.FStackPointer;
    283278      asm
    284279        // Restore microthread stack
     
    287282        mov esp, edx
    288283      end;
    289       FTempPointer := FSelected.FBasePointer;
     284      FTempPointer := CurrentMicroThread.FBasePointer;
    290285      asm
    291286        mov eax, Self
     
    294289      end;
    295290    end;
     291  end else begin
     292    CurrentMicroThread := nil;
    296293  end;
    297294end;
     
    299296constructor TMicroThreadManager.Create;
    300297begin
    301 
     298  CurrentMicroThread := nil;
    302299end;
    303300
     
    343340procedure TMicroThread.Yield;
    344341begin
    345   Manager.Yield(Self);
     342  Manager.Yield;
    346343end;
    347344
     
    430427  fpgettimeofday(@t, nil);
    431428   // Build a 64 bit microsecond tick from the seconds and microsecond longints
    432   Result := (Int64(t.tv_sec) * 1000000) + t.tv_usec;
     429  Result := t.tv_sec + t.tv_usec / 1000000;
    433430  {$ENDIF}
    434431
Note: See TracChangeset for help on using the changeset viewer.