Changeset 148
- Timestamp:
- Jan 26, 2011, 2:16:19 PM (14 years ago)
- Location:
- MicroThreading
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/Demo/Demo.lpi
r147 r148 42 42 </Item3> 43 43 </RequiredPackages> 44 <Units Count="4 6">44 <Units Count="48"> 45 45 <Unit0> 46 46 <Filename Value="Demo.lpr"/> … … 50 50 <TopLine Value="1"/> 51 51 <CursorPos X="1" Y="15"/> 52 <UsageCount Value=" 49"/>52 <UsageCount Value="53"/> 53 53 </Unit0> 54 54 <Unit1> 55 55 <Filename Value="UMainForm.pas"/> 56 56 <IsPartOfProject Value="True"/> 57 <ComponentName Value=" Form1"/>57 <ComponentName Value="MainForm"/> 58 58 <ResourceBaseClass Value="Form"/> 59 59 <UnitName Value="UMainForm"/> 60 60 <EditorIndex Value="0"/> 61 61 <WindowIndex Value="0"/> 62 <TopLine Value=" 82"/>63 <CursorPos X="1 " Y="95"/>64 <UsageCount Value=" 49"/>62 <TopLine Value="70"/> 63 <CursorPos X="18" Y="80"/> 64 <UsageCount Value="53"/> 65 65 <Loaded Value="True"/> 66 66 <LoadedDesigner Value="True"/> … … 69 69 <Filename Value="../UMicroThreading.pas"/> 70 70 <UnitName Value="UMicroThreading"/> 71 <EditorIndex Value="2"/> 72 <WindowIndex Value="0"/> 73 <TopLine Value="500"/> 74 <CursorPos X="1" Y="517"/> 75 <UsageCount Value="27"/> 71 <IsVisibleTab Value="True"/> 72 <EditorIndex Value="4"/> 73 <WindowIndex Value="0"/> 74 <TopLine Value="621"/> 75 <CursorPos X="1" Y="621"/> 76 <UsageCount Value="30"/> 76 77 <Loaded Value="True"/> 77 78 </Unit2> … … 237 238 <Unit24> 238 239 <Filename Value="../../../../Programy/Lazarus/0.9.31_2.4.3/fpc/2.4.3/source/rtl/objpas/sysutils/datih.inc"/> 239 <EditorIndex Value=" 4"/>240 <EditorIndex Value="7"/> 240 241 <WindowIndex Value="0"/> 241 242 <TopLine Value="106"/> 242 243 <CursorPos X="10" Y="119"/> 243 <UsageCount Value="1 6"/>244 <UsageCount Value="19"/> 244 245 <Loaded Value="True"/> 245 246 </Unit24> … … 297 298 <Unit32> 298 299 <Filename Value="../../../../Programy/Lazarus/0.9.31_2.4.3/fpc/2.4.3/source/rtl/objpas/classes/classesh.inc"/> 299 <EditorIndex Value=" 5"/>300 <EditorIndex Value="8"/> 300 301 <WindowIndex Value="0"/> 301 302 <TopLine Value="1504"/> 302 303 <CursorPos X="1" Y="1510"/> 303 <UsageCount Value="1 3"/>304 <UsageCount Value="16"/> 304 305 <Loaded Value="True"/> 305 306 </Unit32> … … 327 328 <Unit36> 328 329 <Filename Value="../../../../Programy/Lazarus/0.9.31_2.4.3/fpc/2.4.3/source/rtl/objpas/classes/classes.inc"/> 329 <EditorIndex Value=" 6"/>330 <EditorIndex Value="9"/> 330 331 <WindowIndex Value="0"/> 331 332 <TopLine Value="109"/> 332 333 <CursorPos X="3" Y="111"/> 333 <UsageCount Value="1 3"/>334 <UsageCount Value="16"/> 334 335 <Loaded Value="True"/> 335 336 </Unit36> 336 337 <Unit37> 337 338 <Filename Value="../../../../Programy/Lazarus/0.9.31_2.4.3/fpc/2.4.3/source/rtl/inc/objpash.inc"/> 339 <EditorIndex Value="1"/> 338 340 <WindowIndex Value="0"/> 339 341 <TopLine Value="181"/> 340 342 <CursorPos X="21" Y="194"/> 341 343 <UsageCount Value="13"/> 344 <Loaded Value="True"/> 342 345 </Unit37> 343 346 <Unit38> … … 385 388 <Unit44> 386 389 <Filename Value="../../../../Programy/Lazarus/0.9.31_2.4.3/lcl/include/spinedit.inc"/> 387 <EditorIndex Value=" 1"/>390 <EditorIndex Value="3"/> 388 391 <WindowIndex Value="0"/> 389 392 <TopLine Value="221"/> 390 393 <CursorPos X="1" Y="235"/> 391 <UsageCount Value="1 0"/>394 <UsageCount Value="13"/> 392 395 <Loaded Value="True"/> 393 396 </Unit44> 394 397 <Unit45> 395 398 <Filename Value="../../../../Programy/Lazarus/0.9.31_2.4.3/lcl/interfaces/win32/win32object.inc"/> 396 <IsVisibleTab Value="True"/> 397 <EditorIndex Value="3"/> 399 <EditorIndex Value="6"/> 398 400 <WindowIndex Value="0"/> 399 401 <TopLine Value="387"/> 400 402 <CursorPos X="1" Y="400"/> 401 <UsageCount Value="1 0"/>403 <UsageCount Value="13"/> 402 404 <Loaded Value="True"/> 403 405 </Unit45> 406 <Unit46> 407 <Filename Value="../../../../Programy/Lazarus/0.9.31_2.4.3/fpc/2.4.3/source/rtl/win/wininc/struct.inc"/> 408 <EditorIndex Value="5"/> 409 <WindowIndex Value="0"/> 410 <TopLine Value="6081"/> 411 <CursorPos X="6" Y="6094"/> 412 <UsageCount Value="13"/> 413 <Loaded Value="True"/> 414 </Unit46> 415 <Unit47> 416 <Filename Value="../../../../Programy/Lazarus/0.9.31_2.4.3/fpc/2.4.3/source/rtl/inc/objpas.inc"/> 417 <EditorIndex Value="2"/> 418 <WindowIndex Value="0"/> 419 <TopLine Value="160"/> 420 <CursorPos X="12" Y="163"/> 421 <UsageCount Value="10"/> 422 <Loaded Value="True"/> 423 </Unit47> 404 424 </Units> 405 425 <JumpHistory Count="30" HistoryIndex="29"> 406 426 <Position1> 407 427 <Filename Value="../UMicroThreading.pas"/> 408 <Caret Line="5 79" Column="1" TopLine="566"/>428 <Caret Line="551" Column="1" TopLine="537"/> 409 429 </Position1> 410 430 <Position2> 411 431 <Filename Value="../UMicroThreading.pas"/> 412 <Caret Line="5 80" Column="1" TopLine="566"/>432 <Caret Line="552" Column="1" TopLine="537"/> 413 433 </Position2> 414 434 <Position3> 415 435 <Filename Value="../UMicroThreading.pas"/> 416 <Caret Line="5 81" Column="1" TopLine="566"/>436 <Caret Line="555" Column="1" TopLine="537"/> 417 437 </Position3> 418 438 <Position4> 419 439 <Filename Value="../UMicroThreading.pas"/> 420 <Caret Line="5 82" Column="1" TopLine="566"/>440 <Caret Line="558" Column="1" TopLine="537"/> 421 441 </Position4> 422 442 <Position5> 423 443 <Filename Value="../UMicroThreading.pas"/> 424 <Caret Line="5 83" Column="1" TopLine="566"/>444 <Caret Line="563" Column="1" TopLine="540"/> 425 445 </Position5> 426 446 <Position6> 427 447 <Filename Value="../UMicroThreading.pas"/> 428 <Caret Line=" 584" Column="1" TopLine="566"/>448 <Caret Line="623" Column="1" TopLine="610"/> 429 449 </Position6> 430 450 <Position7> 431 451 <Filename Value="../UMicroThreading.pas"/> 432 <Caret Line=" 142" Column="26" TopLine="125"/>452 <Caret Line="550" Column="1" TopLine="537"/> 433 453 </Position7> 434 454 <Position8> 435 <Filename Value=" UMainForm.pas"/>436 <Caret Line=" 95" Column="17" TopLine="87"/>455 <Filename Value="../UMicroThreading.pas"/> 456 <Caret Line="551" Column="1" TopLine="537"/> 437 457 </Position8> 438 458 <Position9> 439 459 <Filename Value="../UMicroThreading.pas"/> 440 <Caret Line="5 12" Column="3" TopLine="507"/>460 <Caret Line="552" Column="1" TopLine="537"/> 441 461 </Position9> 442 462 <Position10> 443 <Filename Value=" UMainForm.pas"/>444 <Caret Line=" 95" Column="17" TopLine="87"/>463 <Filename Value="../UMicroThreading.pas"/> 464 <Caret Line="556" Column="1" TopLine="537"/> 445 465 </Position10> 446 466 <Position11> 447 467 <Filename Value="../UMicroThreading.pas"/> 448 <Caret Line="5 13" Column="1" TopLine="507"/>468 <Caret Line="558" Column="1" TopLine="537"/> 449 469 </Position11> 450 470 <Position12> 451 471 <Filename Value="../UMicroThreading.pas"/> 452 <Caret Line="5 14" Column="1" TopLine="507"/>472 <Caret Line="561" Column="1" TopLine="539"/> 453 473 </Position12> 454 474 <Position13> 455 475 <Filename Value="../UMicroThreading.pas"/> 456 <Caret Line=" 327" Column="3" TopLine="323"/>476 <Caret Line="559" Column="3" TopLine="543"/> 457 477 </Position13> 458 478 <Position14> 459 479 <Filename Value="../UMicroThreading.pas"/> 460 <Caret Line="5 13" Column="1" TopLine="500"/>480 <Caret Line="564" Column="1" TopLine="543"/> 461 481 </Position14> 462 482 <Position15> 463 483 <Filename Value="../UMicroThreading.pas"/> 464 <Caret Line="5 14" Column="1" TopLine="500"/>484 <Caret Line="562" Column="1" TopLine="543"/> 465 485 </Position15> 466 486 <Position16> 467 487 <Filename Value="../UMicroThreading.pas"/> 468 <Caret Line="5 16" Column="1" TopLine="500"/>488 <Caret Line="563" Column="1" TopLine="543"/> 469 489 </Position16> 470 490 <Position17> 471 491 <Filename Value="../UMicroThreading.pas"/> 472 <Caret Line="5 17" Column="1" TopLine="500"/>492 <Caret Line="564" Column="1" TopLine="543"/> 473 493 </Position17> 474 494 <Position18> 475 495 <Filename Value="../UMicroThreading.pas"/> 476 <Caret Line=" 328" Column="1" TopLine="315"/>496 <Caret Line="562" Column="1" TopLine="543"/> 477 497 </Position18> 478 498 <Position19> 479 499 <Filename Value="../UMicroThreading.pas"/> 480 <Caret Line=" 330" Column="1" TopLine="315"/>500 <Caret Line="563" Column="1" TopLine="543"/> 481 501 </Position19> 482 502 <Position20> 483 503 <Filename Value="../UMicroThreading.pas"/> 484 <Caret Line=" 331" Column="1" TopLine="315"/>504 <Caret Line="564" Column="1" TopLine="543"/> 485 505 </Position20> 486 506 <Position21> 487 507 <Filename Value="../UMicroThreading.pas"/> 488 <Caret Line=" 332" Column="1" TopLine="315"/>508 <Caret Line="562" Column="1" TopLine="543"/> 489 509 </Position21> 490 510 <Position22> 491 <Filename Value=" UMainForm.pas"/>492 <Caret Line=" 95" Column="17" TopLine="87"/>511 <Filename Value="../UMicroThreading.pas"/> 512 <Caret Line="563" Column="1" TopLine="543"/> 493 513 </Position22> 494 514 <Position23> 495 <Filename Value=" UMainForm.pas"/>496 <Caret Line=" 235" Column="19" TopLine="224"/>515 <Filename Value="../UMicroThreading.pas"/> 516 <Caret Line="564" Column="1" TopLine="543"/> 497 517 </Position23> 498 518 <Position24> 499 519 <Filename Value="../UMicroThreading.pas"/> 500 <Caret Line="5 13" Column="1" TopLine="500"/>520 <Caret Line="562" Column="1" TopLine="543"/> 501 521 </Position24> 502 522 <Position25> 503 <Filename Value=" UMainForm.pas"/>504 <Caret Line=" 244" Column="9" TopLine="224"/>523 <Filename Value="../UMicroThreading.pas"/> 524 <Caret Line="564" Column="1" TopLine="543"/> 505 525 </Position25> 506 526 <Position26> 507 <Filename Value="../ ../../../Programy/Lazarus/0.9.31_2.4.3/lcl/interfaces/win32/win32object.inc"/>508 <Caret Line=" 400" Column="1" TopLine="387"/>527 <Filename Value="../UMicroThreading.pas"/> 528 <Caret Line="141" Column="44" TopLine="127"/> 509 529 </Position26> 510 530 <Position27> 511 531 <Filename Value="../UMicroThreading.pas"/> 512 <Caret Line="5 17" Column="1" TopLine="500"/>532 <Caret Line="580" Column="25" TopLine="568"/> 513 533 </Position27> 514 534 <Position28> 515 <Filename Value=" UMainForm.pas"/>516 <Caret Line=" 95" Column="1" TopLine="82"/>535 <Filename Value="../UMicroThreading.pas"/> 536 <Caret Line="151" Column="27" TopLine="134"/> 517 537 </Position28> 518 538 <Position29> 519 539 <Filename Value="../UMicroThreading.pas"/> 520 <Caret Line=" 517" Column="1" TopLine="500"/>540 <Caret Line="150" Column="47" TopLine="135"/> 521 541 </Position29> 522 542 <Position30> 523 <Filename Value="../ ../../../Programy/Lazarus/0.9.31_2.4.3/lcl/interfaces/win32/win32object.inc"/>524 <Caret Line=" 394" Column="30" TopLine="387"/>543 <Filename Value="../UMicroThreading.pas"/> 544 <Caret Line="118" Column="59" TopLine="112"/> 525 545 </Position30> 526 546 </JumpHistory> … … 535 555 <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 536 556 </SearchPaths> 557 <CodeGeneration> 558 <Checks> 559 <IOChecks Value="True"/> 560 <RangeChecks Value="True"/> 561 <OverflowChecks Value="True"/> 562 <StackChecks Value="True"/> 563 </Checks> 564 <VerifyObjMethodCallValidity Value="True"/> 565 </CodeGeneration> 537 566 <Linking> 567 <Debugging> 568 <UseHeaptrc Value="True"/> 569 </Debugging> 538 570 <Options> 539 571 <Win32> … … 543 575 </Linking> 544 576 <Other> 577 <CompilerMessages> 578 <UseMsgFile Value="True"/> 579 </CompilerMessages> 545 580 <CompilerPath Value="$(CompPath)"/> 546 581 </Other> … … 557 592 </Item2> 558 593 <Item3> 559 <Source Value=" umainform.pas"/>560 <Line Value=" 65"/>594 <Source Value="../Coroutine.pas"/> 595 <Line Value="257"/> 561 596 </Item3> 562 597 <Item4> 563 598 <Source Value="../Coroutine.pas"/> 564 <Line Value=" 257"/>599 <Line Value="145"/> 565 600 </Item4> 566 601 <Item5> 567 <Source Value="../ Coroutine.pas"/>568 <Line Value=" 145"/>602 <Source Value="../UMicroThreading.pas"/> 603 <Line Value="554"/> 569 604 </Item5> 570 605 </BreakPoints> -
MicroThreading/Demo/Demo.lpr
r145 r148 15 15 begin 16 16 Application.Initialize; 17 Application.CreateForm(T Form1, Form1);17 Application.CreateForm(TMainForm, MainForm); 18 18 Application.Run; 19 19 end. -
MicroThreading/Demo/UMainForm.lfm
r147 r148 1 object Form1: TForm12 Left = 2 351 object MainForm: TMainForm 2 Left = 263 3 3 Height = 510 4 Top = 444 Top = 156 5 5 Width = 798 6 6 Caption = 'MicroThreading demo' … … 11 11 OnDestroy = FormDestroy 12 12 LCLVersion = '0.9.31' 13 object Button 1: TButton13 object ButtonSchedulerStartStop: TButton 14 14 Left = 9 15 15 Height = 25 … … 17 17 Width = 103 18 18 Caption = 'Start scheduler' 19 OnClick = Button 1Click19 OnClick = ButtonSchedulerStartStopClick 20 20 TabOrder = 0 21 21 end … … 84 84 TabOrder = 3 85 85 end 86 object Button3: TButton87 Left = 1088 Height = 2589 Top = 20890 Width = 7591 Caption = 'Coroutine'92 OnClick = Button3Click93 TabOrder = 494 end95 86 object Label2: TLabel 96 87 Left = 10 … … 101 92 ParentColor = False 102 93 end 103 object Button 4: TButton94 object ButtonAddWorkers: TButton 104 95 Left = 10 105 96 Height = 25 106 Top = 48107 Width = 88108 Caption = ' Startworkers'109 OnClick = Button 4Click110 TabOrder = 597 Top = 72 98 Width = 104 99 Caption = 'Add workers' 100 OnClick = ButtonAddWorkersClick 101 TabOrder = 4 111 102 end 112 103 object SpinEdit1: TSpinEdit 113 Left = 2 16104 Left = 224 114 105 Height = 21 115 Top = 48116 Width = 82106 Top = 76 107 Width = 74 117 108 MaxValue = 100000 118 109 MinValue = 1 119 TabOrder = 6110 TabOrder = 5 120 111 Value = 200 121 112 end 122 object Button 5: TButton113 object ButtonGetMaxThread: TButton 123 114 Left = 168 124 115 Height = 25 … … 126 117 Width = 131 127 118 Caption = 'Get max TThread count' 128 OnClick = Button5Click 119 OnClick = ButtonGetMaxThreadClick 120 TabOrder = 6 121 end 122 object ButtonShowThreadId: TButton 123 Left = 40 124 Height = 25 125 Top = 160 126 Width = 123 127 Caption = 'Show thread id' 128 OnClick = ButtonShowThreadIdClick 129 129 TabOrder = 7 130 130 end 131 object Button6: TButton132 Left = 88133 Height = 25134 Top = 160135 Width = 75136 Caption = 'Button6'137 OnClick = Button6Click138 TabOrder = 8139 end140 131 object SpinEdit2: TSpinEdit 141 Left = 2 16132 Left = 224 142 133 Height = 21 143 134 Top = 13 144 Width = 82 145 TabOrder = 9 135 Width = 74 136 OnChange = SpinEdit2Change 137 TabOrder = 8 146 138 Value = 1 147 139 end … … 155 147 end 156 148 object Label4: TLabel 157 Left = 1 04149 Left = 120 158 150 Height = 14 159 Top = 48151 Top = 79 160 152 Width = 92 161 153 Caption = 'Microthread count:' 162 154 ParentColor = False 155 end 156 object Label5: TLabel 157 Left = 120 158 Height = 14 159 Top = 40 160 Width = 117 161 Caption = 'Logical processor count:' 162 ParentColor = False 163 end 164 object Label6: TLabel 165 Left = 248 166 Height = 14 167 Top = 40 168 Width = 13 169 Caption = ' ' 170 ParentColor = False 171 end 172 object ButtonClearMicroThreads: TButton 173 Left = 10 174 Height = 25 175 Top = 102 176 Width = 104 177 Caption = 'Clear microthreads' 178 OnClick = ButtonClearMicroThreadsClick 179 TabOrder = 9 163 180 end 164 181 object Timer1: TTimer -
MicroThreading/Demo/UMainForm.pas
r147 r148 11 11 type 12 12 13 { TTest } 14 15 TTest = class(TCoroutine) 16 procedure Execute; override; 17 end; 18 19 { TForm1 } 20 21 TForm1 = class(TForm) 22 Button1: TButton; 13 { TMainForm } 14 15 TMainForm = class(TForm) 16 ButtonSchedulerStartStop: TButton; 23 17 Button2: TButton; 24 Button 3: TButton;25 Button 4: TButton;26 Button 5: TButton;27 Button 6: TButton;18 ButtonAddWorkers: TButton; 19 ButtonGetMaxThread: TButton; 20 ButtonShowThreadId: TButton; 21 ButtonClearMicroThreads: TButton; 28 22 Label1: TLabel; 29 23 Label2: TLabel; 30 24 Label3: TLabel; 31 25 Label4: TLabel; 26 Label5: TLabel; 27 Label6: TLabel; 32 28 ListView1: TListView; 33 29 Memo1: TMemo; … … 35 31 SpinEdit2: TSpinEdit; 36 32 Timer1: TTimer; 37 procedure Button 1Click(Sender: TObject);33 procedure ButtonSchedulerStartStopClick(Sender: TObject); 38 34 procedure Button2Click(Sender: TObject); 39 procedure Button 3Click(Sender: TObject);40 procedure Button 4Click(Sender: TObject);41 procedure Button 5Click(Sender: TObject);42 procedure Button 6Click(Sender: TObject);35 procedure ButtonAddWorkersClick(Sender: TObject); 36 procedure ButtonGetMaxThreadClick(Sender: TObject); 37 procedure ButtonShowThreadIdClick(Sender: TObject); 38 procedure ButtonClearMicroThreadsClick(Sender: TObject); 43 39 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); 44 40 procedure FormCreate(Sender: TObject); 45 41 procedure FormDestroy(Sender: TObject); 46 42 procedure ListView1Data(Sender: TObject; Item: TListItem); 43 procedure SpinEdit2Change(Sender: TObject); 47 44 procedure Timer1Timer(Sender: TObject); 48 45 private … … 50 47 public 51 48 Scheduler: TMicroThreadScheduler; 52 Test: TTest; 53 end; 54 55 var 56 Form1: TForm1; 49 end; 50 51 var 52 MainForm: TMainForm; 57 53 58 54 implementation … … 60 56 { TTest } 61 57 62 procedure TTest.Execute;63 var64 I: Integer;65 begin66 // for I := 0 to 100 do begin67 Form1.Memo1.Lines.Add(IntToStr(I));68 Sleep(10);69 //raise Exception.Create('Test');70 Yield;71 72 // end;73 end;74 75 58 {$R *.lfm} 76 59 77 { T Form1}78 79 procedure T Form1.FormCreate(Sender: TObject);60 { TMainForm } 61 62 procedure TMainForm.FormCreate(Sender: TObject); 80 63 begin 81 64 Scheduler := TMicroThreadScheduler.Create; 82 Test := TTest.Create;83 65 DoubleBuffered := True; 84 66 ListView1.DoubleBuffered := True; 85 end; 86 87 procedure TForm1.Button1Click(Sender: TObject); 88 var 89 I: Integer; 90 begin 91 if Button1.Caption = 'Start scheduler' then begin 92 Button1.Caption := 'Stop scheduler'; 67 Label6.Caption := IntToStr(Scheduler.GetCPUCoreCount); 68 end; 69 70 procedure TMainForm.ButtonSchedulerStartStopClick(Sender: TObject); 71 var 72 I: Integer; 73 begin 74 if ButtonSchedulerStartStop.Caption = 'Start scheduler' then begin 75 ButtonSchedulerStartStop.Caption := 'Stop scheduler'; 93 76 Memo1.Clear; 94 Scheduler.ThreadPoolSize := SpinEdit2.Value; 95 Scheduler.Start; 77 Scheduler.Active := True; 96 78 end else begin 97 Button1.Caption := 'Start scheduler'; 98 Scheduler.Stop; 99 Scheduler.ThreadPoolSize := 0; 100 end; 101 end; 102 103 procedure TForm1.Button2Click(Sender: TObject); 79 ButtonSchedulerStartStop.Caption := 'Start scheduler'; 80 Scheduler.Active := False; 81 end; 82 end; 83 84 procedure TMainForm.Button2Click(Sender: TObject); 104 85 const 105 86 MaxBlock = MaxInt - $f; … … 154 135 end; 155 136 156 procedure TForm1.Button3Click(Sender: TObject); 157 begin 158 Test.Invoke; 159 end; 160 161 procedure TForm1.Button4Click(Sender: TObject); 162 var 163 I: Integer; 164 begin 165 Scheduler.MicroThreads.Clear; 137 procedure TMainForm.ButtonAddWorkersClick(Sender: TObject); 138 var 139 I: Integer; 140 begin 141 //Scheduler.FMicroThreads.Clear; 166 142 for I := 0 to SpinEdit1.Value do 167 143 Scheduler.AddMethod(Worker); 168 144 end; 169 145 170 procedure T Form1.Button5Click(Sender: TObject);146 procedure TMainForm.ButtonGetMaxThreadClick(Sender: TObject); 171 147 var 172 148 NewThread: TThread; … … 185 161 end; 186 162 187 procedure T Form1.Button6Click(Sender: TObject);163 procedure TMainForm.ButtonShowThreadIdClick(Sender: TObject); 188 164 begin 189 165 ShowMessage(IntToStr(GetThreadID)); 190 166 end; 191 167 192 procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); 193 begin 194 Scheduler.Stop; 195 end; 196 197 procedure TForm1.FormDestroy(Sender: TObject); 198 begin 199 Test.Free; 168 procedure TMainForm.ButtonClearMicroThreadsClick(Sender: TObject); 169 begin 170 try 171 Scheduler.MicroThreadsLock.Acquire; 172 Scheduler.MicroThreads.Clear; 173 finally 174 Scheduler.MicroThreadsLock.Release; 175 end; 176 end; 177 178 procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); 179 begin 180 end; 181 182 procedure TMainForm.FormDestroy(Sender: TObject); 183 begin 200 184 Scheduler.Free; 201 185 end; 202 186 203 procedure T Form1.ListView1Data(Sender: TObject; Item: TListItem);187 procedure TMainForm.ListView1Data(Sender: TObject; Item: TListItem); 204 188 begin 205 189 try 206 Scheduler. Lock.Acquire;190 Scheduler.MicroThreadsLock.Acquire; 207 191 if Item.Index < Scheduler.MicroThreads.Count then 208 192 with TMicroThread(Scheduler.MicroThreads[Item.Index]) do begin … … 216 200 end; 217 201 finally 218 Scheduler.Lock.Release; 219 end; 220 end; 221 222 procedure TForm1.Timer1Timer(Sender: TObject); 202 Scheduler.MicroThreadsLock.Release; 203 end; 204 end; 205 206 procedure TMainForm.SpinEdit2Change(Sender: TObject); 207 begin 208 Scheduler.ThreadPoolSize := SpinEdit2.Value; 209 end; 210 211 procedure TMainForm.Timer1Timer(Sender: TObject); 223 212 begin 224 213 ListView1.Items.Count := Scheduler.MicroThreadCount; … … 229 218 end; 230 219 231 procedure T Form1.Worker(MicroThread: TMicroThread);220 procedure TMainForm.Worker(MicroThread: TMicroThread); 232 221 var 233 222 I: Integer; -
MicroThreading/UMicroThreading.pas
r147 r148 105 105 FTerminated: Boolean; 106 106 FTempPointer: Pointer; 107 FCurrentMicroThread: TMicroThread; 108 FScheduler: TMicroThreadScheduler; 107 109 function Execute(Count: Integer): Integer; 108 110 public 109 Scheduler: TMicroThreadScheduler;110 CurrentMicroThread: TMicroThread;111 111 procedure Yield; 112 112 constructor Create; 113 113 destructor Destroy; override; 114 end; 114 property Scheduler: TMicroThreadScheduler read FScheduler; 115 property CurrentMicroThread: TMicroThread read FCurrentMicroThread; 116 end; 117 118 TMicroThreadSchedulerState = (ssStopped, ssRunning, ssTerminating); 115 119 116 120 { TMicroThreadScheduler } … … 118 122 TMicroThreadScheduler = class 119 123 private 120 ThreadPool: TThreadPool; 121 RoundRobinIndex: Integer; 124 FActive: Boolean; 125 FThreadPool: TThreadPool; 126 FThreadPoolLock: TCriticalSection; 127 FThreadPoolSize: Integer; 128 FRoundRobinIndex: Integer; 122 129 FLastId: Integer; 123 130 FFrequency: Int64; 131 FTerminate: Boolean; 124 132 FTerminated: Boolean; 133 FMicroThreads: TObjectList; // TList<TMicroThread> 134 FMainThreadManager: TMicroThreadManager; 135 FMicroThreadsLock: TCriticalSection; 136 FState: TMicroThreadSchedulerState; 125 137 function GetMicroThreadCount: Integer; 126 138 function GetThreadPoolSize: Integer; 139 procedure SetActive(const AValue: Boolean); 127 140 procedure SetThreadPoolSize(const AValue: Integer); 128 141 function GetNextMicroThread: TMicroThread; 142 procedure WaitFor; 143 procedure Start; 144 procedure Stop; 145 function ThreadPoolTerminated: Boolean; 129 146 public 130 MainThreadManager: TMicroThreadManager;131 MicroThreads: TObjectList; // TList<TMicroThread>132 Lock: TCriticalSection;133 147 function GetNow: TDateTime; 134 148 function Add(MicroThread: TMicroThread): Integer; 135 149 function AddMethod(Method: TMicroThreadEvent): Integer; 150 function GetCPUCoreCount: Integer; 136 151 constructor Create; 137 152 destructor Destroy; override; 138 procedure Start;139 procedure Stop;140 153 property MicroThreadCount: Integer read GetMicroThreadCount; 141 154 property ThreadPoolSize: Integer read GetThreadPoolSize 142 155 write SetThreadPoolSize; 156 property MicroThreads: TObjectList read FMicroThreads; 157 property MicroThreadsLock: TCriticalSection read FMicroThreadsLock; 158 property MainThreadManager: TMicroThreadManager read FMainThreadManager; 159 property Active: Boolean read FActive write SetActive; 143 160 end; 144 161 … … 167 184 with MainScheduler do begin 168 185 try 169 Lock.Acquire;186 FMicroThreadsLock.Acquire; 170 187 I := 0; 171 while (I < MicroThreads.Count) and172 not ((CurrentStack >= TMicroThread( MicroThreads[I]).FStack) and173 (CurrentStack <= (TMicroThread( MicroThreads[I]).FStack +174 TMicroThread( MicroThreads[I]).FStackSize))) do Inc(I);175 if I < MicroThreads.Count then begin176 Result := TMicroThread( MicroThreads[I]).FId;188 while (I < FMicroThreads.Count) and 189 not ((CurrentStack >= TMicroThread(FMicroThreads[I]).FStack) and 190 (CurrentStack <= (TMicroThread(FMicroThreads[I]).FStack + 191 TMicroThread(FMicroThreads[I]).FStackSize))) do Inc(I); 192 if I < FMicroThreads.Count then begin 193 Result := TMicroThread(FMicroThreads[I]).FId; 177 194 end else Result := -1; 178 195 finally 179 Lock.Release;196 FMicroThreadsLock.Release; 180 197 end; 181 198 end; … … 199 216 CurrentTime: TDateTime; 200 217 begin 201 CurrentTime := Scheduler.GetNow;202 if Assigned( CurrentMicroThread) then begin203 CurrentMicroThread.FExecutionEndTime := CurrentTime;204 CurrentMicroThread.FExecutionTime :=CurrentMicroThread.FExecutionTime +205 ( CurrentMicroThread.FExecutionEndTime -CurrentMicroThread.FExecutionStartTime);206 if CurrentMicroThread.FState = tsRunning then207 CurrentMicroThread.FState := tsWaiting;208 StaticMicroThread := CurrentMicroThread;218 CurrentTime := FScheduler.GetNow; 219 if Assigned(FCurrentMicroThread) then begin 220 FCurrentMicroThread.FExecutionEndTime := CurrentTime; 221 FCurrentMicroThread.FExecutionTime := FCurrentMicroThread.FExecutionTime + 222 (FCurrentMicroThread.FExecutionEndTime - FCurrentMicroThread.FExecutionStartTime); 223 if FCurrentMicroThread.FState = tsRunning then 224 FCurrentMicroThread.FState := tsWaiting; 225 StaticMicroThread := FCurrentMicroThread; 209 226 asm 210 227 // Store microthread stack … … 215 232 mov [eax].TMicroThread.FBasePointer, edx 216 233 end; 217 StaticManager := CurrentMicroThread.FManager;234 StaticManager := FCurrentMicroThread.FManager; 218 235 asm 219 // Restore scheduler stack236 // Restore FScheduler stack 220 237 mov eax, StaticManager // Self is invalid before BP restore 221 238 mov edx, [eax].TMicroThreadManager.FStackPointer … … 224 241 mov ebp, edx 225 242 end; 226 CurrentMicroThread.FManager := nil;227 CurrentMicroThread := nil;228 end; 229 230 CurrentMicroThread :=Scheduler.GetNextMicroThread;231 232 if Assigned( CurrentMicroThread) and (FExecutedCount < FExecuteCount) then begin233 CurrentMicroThread.FManager := Self;243 FCurrentMicroThread.FManager := nil; 244 FCurrentMicroThread := nil; 245 end; 246 247 FCurrentMicroThread := FScheduler.GetNextMicroThread; 248 249 if Assigned(FCurrentMicroThread) and (FExecutedCount < FExecuteCount) then begin 250 FCurrentMicroThread.FManager := Self; 234 251 Inc(FExecutedCount); 235 252 asm 236 // Store scheduler stack253 // Store FScheduler stack 237 254 mov eax, Self 238 255 mov edx, esp … … 241 258 mov [eax].TMicroThreadManager.FBasePointer, edx 242 259 end; 243 if not CurrentMicroThread.FExecuted then begin244 CurrentMicroThread.FExecuted := True;245 CurrentMicroThread.FState := tsRunning;246 CurrentMicroThread.FExecutionStartTime := CurrentTime;247 StaticMicroThread := CurrentMicroThread;260 if not FCurrentMicroThread.FExecuted then begin 261 FCurrentMicroThread.FExecuted := True; 262 FCurrentMicroThread.FState := tsRunning; 263 FCurrentMicroThread.FExecutionStartTime := CurrentTime; 264 StaticMicroThread := FCurrentMicroThread; 248 265 asm 249 266 // Restore microthread stack … … 260 277 end; 261 278 //FSelected.Method(FSelected); 262 StaticManager := CurrentMicroThread.FManager;279 StaticManager := FCurrentMicroThread.FManager; 263 280 asm 264 // Restore scheduler stack281 // Restore FScheduler stack 265 282 mov eax, StaticManager // Self is invalid before BP restore 266 283 mov edx, [eax].TMicroThreadManager.FStackPointer … … 269 286 mov ebp, edx 270 287 end; 271 CurrentMicroThread.FManager := nil;272 CurrentMicroThread.FExecutionEndTime := CurrentTime;273 CurrentMicroThread.FExecutionTime :=CurrentMicroThread.FExecutionTime +274 ( CurrentMicroThread.FExecutionEndTime -CurrentMicroThread.FExecutionStartTime);275 CurrentMicroThread.FFinished := True;276 if CurrentMicroThread.FFreeOnTerminate then begin288 FCurrentMicroThread.FManager := nil; 289 FCurrentMicroThread.FExecutionEndTime := CurrentTime; 290 FCurrentMicroThread.FExecutionTime := FCurrentMicroThread.FExecutionTime + 291 (FCurrentMicroThread.FExecutionEndTime - FCurrentMicroThread.FExecutionStartTime); 292 FCurrentMicroThread.FFinished := True; 293 if FCurrentMicroThread.FFreeOnTerminate then begin 277 294 // Microthread is finished, remove it from queue 278 with Scheduler do295 with FScheduler do 279 296 try 280 Lock.Acquire;281 MicroThreads.Delete(MicroThreads.IndexOf(CurrentMicroThread));297 FMicroThreadsLock.Acquire; 298 FMicroThreads.Delete(FMicroThreads.IndexOf(FCurrentMicroThread)); 282 299 finally 283 Lock.Release;300 FMicroThreadsLock.Release; 284 301 end; 285 302 end; 286 CurrentMicroThread := nil;303 FCurrentMicroThread := nil; 287 304 end else 288 if CurrentMicroThread.State = tsWaiting then begin305 if FCurrentMicroThread.State = tsWaiting then begin 289 306 // Execute selected thread 290 CurrentMicroThread.FState := tsRunning;291 CurrentMicroThread.FExecutionStartTime := CurrentTime;292 FTempPointer := CurrentMicroThread.FStackPointer;307 FCurrentMicroThread.FState := tsRunning; 308 FCurrentMicroThread.FExecutionStartTime := CurrentTime; 309 FTempPointer := FCurrentMicroThread.FStackPointer; 293 310 asm 294 311 // Restore microthread stack … … 297 314 mov esp, edx 298 315 end; 299 FTempPointer := CurrentMicroThread.FBasePointer;316 FTempPointer := FCurrentMicroThread.FBasePointer; 300 317 asm 301 318 mov eax, Self … … 305 322 end; 306 323 end else begin 307 CurrentMicroThread := nil;324 FCurrentMicroThread := nil; 308 325 end; 309 326 end; … … 311 328 constructor TMicroThreadManager.Create; 312 329 begin 313 CurrentMicroThread := nil;330 FCurrentMicroThread := nil; 314 331 end; 315 332 … … 469 486 MicroThread.FScheduler := Self; 470 487 MicroThread.FId := FLastId; 471 Result := MicroThreads.Add(MicroThread);488 Result := FMicroThreads.Add(MicroThread); 472 489 end; 473 490 … … 482 499 end; 483 500 501 function TMicroThreadScheduler.GetCPUCoreCount: Integer; 502 var 503 SystemInfo: _SYSTEM_INFO; 504 begin 505 GetSystemInfo(SystemInfo); 506 Result := SystemInfo.dwNumberOfProcessors; 507 end; 508 484 509 constructor TMicroThreadScheduler.Create; 485 510 begin 486 Lock := TCriticalSection.Create; 487 MicroThreads := TObjectList.Create; 488 ThreadPool := TThreadPool.Create; 511 FTerminated := True; 512 FMicroThreadsLock := TCriticalSection.Create; 513 FMicroThreads := TObjectList.Create; 514 FThreadPool := TThreadPool.Create; 515 FThreadPoolLock := TCriticalSection.Create; 489 516 {$IFDEF Windows} 490 517 QueryPerformanceFrequency(FFrequency); 491 518 {$ENDIF} 492 RoundRobinIndex := -1;493 MainThreadManager := TMicroThreadManager.Create;494 MainThreadManager.Scheduler := Self;519 FRoundRobinIndex := -1; 520 FMainThreadManager := TMicroThreadManager.Create; 521 FMainThreadManager.FScheduler := Self; 495 522 end; 496 523 497 524 destructor TMicroThreadScheduler.Destroy; 498 525 begin 499 MainThreadManager.Free;500 F Terminated := True;501 ThreadPool.Free;502 MicroThreads.Free;503 Lock.Free;526 Active := False; 527 FMainThreadManager.Free; 528 FThreadPool.Free; 529 FMicroThreads.Free; 530 FMicroThreadsLock.Free; 504 531 inherited Destroy; 505 532 end; … … 511 538 begin 512 539 FTerminated := False; 513 for I := 0 to ThreadPool.Count - 1 do 514 TMicroThreadSchedulerPoolThread(ThreadPool[I]).Start; 540 FTerminate := False; 541 for I := 0 to FThreadPool.Count - 1 do 542 TMicroThreadSchedulerPoolThread(FThreadPool[I]).Start; 515 543 repeat 516 Executed := MainThreadManager.Execute(10);544 Executed := FMainThreadManager.Execute(10); 517 545 Application.ProcessMessages; 518 546 if Executed = 0 then Sleep(1); 519 until FTerminated; 547 until FTerminate; 548 FTerminated := True; 520 549 end; 521 550 … … 524 553 I: Integer; 525 554 begin 526 for I := 0 to ThreadPool.Count - 1 do 527 TMicroThreadSchedulerPoolThread(ThreadPool[I]).Terminate; 528 FTerminated := True; 555 try 556 FThreadPoolLock.Acquire; 557 for I := 0 to FThreadPool.Count - 1 do begin 558 TMicroThreadSchedulerPoolThread(FThreadPool[I]).Terminate; 559 end; 560 finally 561 FThreadPoolLock.Release; 562 end; 563 FTerminate := True; 564 565 // Wait for all thread managers to finish 566 repeat 567 Application.ProcessMessages; 568 Sleep(1); 569 until FTerminated and (ThreadPoolSize = 0); 570 end; 571 572 function TMicroThreadScheduler.ThreadPoolTerminated: Boolean; 573 var 574 I: Integer; 575 begin 576 try 577 FThreadPoolLock.Acquire; 578 I := 0; 579 while (I < FThreadPool.Count) and 580 (TMicroThreadSchedulerPoolThread(FThreadPool[I]).Terminated do 581 finally 582 FThreadPoolLock.Release; 583 end; 529 584 end; 530 585 … … 537 592 Result := nil; 538 593 try 539 Lock.Acquire;594 FMicroThreadsLock.Acquire; 540 595 I := 0; 541 Inc( RoundRobinIndex);542 if RoundRobinIndex >=MicroThreads.Count then543 RoundRobinIndex := 0;544 while (I < MicroThreads.Count) and545 (TMicroThread( MicroThreads[RoundRobinIndex]).State <> tsWaiting) do begin596 Inc(FRoundRobinIndex); 597 if FRoundRobinIndex >= FMicroThreads.Count then 598 FRoundRobinIndex := 0; 599 while (I < FMicroThreads.Count) and 600 (TMicroThread(FMicroThreads[FRoundRobinIndex]).State <> tsWaiting) do begin 546 601 // WakeUp sleeping threads 547 if (TMicroThread( MicroThreads[RoundRobinIndex]).FState = tsSleeping) and548 (TMicroThread( MicroThreads[RoundRobinIndex]).FWakeupTime < CurrentTime) then549 TMicroThread( MicroThreads[RoundRobinIndex]).FState := tsWaiting else602 if (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState = tsSleeping) and 603 (TMicroThread(FMicroThreads[FRoundRobinIndex]).FWakeupTime < CurrentTime) then 604 TMicroThread(FMicroThreads[FRoundRobinIndex]).FState := tsWaiting else 550 605 begin 551 606 // Go to next thread 552 607 Inc(I); 553 Inc( RoundRobinIndex);554 if RoundRobinIndex >=MicroThreads.Count then555 RoundRobinIndex := 0;608 Inc(FRoundRobinIndex); 609 if FRoundRobinIndex >= FMicroThreads.Count then 610 FRoundRobinIndex := 0; 556 611 end; 557 612 end; 558 if I < MicroThreads.Count then begin559 Result := TMicroThread( MicroThreads[RoundRobinIndex]);613 if I < FMicroThreads.Count then begin 614 Result := TMicroThread(FMicroThreads[FRoundRobinIndex]); 560 615 end; 561 616 finally 562 Lock.Release;617 FMicroThreadsLock.Release; 563 618 end; 564 619 end; … … 567 622 begin 568 623 try 569 Lock.Acquire;570 Result := MicroThreads.Count;624 FMicroThreadsLock.Acquire; 625 Result := FMicroThreads.Count; 571 626 finally 572 Lock.Release;627 FMicroThreadsLock.Release; 573 628 end; 574 629 end; … … 576 631 function TMicroThreadScheduler.GetThreadPoolSize: Integer; 577 632 begin 578 Result := ThreadPool.Count; 633 Result := FThreadPoolSize; 634 end; 635 636 procedure TMicroThreadScheduler.SetActive(const AValue: Boolean); 637 begin 638 if FActive = AValue then Exit; 639 FActive := AValue; 640 if AValue then Start 641 else Stop; 579 642 end; 580 643 … … 584 647 NewThread: TMicroThreadSchedulerPoolThread; 585 648 begin 586 if AValue > ThreadPool.Count then begin 587 ThreadPool.Capacity := AValue; 588 while ThreadPool.Count < AValue do begin 589 NewThread := TMicroThreadSchedulerPoolThread.Create(True); 590 NewThread.Manager.Scheduler := Self; 591 ThreadPool.Add(NewThread); 592 end; 593 end else 594 ThreadPool.Count := AValue; 649 FThreadPoolSize := AValue; 650 if FState = ssRunning then 651 SetThreadPoolCount 595 652 end; 596 653
Note:
See TracChangeset
for help on using the changeset viewer.