Changeset 134


Ignore:
Timestamp:
Jan 23, 2011, 7:25:13 PM (14 years ago)
Author:
george
Message:
  • Fixed: Switching micro thread using SP register only was not working. To switch method context BP register have to be switched too.
Location:
Microthreading
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • Microthreading/Demo/Demo.lpi

    r133 r134  
    4242      </Item3>
    4343    </RequiredPackages>
    44     <Units Count="21">
     44    <Units Count="22">
    4545      <Unit0>
    4646        <Filename Value="Demo.lpr"/>
    4747        <IsPartOfProject Value="True"/>
    4848        <UnitName Value="Demo"/>
    49         <UsageCount Value="31"/>
     49        <WindowIndex Value="0"/>
     50        <TopLine Value="1"/>
     51        <CursorPos X="1" Y="15"/>
     52        <UsageCount Value="34"/>
    5053      </Unit0>
    5154      <Unit1>
     
    5861        <EditorIndex Value="0"/>
    5962        <WindowIndex Value="0"/>
    60         <TopLine Value="124"/>
    61         <CursorPos X="5" Y="149"/>
    62         <UsageCount Value="31"/>
     63        <TopLine Value="125"/>
     64        <CursorPos X="7" Y="149"/>
     65        <UsageCount Value="34"/>
    6366        <Loaded Value="True"/>
    6467        <LoadedDesigner Value="True"/>
     
    6770        <Filename Value="../umicrothreading.pas"/>
    6871        <UnitName Value="UMicroThreading"/>
    69         <EditorIndex Value="6"/>
    70         <WindowIndex Value="0"/>
    71         <TopLine Value="202"/>
    72         <CursorPos X="1" Y="225"/>
    73         <UsageCount Value="16"/>
     72        <EditorIndex Value="7"/>
     73        <WindowIndex Value="0"/>
     74        <TopLine Value="146"/>
     75        <CursorPos X="9" Y="155"/>
     76        <UsageCount Value="17"/>
    7477        <Loaded Value="True"/>
    7578      </Unit2>
     
    117120        <Filename Value="../../ExceptionLogger/UStackTrace.pas"/>
    118121        <UnitName Value="UStackTrace"/>
    119         <EditorIndex Value="3"/>
     122        <EditorIndex Value="4"/>
    120123        <WindowIndex Value="0"/>
    121124        <TopLine Value="56"/>
    122125        <CursorPos X="24" Y="77"/>
    123         <UsageCount Value="16"/>
     126        <UsageCount Value="17"/>
    124127        <Loaded Value="True"/>
    125128        <DefaultSyntaxHighlighter Value="Delphi"/>
     
    128131        <Filename Value="../../ExceptionLogger/CustomLineInfo.pas"/>
    129132        <UnitName Value="CustomLineInfo"/>
    130         <EditorIndex Value="5"/>
     133        <EditorIndex Value="6"/>
    131134        <WindowIndex Value="0"/>
    132135        <TopLine Value="264"/>
    133136        <CursorPos X="37" Y="141"/>
    134         <UsageCount Value="16"/>
     137        <UsageCount Value="17"/>
    135138        <Loaded Value="True"/>
    136139        <DefaultSyntaxHighlighter Value="Delphi"/>
     
    153156      <Unit12>
    154157        <Filename Value="/usr/share/fpcsrc/2.4.0/rtl/i386/i386.inc"/>
    155         <EditorIndex Value="4"/>
     158        <EditorIndex Value="5"/>
    156159        <WindowIndex Value="0"/>
    157160        <TopLine Value="1046"/>
    158161        <CursorPos X="34" Y="1053"/>
    159         <UsageCount Value="16"/>
     162        <UsageCount Value="17"/>
    160163        <Loaded Value="True"/>
    161164      </Unit12>
     
    176179      <Unit15>
    177180        <Filename Value="../../../../lazarus/lcl/include/control.inc"/>
     181        <EditorIndex Value="2"/>
    178182        <WindowIndex Value="0"/>
    179183        <TopLine Value="2271"/>
    180         <CursorPos X="30" Y="2293"/>
    181         <UsageCount Value="9"/>
     184        <CursorPos X="4" Y="2274"/>
     185        <UsageCount Value="11"/>
     186        <Loaded Value="True"/>
    182187      </Unit15>
    183188      <Unit16>
    184189        <Filename Value="../Coroutine.pas"/>
    185190        <UnitName Value="Coroutine"/>
    186         <EditorIndex Value="1"/>
    187         <WindowIndex Value="0"/>
    188         <TopLine Value="270"/>
     191        <EditorIndex Value="3"/>
     192        <WindowIndex Value="0"/>
     193        <TopLine Value="290"/>
    189194        <CursorPos X="51" Y="287"/>
    190         <UsageCount Value="16"/>
     195        <UsageCount Value="17"/>
    191196        <Loaded Value="True"/>
    192197      </Unit16>
     
    200205      <Unit18>
    201206        <Filename Value="/usr/share/fpcsrc/2.4.0/rtl/objpas/classes/classesh.inc"/>
    202         <EditorIndex Value="2"/>
    203207        <WindowIndex Value="0"/>
    204208        <TopLine Value="1368"/>
    205209        <CursorPos X="3" Y="1385"/>
    206210        <UsageCount Value="11"/>
    207         <Loaded Value="True"/>
    208211      </Unit18>
    209212      <Unit19>
     
    221224        <UsageCount Value="10"/>
    222225      </Unit20>
     226      <Unit21>
     227        <Filename Value="/usr/share/fpcsrc/2.4.0/rtl/objpas/sysutils/osutilsh.inc"/>
     228        <EditorIndex Value="1"/>
     229        <WindowIndex Value="0"/>
     230        <TopLine Value="8"/>
     231        <CursorPos X="11" Y="25"/>
     232        <UsageCount Value="11"/>
     233        <Loaded Value="True"/>
     234      </Unit21>
    223235    </Units>
    224236    <JumpHistory Count="30" HistoryIndex="29">
    225237      <Position1>
    226238        <Filename Value="../umicrothreading.pas"/>
    227         <Caret Line="178" Column="1" TopLine="161"/>
     239        <Caret Line="250" Column="1" TopLine="222"/>
    228240      </Position1>
    229241      <Position2>
    230         <Filename Value="umainform.pas"/>
    231         <Caret Line="152" Column="3" TopLine="124"/>
     242        <Filename Value="../umicrothreading.pas"/>
     243        <Caret Line="251" Column="1" TopLine="223"/>
    232244      </Position2>
    233245      <Position3>
    234         <Filename Value="umainform.pas"/>
    235         <Caret Line="150" Column="29" TopLine="124"/>
     246        <Filename Value="../umicrothreading.pas"/>
     247        <Caret Line="255" Column="1" TopLine="225"/>
    236248      </Position3>
    237249      <Position4>
    238250        <Filename Value="../umicrothreading.pas"/>
    239         <Caret Line="176" Column="7" TopLine="161"/>
     251        <Caret Line="82" Column="1" TopLine="65"/>
    240252      </Position4>
    241253      <Position5>
    242         <Filename Value="../umicrothreading.pas"/>
    243         <Caret Line="209" Column="1" TopLine="192"/>
     254        <Filename Value="umainform.pas"/>
     255        <Caret Line="150" Column="1" TopLine="125"/>
    244256      </Position5>
    245257      <Position6>
    246         <Filename Value="../umicrothreading.pas"/>
    247         <Caret Line="212" Column="1" TopLine="192"/>
     258        <Filename Value="umainform.pas"/>
     259        <Caret Line="151" Column="1" TopLine="125"/>
    248260      </Position6>
    249261      <Position7>
    250262        <Filename Value="../umicrothreading.pas"/>
    251         <Caret Line="213" Column="1" TopLine="192"/>
     263        <Caret Line="240" Column="1" TopLine="223"/>
    252264      </Position7>
    253265      <Position8>
    254266        <Filename Value="../umicrothreading.pas"/>
    255         <Caret Line="214" Column="1" TopLine="192"/>
     267        <Caret Line="163" Column="37" TopLine="137"/>
    256268      </Position8>
    257269      <Position9>
    258270        <Filename Value="../umicrothreading.pas"/>
    259         <Caret Line="216" Column="1" TopLine="192"/>
     271        <Caret Line="155" Column="9" TopLine="137"/>
    260272      </Position9>
    261273      <Position10>
    262274        <Filename Value="../umicrothreading.pas"/>
    263         <Caret Line="217" Column="1" TopLine="192"/>
     275        <Caret Line="162" Column="52" TopLine="137"/>
    264276      </Position10>
    265277      <Position11>
    266278        <Filename Value="../umicrothreading.pas"/>
    267         <Caret Line="218" Column="1" TopLine="192"/>
     279        <Caret Line="161" Column="29" TopLine="145"/>
    268280      </Position11>
    269281      <Position12>
    270282        <Filename Value="../umicrothreading.pas"/>
    271         <Caret Line="221" Column="1" TopLine="193"/>
     283        <Caret Line="155" Column="14" TopLine="145"/>
    272284      </Position12>
    273285      <Position13>
    274286        <Filename Value="../umicrothreading.pas"/>
    275         <Caret Line="222" Column="1" TopLine="194"/>
     287        <Caret Line="143" Column="20" TopLine="135"/>
    276288      </Position13>
    277289      <Position14>
    278290        <Filename Value="../umicrothreading.pas"/>
    279         <Caret Line="223" Column="1" TopLine="195"/>
     291        <Caret Line="216" Column="50" TopLine="196"/>
    280292      </Position14>
    281293      <Position15>
    282         <Filename Value="umainform.pas"/>
    283         <Caret Line="150" Column="29" TopLine="124"/>
     294        <Filename Value="../umicrothreading.pas"/>
     295        <Caret Line="158" Column="12" TopLine="144"/>
    284296      </Position15>
    285297      <Position16>
    286298        <Filename Value="../umicrothreading.pas"/>
    287         <Caret Line="177" Column="15" TopLine="167"/>
     299        <Caret Line="164" Column="22" TopLine="144"/>
    288300      </Position16>
    289301      <Position17>
    290302        <Filename Value="../umicrothreading.pas"/>
    291         <Caret Line="209" Column="1" TopLine="210"/>
     303        <Caret Line="157" Column="12" TopLine="144"/>
    292304      </Position17>
    293305      <Position18>
    294306        <Filename Value="../umicrothreading.pas"/>
    295         <Caret Line="212" Column="1" TopLine="206"/>
     307        <Caret Line="164" Column="1" TopLine="144"/>
    296308      </Position18>
    297309      <Position19>
    298310        <Filename Value="../umicrothreading.pas"/>
    299         <Caret Line="213" Column="1" TopLine="206"/>
     311        <Caret Line="165" Column="1" TopLine="144"/>
    300312      </Position19>
    301313      <Position20>
    302314        <Filename Value="../umicrothreading.pas"/>
    303         <Caret Line="214" Column="1" TopLine="206"/>
     315        <Caret Line="166" Column="1" TopLine="144"/>
    304316      </Position20>
    305317      <Position21>
    306318        <Filename Value="../umicrothreading.pas"/>
    307         <Caret Line="216" Column="1" TopLine="206"/>
     319        <Caret Line="167" Column="1" TopLine="144"/>
    308320      </Position21>
    309321      <Position22>
    310322        <Filename Value="../umicrothreading.pas"/>
    311         <Caret Line="217" Column="1" TopLine="206"/>
     323        <Caret Line="168" Column="1" TopLine="144"/>
    312324      </Position22>
    313325      <Position23>
    314326        <Filename Value="../umicrothreading.pas"/>
    315         <Caret Line="218" Column="1" TopLine="206"/>
     327        <Caret Line="173" Column="1" TopLine="145"/>
    316328      </Position23>
    317329      <Position24>
    318330        <Filename Value="../umicrothreading.pas"/>
    319         <Caret Line="221" Column="1" TopLine="206"/>
     331        <Caret Line="174" Column="1" TopLine="146"/>
    320332      </Position24>
    321333      <Position25>
    322334        <Filename Value="../umicrothreading.pas"/>
    323         <Caret Line="222" Column="1" TopLine="206"/>
     335        <Caret Line="161" Column="1" TopLine="146"/>
    324336      </Position25>
    325337      <Position26>
    326338        <Filename Value="../umicrothreading.pas"/>
    327         <Caret Line="223" Column="1" TopLine="206"/>
     339        <Caret Line="164" Column="1" TopLine="146"/>
    328340      </Position26>
    329341      <Position27>
    330         <Filename Value="umainform.pas"/>
    331         <Caret Line="152" Column="5" TopLine="124"/>
     342        <Filename Value="../umicrothreading.pas"/>
     343        <Caret Line="165" Column="1" TopLine="146"/>
    332344      </Position27>
    333345      <Position28>
    334         <Filename Value="umainform.pas"/>
    335         <Caret Line="149" Column="5" TopLine="124"/>
     346        <Filename Value="../umicrothreading.pas"/>
     347        <Caret Line="166" Column="1" TopLine="146"/>
    336348      </Position28>
    337349      <Position29>
    338350        <Filename Value="../umicrothreading.pas"/>
    339         <Caret Line="184" Column="1" TopLine="167"/>
     351        <Caret Line="167" Column="1" TopLine="146"/>
    340352      </Position29>
    341353      <Position30>
    342354        <Filename Value="../umicrothreading.pas"/>
    343         <Caret Line="209" Column="1" TopLine="202"/>
     355        <Caret Line="168" Column="1" TopLine="146"/>
    344356      </Position30>
    345357    </JumpHistory>
     
    366378  </CompilerOptions>
    367379  <Debugging>
    368     <BreakPoints Count="12">
     380    <BreakPoints Count="6">
    369381      <Item1>
    370382        <Source Value="../Coroutine.pas"/>
     
    376388      </Item2>
    377389      <Item3>
    378         <Source Value="../umicrothreading.pas"/>
    379         <Line Value="115"/>
     390        <Source Value="umainform.pas"/>
     391        <Line Value="50"/>
    380392      </Item3>
    381393      <Item4>
     394        <Source Value="../Coroutine.pas"/>
     395        <Line Value="257"/>
     396      </Item4>
     397      <Item5>
     398        <Source Value="../Coroutine.pas"/>
     399        <Line Value="145"/>
     400      </Item5>
     401      <Item6>
    382402        <Source Value="umainform.pas"/>
    383403        <Line Value="146"/>
    384       </Item4>
    385       <Item5>
    386         <Source Value="umainform.pas"/>
    387         <Line Value="50"/>
    388       </Item5>
    389       <Item6>
    390         <Source Value="../Coroutine.pas"/>
    391         <Line Value="257"/>
    392404      </Item6>
    393       <Item7>
    394         <Source Value="../Coroutine.pas"/>
    395         <Line Value="145"/>
    396       </Item7>
    397       <Item8>
    398         <Source Value="../umicrothreading.pas"/>
    399         <Line Value="239"/>
    400       </Item8>
    401       <Item9>
    402         <Source Value="../umicrothreading.pas"/>
    403         <Line Value="183"/>
    404       </Item9>
    405       <Item10>
    406         <Source Value="../umicrothreading.pas"/>
    407         <Line Value="209"/>
    408       </Item10>
    409       <Item11>
    410         <Source Value="../umicrothreading.pas"/>
    411         <Line Value="225"/>
    412       </Item11>
    413       <Item12>
    414         <Source Value="umainform.pas"/>
    415         <Line Value="154"/>
    416       </Item12>
    417405    </BreakPoints>
    418406    <Exceptions Count="3">
  • Microthreading/Demo/umainform.pas

    r133 r134  
    145145  I: Integer;
    146146begin
    147   //Memo1.Lines.Add('Work');
    148   //with MicroThread do
    149   //for I := 0 to 100 do begin
    150   //  Memo1.Lines.Add(InttoStr(Id) + ': ' + IntToStr(I));
    151     //Sleep(10);
    152   //  Yield;
    153   //end;
     147  with MicroThread do begin
     148    Memo1.Lines.Add('Worker ' + IntToStr(Id));
     149    for I := 0 to 10 do begin
     150      Memo1.Lines.Add(InttoStr(Id) + ': ' + IntToStr(I));
     151      SysUtils.Sleep(10 * Id);
     152      Yield;
     153    end;
     154  end;
    154155end;
    155156
  • Microthreading/umicrothreading.pas

    r133 r134  
    3030    FStack: Pointer;
    3131    FStackSize: Integer;
    32     FInstructionPointer: Pointer;
    3332    FExecutionStartTime: TDateTime;
    3433    FExecutionEndTime: TDateTime;
     34    FStackPointer: Pointer;
     35    FBasePointer: Pointer;
    3536    FWakeupTime: TDateTime;
    36     procedure Finish;
    37     procedure SaveContext;
    38     procedure RestoreContext;
    39     procedure Init;
    4037  public
    41     FStackPointer: Pointer;
    4238    Id: Integer;
    4339    Name: string;
     
    6561    RoundRobinIndex: Integer;
    6662    LastId: Integer;
    67     FStackPointer: Pointer;
     63    FMainStackPointer: Pointer;
     64    FMainBasePointer: Pointer;
     65    FSelected: TMicroThread;
     66    FTempPointer: Pointer;
    6867    procedure Yield(MicroThread: TMicroThread);
    6968  public
     
    9493  FStackSize := $10000;
    9594  FStack := GetMem(FStackSize);
    96   FStackPointer := FStack + FStackSize;
     95  FBasePointer := FStack + FStackSize;
     96  FStackPointer := FBasePointer - 20;
    9797end;
    9898
     
    101101  FreeMem(FStack);
    102102  inherited Destroy;
    103 end;
    104 
    105 procedure TMicroThread.SaveContext; assembler; nostackframe;
    106 asm
    107   mov eax, Self
    108   mov edx, esp
    109   mov [eax].FStackPointer, edx
    110   pop edx
    111   mov [eax].FInstructionPointer, edx
    112 end;
    113 
    114 procedure TMicroThread.RestoreContext; assembler; nostackframe;
    115 asm
    116   mov eax, Self
    117   mov edx, [eax].FStackPointer
    118   mov esp, edx
    119   mov edx, [eax].FInstructionPointer
    120   push edx
    121   ret
    122 end;
    123 
    124 procedure TMicroThread.Init;
    125 var
    126   FProc: TCallerAddr;
    127 begin
    128   FProc.A := Method;
    129   FInstructionPointer := FProc.B;
    130 end;
    131 
    132 procedure TMicroThread.Finish;
    133 begin
    134   // Microthread is finished, remove it from queue
    135   try
    136     Scheduler.Lock.Acquire;
    137     Scheduler.MicroThreads.Delete(Scheduler.MicroThreads.IndexOf(Self));
    138   finally
    139     Scheduler.Lock.Release;
    140   end;
    141103end;
    142104
     
    154116  Inc(LastId);
    155117  NewMicroThread.Id := LastId;
    156   NewMicroThread.Init;
    157118  MicroThreads.Add(NewMicroThread);
    158119end;
     
    175136procedure TMicroThreadScheduler.Start;
    176137begin
     138  RoundRobinIndex := -1;
    177139  Yield(nil);
    178140end;
     141
     142var
     143  StaticMicroThread: TMicroThread;
     144  StaticScheduler: TMicroThreadScheduler;
    179145
    180146procedure TMicroThreadScheduler.Yield(MicroThread: TMicroThread);
     
    184150  if Assigned(MicroThread) then begin
    185151    MicroThread.FExecutionStartTime := Now;
    186     MicroThread.SaveContext;
    187152    MicroThread.State := tsSleeping;
    188153    asm
     154      // Store microthread stack
     155      mov eax, MicroThread
     156      mov edx, esp
     157      mov [eax].TMicroThread.FStackPointer, edx
     158      mov edx, ebp
     159      mov [eax].TMicroThread.FBasePointer, edx
     160    end;
     161    StaticScheduler := MicroThread.Scheduler;
     162    asm
    189163      // Restore scheduler stack
    190       mov eax, Self
    191       mov edx, [eax].FStackPointer
     164      mov eax, StaticScheduler  // Self is invalid before BP restore
     165      mov edx, [eax].TMicroThreadScheduler.FMainStackPointer
    192166      mov esp, edx
     167      mov edx, [eax].TMicroThreadScheduler.FMainBasePointer
     168      mov ebp, edx
    193169    end;
    194170  end;
    195171
    196172  // Try to find new microthread for execution
     173  FSelected := nil;
    197174  try
    198175    Lock.Acquire;
    199176    I := 0;
    200     while (I < MicroThreads.Count) and (TMicroThread(MicroThreads[I]).State <> tsReady) do
     177    Inc(RoundRobinIndex);
     178    if RoundRobinIndex >= MicroThreads.Count then
     179      RoundRobinIndex := 0;
     180    while (I < MicroThreads.Count) and (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsReady) and
     181(TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsSleeping) do begin
    201182      Inc(I);
     183      Inc(RoundRobinIndex);
     184      if RoundRobinIndex >= MicroThreads.Count then
     185        RoundRobinIndex := 0;
     186    end;
    202187    if I < MicroThreads.Count then begin
    203       MicroThread := TMicroThread(MicroThreads[I]);
     188      FSelected := TMicroThread(MicroThreads[RoundRobinIndex]);
    204189    end;
    205190  finally
     
    207192  end;
    208193
    209   if Assigned(MicroThread) then begin
     194  if Assigned(FSelected) then begin
    210195    asm
    211196      // Store scheduler stack
    212197      mov eax, Self
    213198      mov edx, esp
    214       mov [eax].FStackPointer, edx
    215     end;
    216     if MicroThread.State = tsReady then begin
    217       MicroThread.State := tsRunning;
    218       MicroThread.FExecutionStartTime := Now;
     199      mov [eax].TMicroThreadScheduler.FMainStackPointer, edx
     200      mov edx, ebp
     201      mov [eax].TMicroThreadScheduler.FMainBasePointer, edx
     202    end;
     203    if FSelected.State = tsReady then begin
     204      FSelected.State := tsRunning;
     205      FSelected.FExecutionStartTime := Now;
     206      FTempPointer := FSelected.FStackPointer;
    219207      asm
    220208        // Restore microthread stack
    221         mov eax, MicroThread
    222         mov edx, [eax].FStackPointer
     209        mov eax, Self
     210        mov edx, [eax].TMicroThreadScheduler.FTempPointer
    223211        mov esp, edx
    224212      end;
    225       MicroThread.Method(MicroThread);
     213      StaticMicroThread := FSelected; // BP will be change and Self pointer will be invalid
     214      FTempPointer := FSelected.FBasePointer;
     215      asm
     216        mov eax, Self
     217        mov edx, [eax].TMicroThreadScheduler.FTempPointer
     218        mov ebp, edx
     219      end;
     220      StaticMicroThread.Method(StaticMicroThread);
     221      //FSelected.Method(FSelected);
     222      StaticScheduler := StaticMicroThread.Scheduler;
    226223      asm
    227224        // Restore scheduler stack
    228         mov eax, Self
    229         mov edx, [eax].FStackPointer
     225        mov eax, StaticScheduler // Self is invalid before BP restore
     226        mov edx, [eax].TMicroThreadScheduler.FMainStackPointer
    230227        mov esp, edx
     228        mov edx, [eax].TMicroThreadScheduler.FMainBasePointer
     229        mov ebp, edx
     230      end;
     231      // Microthread is finished, remove it from queue
     232      try
     233        Lock.Acquire;
     234        MicroThreads.Delete(MicroThreads.IndexOf(FSelected));
     235      finally
     236        Lock.Release;
    231237      end;
    232238    end else
    233     if MicroThread.State = tsSleeping then begin
     239    if FSelected.State = tsSleeping then begin
    234240      // Execute selected thread
    235       MicroThread.State := tsRunning;
    236       MicroThread.FExecutionStartTime := Now;
    237       MicroThread.RestoreContext;
     241      FSelected.State := tsRunning;
     242      FSelected.FExecutionStartTime := Now;
     243      FTempPointer := FSelected.FStackPointer;
     244      asm
     245        // Restore microthread stack
     246        mov eax, Self
     247        mov edx, [eax].TMicroThreadScheduler.FTempPointer
     248        mov esp, edx
     249      end;
     250      FTempPointer := FSelected.FBasePointer;
     251      asm
     252        mov eax, Self
     253        mov edx, [eax].TMicroThreadScheduler.FTempPointer
     254        mov ebp, edx
     255      end;
    238256    end;
    239257  end;
Note: See TracChangeset for help on using the changeset viewer.