Changeset 134
- Timestamp:
- Jan 23, 2011, 7:25:13 PM (14 years ago)
- Location:
- Microthreading
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
Microthreading/Demo/Demo.lpi
r133 r134 42 42 </Item3> 43 43 </RequiredPackages> 44 <Units Count="2 1">44 <Units Count="22"> 45 45 <Unit0> 46 46 <Filename Value="Demo.lpr"/> 47 47 <IsPartOfProject Value="True"/> 48 48 <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"/> 50 53 </Unit0> 51 54 <Unit1> … … 58 61 <EditorIndex Value="0"/> 59 62 <WindowIndex Value="0"/> 60 <TopLine Value="12 4"/>61 <CursorPos X=" 5" Y="149"/>62 <UsageCount Value="3 1"/>63 <TopLine Value="125"/> 64 <CursorPos X="7" Y="149"/> 65 <UsageCount Value="34"/> 63 66 <Loaded Value="True"/> 64 67 <LoadedDesigner Value="True"/> … … 67 70 <Filename Value="../umicrothreading.pas"/> 68 71 <UnitName Value="UMicroThreading"/> 69 <EditorIndex Value=" 6"/>70 <WindowIndex Value="0"/> 71 <TopLine Value=" 202"/>72 <CursorPos X=" 1" Y="225"/>73 <UsageCount Value="1 6"/>72 <EditorIndex Value="7"/> 73 <WindowIndex Value="0"/> 74 <TopLine Value="146"/> 75 <CursorPos X="9" Y="155"/> 76 <UsageCount Value="17"/> 74 77 <Loaded Value="True"/> 75 78 </Unit2> … … 117 120 <Filename Value="../../ExceptionLogger/UStackTrace.pas"/> 118 121 <UnitName Value="UStackTrace"/> 119 <EditorIndex Value=" 3"/>122 <EditorIndex Value="4"/> 120 123 <WindowIndex Value="0"/> 121 124 <TopLine Value="56"/> 122 125 <CursorPos X="24" Y="77"/> 123 <UsageCount Value="1 6"/>126 <UsageCount Value="17"/> 124 127 <Loaded Value="True"/> 125 128 <DefaultSyntaxHighlighter Value="Delphi"/> … … 128 131 <Filename Value="../../ExceptionLogger/CustomLineInfo.pas"/> 129 132 <UnitName Value="CustomLineInfo"/> 130 <EditorIndex Value=" 5"/>133 <EditorIndex Value="6"/> 131 134 <WindowIndex Value="0"/> 132 135 <TopLine Value="264"/> 133 136 <CursorPos X="37" Y="141"/> 134 <UsageCount Value="1 6"/>137 <UsageCount Value="17"/> 135 138 <Loaded Value="True"/> 136 139 <DefaultSyntaxHighlighter Value="Delphi"/> … … 153 156 <Unit12> 154 157 <Filename Value="/usr/share/fpcsrc/2.4.0/rtl/i386/i386.inc"/> 155 <EditorIndex Value=" 4"/>158 <EditorIndex Value="5"/> 156 159 <WindowIndex Value="0"/> 157 160 <TopLine Value="1046"/> 158 161 <CursorPos X="34" Y="1053"/> 159 <UsageCount Value="1 6"/>162 <UsageCount Value="17"/> 160 163 <Loaded Value="True"/> 161 164 </Unit12> … … 176 179 <Unit15> 177 180 <Filename Value="../../../../lazarus/lcl/include/control.inc"/> 181 <EditorIndex Value="2"/> 178 182 <WindowIndex Value="0"/> 179 183 <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"/> 182 187 </Unit15> 183 188 <Unit16> 184 189 <Filename Value="../Coroutine.pas"/> 185 190 <UnitName Value="Coroutine"/> 186 <EditorIndex Value=" 1"/>187 <WindowIndex Value="0"/> 188 <TopLine Value="2 70"/>191 <EditorIndex Value="3"/> 192 <WindowIndex Value="0"/> 193 <TopLine Value="290"/> 189 194 <CursorPos X="51" Y="287"/> 190 <UsageCount Value="1 6"/>195 <UsageCount Value="17"/> 191 196 <Loaded Value="True"/> 192 197 </Unit16> … … 200 205 <Unit18> 201 206 <Filename Value="/usr/share/fpcsrc/2.4.0/rtl/objpas/classes/classesh.inc"/> 202 <EditorIndex Value="2"/>203 207 <WindowIndex Value="0"/> 204 208 <TopLine Value="1368"/> 205 209 <CursorPos X="3" Y="1385"/> 206 210 <UsageCount Value="11"/> 207 <Loaded Value="True"/>208 211 </Unit18> 209 212 <Unit19> … … 221 224 <UsageCount Value="10"/> 222 225 </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> 223 235 </Units> 224 236 <JumpHistory Count="30" HistoryIndex="29"> 225 237 <Position1> 226 238 <Filename Value="../umicrothreading.pas"/> 227 <Caret Line=" 178" Column="1" TopLine="161"/>239 <Caret Line="250" Column="1" TopLine="222"/> 228 240 </Position1> 229 241 <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"/> 232 244 </Position2> 233 245 <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"/> 236 248 </Position3> 237 249 <Position4> 238 250 <Filename Value="../umicrothreading.pas"/> 239 <Caret Line=" 176" Column="7" TopLine="161"/>251 <Caret Line="82" Column="1" TopLine="65"/> 240 252 </Position4> 241 253 <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"/> 244 256 </Position5> 245 257 <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"/> 248 260 </Position6> 249 261 <Position7> 250 262 <Filename Value="../umicrothreading.pas"/> 251 <Caret Line="2 13" Column="1" TopLine="192"/>263 <Caret Line="240" Column="1" TopLine="223"/> 252 264 </Position7> 253 265 <Position8> 254 266 <Filename Value="../umicrothreading.pas"/> 255 <Caret Line=" 214" Column="1" TopLine="192"/>267 <Caret Line="163" Column="37" TopLine="137"/> 256 268 </Position8> 257 269 <Position9> 258 270 <Filename Value="../umicrothreading.pas"/> 259 <Caret Line=" 216" Column="1" TopLine="192"/>271 <Caret Line="155" Column="9" TopLine="137"/> 260 272 </Position9> 261 273 <Position10> 262 274 <Filename Value="../umicrothreading.pas"/> 263 <Caret Line=" 217" Column="1" TopLine="192"/>275 <Caret Line="162" Column="52" TopLine="137"/> 264 276 </Position10> 265 277 <Position11> 266 278 <Filename Value="../umicrothreading.pas"/> 267 <Caret Line=" 218" Column="1" TopLine="192"/>279 <Caret Line="161" Column="29" TopLine="145"/> 268 280 </Position11> 269 281 <Position12> 270 282 <Filename Value="../umicrothreading.pas"/> 271 <Caret Line=" 221" Column="1" TopLine="193"/>283 <Caret Line="155" Column="14" TopLine="145"/> 272 284 </Position12> 273 285 <Position13> 274 286 <Filename Value="../umicrothreading.pas"/> 275 <Caret Line=" 222" Column="1" TopLine="194"/>287 <Caret Line="143" Column="20" TopLine="135"/> 276 288 </Position13> 277 289 <Position14> 278 290 <Filename Value="../umicrothreading.pas"/> 279 <Caret Line="2 23" Column="1" TopLine="195"/>291 <Caret Line="216" Column="50" TopLine="196"/> 280 292 </Position14> 281 293 <Position15> 282 <Filename Value=" umainform.pas"/>283 <Caret Line="15 0" Column="29" TopLine="124"/>294 <Filename Value="../umicrothreading.pas"/> 295 <Caret Line="158" Column="12" TopLine="144"/> 284 296 </Position15> 285 297 <Position16> 286 298 <Filename Value="../umicrothreading.pas"/> 287 <Caret Line="1 77" Column="15" TopLine="167"/>299 <Caret Line="164" Column="22" TopLine="144"/> 288 300 </Position16> 289 301 <Position17> 290 302 <Filename Value="../umicrothreading.pas"/> 291 <Caret Line=" 209" Column="1" TopLine="210"/>303 <Caret Line="157" Column="12" TopLine="144"/> 292 304 </Position17> 293 305 <Position18> 294 306 <Filename Value="../umicrothreading.pas"/> 295 <Caret Line=" 212" Column="1" TopLine="206"/>307 <Caret Line="164" Column="1" TopLine="144"/> 296 308 </Position18> 297 309 <Position19> 298 310 <Filename Value="../umicrothreading.pas"/> 299 <Caret Line=" 213" Column="1" TopLine="206"/>311 <Caret Line="165" Column="1" TopLine="144"/> 300 312 </Position19> 301 313 <Position20> 302 314 <Filename Value="../umicrothreading.pas"/> 303 <Caret Line=" 214" Column="1" TopLine="206"/>315 <Caret Line="166" Column="1" TopLine="144"/> 304 316 </Position20> 305 317 <Position21> 306 318 <Filename Value="../umicrothreading.pas"/> 307 <Caret Line=" 216" Column="1" TopLine="206"/>319 <Caret Line="167" Column="1" TopLine="144"/> 308 320 </Position21> 309 321 <Position22> 310 322 <Filename Value="../umicrothreading.pas"/> 311 <Caret Line=" 217" Column="1" TopLine="206"/>323 <Caret Line="168" Column="1" TopLine="144"/> 312 324 </Position22> 313 325 <Position23> 314 326 <Filename Value="../umicrothreading.pas"/> 315 <Caret Line=" 218" Column="1" TopLine="206"/>327 <Caret Line="173" Column="1" TopLine="145"/> 316 328 </Position23> 317 329 <Position24> 318 330 <Filename Value="../umicrothreading.pas"/> 319 <Caret Line=" 221" Column="1" TopLine="206"/>331 <Caret Line="174" Column="1" TopLine="146"/> 320 332 </Position24> 321 333 <Position25> 322 334 <Filename Value="../umicrothreading.pas"/> 323 <Caret Line=" 222" Column="1" TopLine="206"/>335 <Caret Line="161" Column="1" TopLine="146"/> 324 336 </Position25> 325 337 <Position26> 326 338 <Filename Value="../umicrothreading.pas"/> 327 <Caret Line=" 223" Column="1" TopLine="206"/>339 <Caret Line="164" Column="1" TopLine="146"/> 328 340 </Position26> 329 341 <Position27> 330 <Filename Value=" umainform.pas"/>331 <Caret Line="1 52" Column="5" TopLine="124"/>342 <Filename Value="../umicrothreading.pas"/> 343 <Caret Line="165" Column="1" TopLine="146"/> 332 344 </Position27> 333 345 <Position28> 334 <Filename Value=" umainform.pas"/>335 <Caret Line="1 49" Column="5" TopLine="124"/>346 <Filename Value="../umicrothreading.pas"/> 347 <Caret Line="166" Column="1" TopLine="146"/> 336 348 </Position28> 337 349 <Position29> 338 350 <Filename Value="../umicrothreading.pas"/> 339 <Caret Line="1 84" Column="1" TopLine="167"/>351 <Caret Line="167" Column="1" TopLine="146"/> 340 352 </Position29> 341 353 <Position30> 342 354 <Filename Value="../umicrothreading.pas"/> 343 <Caret Line=" 209" Column="1" TopLine="202"/>355 <Caret Line="168" Column="1" TopLine="146"/> 344 356 </Position30> 345 357 </JumpHistory> … … 366 378 </CompilerOptions> 367 379 <Debugging> 368 <BreakPoints Count=" 12">380 <BreakPoints Count="6"> 369 381 <Item1> 370 382 <Source Value="../Coroutine.pas"/> … … 376 388 </Item2> 377 389 <Item3> 378 <Source Value=" ../umicrothreading.pas"/>379 <Line Value=" 115"/>390 <Source Value="umainform.pas"/> 391 <Line Value="50"/> 380 392 </Item3> 381 393 <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> 382 402 <Source Value="umainform.pas"/> 383 403 <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"/>392 404 </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>417 405 </BreakPoints> 418 406 <Exceptions Count="3"> -
Microthreading/Demo/umainform.pas
r133 r134 145 145 I: Integer; 146 146 begin 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; 154 155 end; 155 156 -
Microthreading/umicrothreading.pas
r133 r134 30 30 FStack: Pointer; 31 31 FStackSize: Integer; 32 FInstructionPointer: Pointer;33 32 FExecutionStartTime: TDateTime; 34 33 FExecutionEndTime: TDateTime; 34 FStackPointer: Pointer; 35 FBasePointer: Pointer; 35 36 FWakeupTime: TDateTime; 36 procedure Finish;37 procedure SaveContext;38 procedure RestoreContext;39 procedure Init;40 37 public 41 FStackPointer: Pointer;42 38 Id: Integer; 43 39 Name: string; … … 65 61 RoundRobinIndex: Integer; 66 62 LastId: Integer; 67 FStackPointer: Pointer; 63 FMainStackPointer: Pointer; 64 FMainBasePointer: Pointer; 65 FSelected: TMicroThread; 66 FTempPointer: Pointer; 68 67 procedure Yield(MicroThread: TMicroThread); 69 68 public … … 94 93 FStackSize := $10000; 95 94 FStack := GetMem(FStackSize); 96 FStackPointer := FStack + FStackSize; 95 FBasePointer := FStack + FStackSize; 96 FStackPointer := FBasePointer - 20; 97 97 end; 98 98 … … 101 101 FreeMem(FStack); 102 102 inherited Destroy; 103 end;104 105 procedure TMicroThread.SaveContext; assembler; nostackframe;106 asm107 mov eax, Self108 mov edx, esp109 mov [eax].FStackPointer, edx110 pop edx111 mov [eax].FInstructionPointer, edx112 end;113 114 procedure TMicroThread.RestoreContext; assembler; nostackframe;115 asm116 mov eax, Self117 mov edx, [eax].FStackPointer118 mov esp, edx119 mov edx, [eax].FInstructionPointer120 push edx121 ret122 end;123 124 procedure TMicroThread.Init;125 var126 FProc: TCallerAddr;127 begin128 FProc.A := Method;129 FInstructionPointer := FProc.B;130 end;131 132 procedure TMicroThread.Finish;133 begin134 // Microthread is finished, remove it from queue135 try136 Scheduler.Lock.Acquire;137 Scheduler.MicroThreads.Delete(Scheduler.MicroThreads.IndexOf(Self));138 finally139 Scheduler.Lock.Release;140 end;141 103 end; 142 104 … … 154 116 Inc(LastId); 155 117 NewMicroThread.Id := LastId; 156 NewMicroThread.Init;157 118 MicroThreads.Add(NewMicroThread); 158 119 end; … … 175 136 procedure TMicroThreadScheduler.Start; 176 137 begin 138 RoundRobinIndex := -1; 177 139 Yield(nil); 178 140 end; 141 142 var 143 StaticMicroThread: TMicroThread; 144 StaticScheduler: TMicroThreadScheduler; 179 145 180 146 procedure TMicroThreadScheduler.Yield(MicroThread: TMicroThread); … … 184 150 if Assigned(MicroThread) then begin 185 151 MicroThread.FExecutionStartTime := Now; 186 MicroThread.SaveContext;187 152 MicroThread.State := tsSleeping; 188 153 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 189 163 // Restore scheduler stack 190 mov eax, S elf191 mov edx, [eax]. FStackPointer164 mov eax, StaticScheduler // Self is invalid before BP restore 165 mov edx, [eax].TMicroThreadScheduler.FMainStackPointer 192 166 mov esp, edx 167 mov edx, [eax].TMicroThreadScheduler.FMainBasePointer 168 mov ebp, edx 193 169 end; 194 170 end; 195 171 196 172 // Try to find new microthread for execution 173 FSelected := nil; 197 174 try 198 175 Lock.Acquire; 199 176 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 201 182 Inc(I); 183 Inc(RoundRobinIndex); 184 if RoundRobinIndex >= MicroThreads.Count then 185 RoundRobinIndex := 0; 186 end; 202 187 if I < MicroThreads.Count then begin 203 MicroThread := TMicroThread(MicroThreads[I]);188 FSelected := TMicroThread(MicroThreads[RoundRobinIndex]); 204 189 end; 205 190 finally … … 207 192 end; 208 193 209 if Assigned( MicroThread) then begin194 if Assigned(FSelected) then begin 210 195 asm 211 196 // Store scheduler stack 212 197 mov eax, Self 213 198 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; 219 207 asm 220 208 // Restore microthread stack 221 mov eax, MicroThread222 mov edx, [eax]. FStackPointer209 mov eax, Self 210 mov edx, [eax].TMicroThreadScheduler.FTempPointer 223 211 mov esp, edx 224 212 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; 226 223 asm 227 224 // Restore scheduler stack 228 mov eax, S elf229 mov edx, [eax]. FStackPointer225 mov eax, StaticScheduler // Self is invalid before BP restore 226 mov edx, [eax].TMicroThreadScheduler.FMainStackPointer 230 227 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; 231 237 end; 232 238 end else 233 if MicroThread.State = tsSleeping then begin239 if FSelected.State = tsSleeping then begin 234 240 // 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; 238 256 end; 239 257 end;
Note:
See TracChangeset
for help on using the changeset viewer.