Changeset 155 for MicroThreading
- Timestamp:
- Jan 28, 2011, 7:33:14 AM (14 years ago)
- Location:
- MicroThreading
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/Demo/Demo.lpi
r154 r155 48 48 <TopLine Value="1"/> 49 49 <CursorPos X="21" Y="18"/> 50 <UsageCount Value=" 69"/>50 <UsageCount Value="70"/> 51 51 <Loaded Value="True"/> 52 52 </Unit0> … … 59 59 <EditorIndex Value="0"/> 60 60 <WindowIndex Value="0"/> 61 <TopLine Value="2 63"/>62 <CursorPos X=" 8" Y="276"/>63 <UsageCount Value=" 69"/>61 <TopLine Value="206"/> 62 <CursorPos X="1" Y="211"/> 63 <UsageCount Value="70"/> 64 64 <Loaded Value="True"/> 65 65 <LoadedDesigner Value="True"/> … … 71 71 <EditorIndex Value="2"/> 72 72 <WindowIndex Value="0"/> 73 <TopLine Value=" 51"/>74 <CursorPos X="2 2" Y="54"/>73 <TopLine Value="708"/> 74 <CursorPos X="24" Y="718"/> 75 75 <UsageCount Value="37"/> 76 76 <Loaded Value="True"/> … … 543 543 <Position1> 544 544 <Filename Value="../UMicroThreading.pas"/> 545 <Caret Line=" 250" Column="1" TopLine="228"/>545 <Caret Line="718" Column="1" TopLine="701"/> 546 546 </Position1> 547 547 <Position2> 548 548 <Filename Value="../UMicroThreading.pas"/> 549 <Caret Line=" 472" Column="1" TopLine="459"/>549 <Caret Line="719" Column="1" TopLine="701"/> 550 550 </Position2> 551 551 <Position3> 552 552 <Filename Value="../UMicroThreading.pas"/> 553 <Caret Line=" 473" Column="1" TopLine="459"/>553 <Caret Line="720" Column="1" TopLine="701"/> 554 554 </Position3> 555 555 <Position4> 556 556 <Filename Value="../UMicroThreading.pas"/> 557 <Caret Line=" 474" Column="1" TopLine="459"/>557 <Caret Line="718" Column="1" TopLine="701"/> 558 558 </Position4> 559 559 <Position5> 560 560 <Filename Value="../UMicroThreading.pas"/> 561 <Caret Line=" 459" Column="1" TopLine="446"/>561 <Caret Line="719" Column="1" TopLine="701"/> 562 562 </Position5> 563 563 <Position6> 564 564 <Filename Value="../UMicroThreading.pas"/> 565 <Caret Line=" 267" Column="1" TopLine="254"/>565 <Caret Line="720" Column="1" TopLine="701"/> 566 566 </Position6> 567 567 <Position7> 568 568 <Filename Value="../UMicroThreading.pas"/> 569 <Caret Line=" 268" Column="1" TopLine="254"/>569 <Caret Line="718" Column="1" TopLine="701"/> 570 570 </Position7> 571 571 <Position8> 572 <Filename Value="../U Platform.pas"/>573 <Caret Line=" 29" Column="1" TopLine="16"/>572 <Filename Value="../UMicroThreading.pas"/> 573 <Caret Line="719" Column="1" TopLine="701"/> 574 574 </Position8> 575 575 <Position9> 576 <Filename Value="../U Platform.pas"/>577 <Caret Line=" 31" Column="1" TopLine="16"/>576 <Filename Value="../UMicroThreading.pas"/> 577 <Caret Line="720" Column="1" TopLine="701"/> 578 578 </Position9> 579 579 <Position10> 580 <Filename Value="../U Platform.pas"/>581 <Caret Line=" 40" Column="1" TopLine="18"/>580 <Filename Value="../UMicroThreading.pas"/> 581 <Caret Line="670" Column="3" TopLine="664"/> 582 582 </Position10> 583 583 <Position11> 584 <Filename Value="../U Platform.pas"/>585 <Caret Line=" 41" Column="1" TopLine="19"/>584 <Filename Value="../UMicroThreading.pas"/> 585 <Caret Line="706" Column="1" TopLine="693"/> 586 586 </Position11> 587 587 <Position12> 588 588 <Filename Value="../UMicroThreading.pas"/> 589 <Caret Line=" 269" Column="1" TopLine="254"/>589 <Caret Line="771" Column="3" TopLine="767"/> 590 590 </Position12> 591 591 <Position13> 592 592 <Filename Value="../UMicroThreading.pas"/> 593 <Caret Line=" 270" Column="1" TopLine="260"/>593 <Caret Line="719" Column="12" TopLine="699"/> 594 594 </Position13> 595 595 <Position14> 596 596 <Filename Value="../UMicroThreading.pas"/> 597 <Caret Line=" 273" Column="1" TopLine="260"/>597 <Caret Line="718" Column="1" TopLine="699"/> 598 598 </Position14> 599 599 <Position15> 600 600 <Filename Value="../UMicroThreading.pas"/> 601 <Caret Line=" 274" Column="1" TopLine="260"/>601 <Caret Line="719" Column="1" TopLine="699"/> 602 602 </Position15> 603 603 <Position16> 604 604 <Filename Value="../UMicroThreading.pas"/> 605 <Caret Line=" 275" Column="1" TopLine="260"/>605 <Caret Line="720" Column="1" TopLine="699"/> 606 606 </Position16> 607 607 <Position17> 608 608 <Filename Value="../UMicroThreading.pas"/> 609 <Caret Line=" 276" Column="1" TopLine="260"/>609 <Caret Line="718" Column="1" TopLine="699"/> 610 610 </Position17> 611 611 <Position18> 612 612 <Filename Value="../UMicroThreading.pas"/> 613 <Caret Line=" 277" Column="1" TopLine="260"/>613 <Caret Line="719" Column="1" TopLine="699"/> 614 614 </Position18> 615 615 <Position19> 616 616 <Filename Value="../UMicroThreading.pas"/> 617 <Caret Line=" 278" Column="1" TopLine="260"/>617 <Caret Line="720" Column="1" TopLine="699"/> 618 618 </Position19> 619 619 <Position20> 620 620 <Filename Value="../UMicroThreading.pas"/> 621 <Caret Line=" 281" Column="1" TopLine="260"/>621 <Caret Line="718" Column="1" TopLine="699"/> 622 622 </Position20> 623 623 <Position21> 624 624 <Filename Value="../UMicroThreading.pas"/> 625 <Caret Line=" 282" Column="1" TopLine="260"/>625 <Caret Line="719" Column="1" TopLine="699"/> 626 626 </Position21> 627 627 <Position22> 628 628 <Filename Value="../UMicroThreading.pas"/> 629 <Caret Line=" 283" Column="1" TopLine="261"/>629 <Caret Line="718" Column="1" TopLine="699"/> 630 630 </Position22> 631 631 <Position23> 632 632 <Filename Value="../UMicroThreading.pas"/> 633 <Caret Line=" 284" Column="1" TopLine="262"/>633 <Caret Line="719" Column="1" TopLine="699"/> 634 634 </Position23> 635 635 <Position24> 636 636 <Filename Value="../UMicroThreading.pas"/> 637 <Caret Line=" 286" Column="1" TopLine="264"/>637 <Caret Line="720" Column="1" TopLine="699"/> 638 638 </Position24> 639 639 <Position25> 640 <Filename Value=" UMainForm.pas"/>641 <Caret Line=" 276" Column="1" TopLine="263"/>640 <Filename Value="../UMicroThreading.pas"/> 641 <Caret Line="718" Column="1" TopLine="699"/> 642 642 </Position25> 643 643 <Position26> 644 644 <Filename Value="../UMicroThreading.pas"/> 645 <Caret Line=" 249" Column="1" TopLine="236"/>645 <Caret Line="719" Column="1" TopLine="699"/> 646 646 </Position26> 647 647 <Position27> 648 648 <Filename Value="../UMicroThreading.pas"/> 649 <Caret Line=" 250" Column="1" TopLine="236"/>649 <Caret Line="4" Column="72" TopLine="1"/> 650 650 </Position27> 651 651 <Position28> 652 <Filename Value=" UMainForm.pas"/>653 <Caret Line=" 276" Column="8" TopLine="263"/>652 <Filename Value="../UMicroThreading.pas"/> 653 <Caret Line="166" Column="26" TopLine="144"/> 654 654 </Position28> 655 655 <Position29> 656 656 <Filename Value="../UMicroThreading.pas"/> 657 <Caret Line=" 250" Column="29" TopLine="245"/>657 <Caret Line="670" Column="24" TopLine="654"/> 658 658 </Position29> 659 659 <Position30> 660 660 <Filename Value="../UMicroThreading.pas"/> 661 <Caret Line=" 64" Column="17" TopLine="51"/>661 <Caret Line="783" Column="25" TopLine="766"/> 662 662 </Position30> 663 663 </JumpHistory> -
MicroThreading/Demo/UMainForm.lfm
r152 r155 7 7 ClientHeight = 533 8 8 ClientWidth = 775 9 OnClose = FormClose10 9 OnCreate = FormCreate 11 10 OnDestroy = FormDestroy … … 128 127 end 129 128 item 129 Caption = 'Block state' 130 end 131 item 130 132 Caption = 'Execution time' 131 133 Width = 70 -
MicroThreading/Demo/UMainForm.pas
r154 r155 55 55 procedure ButtonClearMicroThreadsClick(Sender: TObject); 56 56 procedure CheckBoxUseMainThreadChange(Sender: TObject); 57 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);58 57 procedure FormCreate(Sender: TObject); 59 58 procedure FormDestroy(Sender: TObject); … … 208 207 end; 209 208 210 procedure TMainForm.Form Close(Sender: TObject; var CloseAction: TCloseAction);209 procedure TMainForm.FormDestroy(Sender: TObject); 211 210 begin 212 211 MainScheduler.Active := False; 213 end;214 215 procedure TMainForm.FormDestroy(Sender: TObject);216 begin217 MainScheduler.Free;218 212 end; 219 213 … … 234 228 Item.SubItems.Add(IntToStr(Priority)); 235 229 Item.SubItems.Add(MicroThreadStateText[State]); 230 Item.SubItems.Add(MicroThreadBlockStateText[BlockState]); 236 231 Item.SubItems.Add(FloatToStr(ExecutionTime)); 237 232 Item.SubItems.Add(IntToStr(Trunc(Completion * 100)) + '%'); -
MicroThreading/UMicroThreading.pas
r154 r155 28 28 TMicroThreadManager = class; 29 29 30 TMicroThreadState = (tsWaiting, tsRunning, tsBlocked, tsSuspended, 31 tsSleeping); 30 TMicroThreadState = (tsWaiting, tsRunning, tsBlocked, tsSuspended); 31 TMicroThreadBlockState = (tbsNone, tbsSleeping, tbsWaitFor, tbsTerminating, 32 tbsTerminated); 32 33 33 34 { TMicroThreadEvent } … … 61 62 FStackSize: Integer; 62 63 FBasePointer: Pointer; 63 FWakeUpTime: TDateTime;64 FTerminated: Boolean;65 64 FExecuted: Boolean; // At first go through Execute method, then switch context 66 FFinished: Boolean; 67 FSuspended: Boolean; 68 FBlocked: Boolean; 65 FBlockState: TMicroThreadBlockState; 66 FBlockTime: TDateTime; 69 67 FState: TMicroThreadState; 68 FStatePending: TMicroThreadState; 70 69 FScheduler: TMicroThreadScheduler; 71 70 FManager: TMicroThreadManager; 72 71 FId: Integer; 73 FBlockCondition: Boolean;74 72 procedure CallExecute; 75 73 function GetStackUsed: Integer; 74 function GetTerminated: Boolean; 76 75 procedure SetScheduler(const AValue: TMicroThreadScheduler); 77 76 public … … 96 95 property Id: Integer read FId; 97 96 property State: TMicroThreadState read FState; 97 property BlockState: TMicroThreadBlockState read FBlockState; 98 98 property ExecutionTime: TDateTime read FExecutionTime; 99 99 property FreeOnTerminate: Boolean read FFreeOnTerminate 100 100 write FFreeOnTerminate; 101 property Terminated: Boolean read FTerminated;101 property Terminated: Boolean read GetTerminated; 102 102 property Scheduler: TMicroThreadScheduler read FScheduler 103 103 write SetScheduler; … … 207 207 const 208 208 MicroThreadStateText: array[TMicroThreadState] of string = ('Waiting', 209 'Running', 'Blocked', 'Suspended', 'Sleeping'); 209 'Running', 'Blocked', 'Suspended'); 210 MicroThreadBlockStateText: array[TMicroThreadBlockState] of string = ('None', 211 'Sleeping', 'WaitFor', 'Terminating', 'Terminated'); 210 212 211 213 function GetCurrentMicroThread: TMicroThread; … … 289 291 begin 290 292 for I := 0 to FMicroThreads.Count - 1 do 291 TMicroThread(FMicroThreads[I]).F BlockCondition := True;293 TMicroThread(FMicroThreads[I]).FStatePending := tsWaiting; 292 294 if not FAutoReset then FSignaled := True; 293 295 end; … … 400 402 FCurrentMicroThread.FExecutionTime := FCurrentMicroThread.FExecutionTime + 401 403 (FCurrentMicroThread.FExecutionEndTime - FCurrentMicroThread.FExecutionStartTime); 402 FCurrentMicroThread.FFinished := True; 404 FCurrentMicroThread.FState := tsBlocked; 405 FCurrentMicroThread.FBlockState := tbsTerminated; 403 406 if FCurrentMicroThread.FFreeOnTerminate then begin 404 407 // Microthread is finished, remove it from queue … … 514 517 end; 515 518 519 function TMicroThread.GetTerminated: Boolean; 520 begin 521 Result := (FState = tsBlocked) and (FBlockState = tbsTerminated); 522 end; 523 516 524 procedure TMicroThread.SetScheduler(const AValue: TMicroThreadScheduler); 517 525 begin … … 532 540 begin 533 541 if GetMicroThreadId <> -1 then 534 while not FFinisheddo begin542 while not ((FState = tsBlocked) and (FBlockState = tbsTerminated)) do begin 535 543 MTSleep(1); 536 544 end; … … 539 547 procedure TMicroThread.MTSleep(Duration: TDateTime); 540 548 begin 541 FWakeUpTime := NowPrecise + Duration; 542 FState := tsSleeping; 549 FBlockTime := NowPrecise + Duration; 550 FBlockState := tbsSleeping; 551 FStatePending := tsBlocked; 543 552 Yield; 544 553 end; … … 552 561 Event.FMicroThreadsLock.Release; 553 562 end; 554 FBlocked := True; 563 FBlockTime := NowPrecise + Duration; 564 FBlockState := tbsWaitFor; 565 FStatePending := tsBlocked; 555 566 Yield; 556 repeat557 if FState = tsBlocked then MTSleep(1);558 until Result <> wrTimeout;559 567 try 560 568 Event.FMicroThreadsLock.Acquire; … … 573 581 FStackPointer := FBasePointer - SizeOf(Pointer); 574 582 FExecutionTime := 0; 575 FTerminated := False; 583 FState := tsWaiting; 584 FStatePending := tsWaiting; 576 585 if CreateSuspended then begin 577 586 FState := tsSuspended; 578 FS uspended := True;579 end else FSuspended := False;587 FStatePending := tsSuspended; 588 end; 580 589 FFreeOnTerminate := True; 581 590 end; … … 583 592 procedure TMicroThread.Terminate; 584 593 begin 585 FTerminated := True; 594 FBlockState := tbsTerminated; 595 FStatePending := tsBlocked; 586 596 end; 587 597 … … 601 611 procedure TMicroThread.Resume; 602 612 begin 603 FSuspended := False;604 613 if FState = tsSuspended then 605 FState := tsWaiting;614 FStatePending := tsWaiting; 606 615 end; 607 616 608 617 procedure TMicroThread.Suspend; 609 618 begin 610 FS uspended := True;619 FStatePending := tsSuspended; 611 620 //Yield; 612 621 end; … … 684 693 procedure TMicroThreadScheduler.Start; 685 694 begin 686 FMainThreadTerminated := False;687 695 UpdateThreadPoolSize; 688 696 FState := ssRunning; … … 761 769 begin 762 770 FMainThreadStarter.Enabled := False; 771 FMainThreadTerminated := False; 763 772 repeat 764 773 Executed := FMainThreadManager.Execute(1); … … 782 791 if FRoundRobinIndex >= FMicroThreads.Count then 783 792 FRoundRobinIndex := 0; 784 while (I < FMicroThreads.Count) and 785 (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState <> tsWaiting) do begin 786 // WakeUp sleeping threads 787 if (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState = tsSleeping) and 788 (TMicroThread(FMicroThreads[FRoundRobinIndex]).FWakeupTime < CurrentTime) then 789 TMicroThread(FMicroThreads[FRoundRobinIndex]).FState := tsWaiting 793 while (I < FMicroThreads.Count) do 794 with TMicroThread(FMicroThreads[FRoundRobinIndex]) do begin 795 FState := FStatePending; 796 if (FState = tsWaiting) then Break 790 797 else 791 if (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState = tsBlocked) and 792 (TMicroThread(FMicroThreads[FRoundRobinIndex]).FBlockCondition) then 793 TMicroThread(FMicroThreads[FRoundRobinIndex]).FState := tsWaiting 794 else begin 795 // Go to next thread 796 Inc(I); 797 Inc(FRoundRobinIndex); 798 if FRoundRobinIndex >= FMicroThreads.Count then 799 FRoundRobinIndex := 0; 798 if (FState = tsBlocked) then begin 799 // Wakeup sleeping threads 800 if (FBlockState = tbsSleeping) and 801 (FBlockTime < CurrentTime) then begin 802 FState := tsWaiting; 803 FBlockState := tbsNone; 804 Break; 805 end 806 else 807 // Unblock event waiting threads 808 if (FBlockState = tbsWaitFor) and 809 (FBlockTime < CurrentTime) then begin 810 FState := tsWaiting; 811 FBlockState := tbsNone; 812 Break; 813 end; 800 814 end; 815 // Go to next thread 816 Inc(I); 817 Inc(FRoundRobinIndex); 818 if FRoundRobinIndex >= FMicroThreads.Count then 819 FRoundRobinIndex := 0; 801 820 end; 802 821 if I < FMicroThreads.Count then begin 803 822 Result := TMicroThread(FMicroThreads[FRoundRobinIndex]); 804 823 Result.FState := tsRunning; 824 Result.FStatePending := tsWaiting; 805 825 end; 806 826 finally … … 813 833 try 814 834 FMicroThreadsLock.Acquire; 815 if MicroThread.FState = tsRunning then begin 816 MicroThread.FState := tsWaiting; 817 end; 835 MicroThread.FState := MicroThread.FStatePending; 818 836 finally 819 837 FMicroThreadsLock.Release;
Note:
See TracChangeset
for help on using the changeset viewer.