Changeset 162 for MicroThreading/UMicroThreading.pas
- Timestamp:
- Feb 7, 2011, 1:04:27 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/UMicroThreading.pas
r161 r162 1 (* Not implemented yet 1 // Date: 2010-02-07 2 3 (* 4 Not implemented yet 2 5 - Stack limit checking 3 6 - measurement of cpu usage by micro threads 4 - microthread critical sections (no low level cpu blocking) 5 - wait for single and multiple objects 6 - micro thread priorty 7 - wait for multiple objects 8 - micro thread priority 7 9 *) 8 10 … … 31 33 SCantDetermineThreadID = 'Can''t determine thread for id %d'; 32 34 SNotInThread = 'Not in thread'; 35 SReleaseNotAcquiredLock = 'Release not acquired lock'; 33 36 34 37 … … 41 44 TMicroThreadBlockState = (tbsNone, tbsSleeping, tbsWaitFor, tbsTerminating, 42 45 tbsTerminated); 46 47 { TMicroThreadCriticalSection } 48 49 TMicroThreadCriticalSection = class 50 Lock: TCriticalSection; 51 Counter: Integer; 52 procedure Acquire; 53 procedure Release; 54 constructor Create; 55 destructor Destroy; override; 56 end; 43 57 44 58 { TMicroThreadEvent } … … 53 67 procedure SetEvent; 54 68 procedure ResetEvent; 55 procedure WaitFor(Duration: TDateTime);69 function WaitFor(Duration: TDateTime): TWaitResult; 56 70 constructor Create; 57 71 destructor Destroy; override; … … 70 84 FExecutionCount: Integer; 71 85 FStack: Pointer; 72 FStackPointer: Pointer; 86 FStackPointer: Pointer; // Register SP 73 87 FStackSize: Integer; 74 FBasePointer: Pointer; 88 FBasePointer: Pointer; // Register BP 75 89 FExceptObjectStack: PExceptObject; 76 90 FExceptAddrStack: PExceptAddr; … … 160 174 FThread: TMicroThreadThread; 161 175 FId: Integer; 176 FLoopDuration: TDateTime; 177 FLoopStart: TDateTime; 162 178 procedure SetCurrentMicroThread(const AValue: TMicroThread); 163 179 function Execute(Count: Integer): Integer; … … 170 186 destructor Destroy; override; 171 187 property Scheduler: TMicroThreadScheduler read FScheduler; 188 property LoopDuration: TDateTime read FLoopDuration; 189 function GetCurrentMicroThreadId: Integer; 172 190 end; 173 191 … … 206 224 procedure MainThreadTick(Data: PtrInt); 207 225 public 226 BurstCount: Integer; 208 227 function Add(MicroThread: TMicroThread): Integer; 209 228 function AddMethod(Method: TMicroThreadMethod): Integer; … … 343 362 end; 344 363 364 { TMicroThreadCriticalSection } 365 366 procedure TMicroThreadCriticalSection.Acquire; 367 begin 368 try 369 Lock.Acquire; 370 while Counter > 0 do begin 371 try 372 Lock.Release; 373 MTSleep(1 * OneMillisecond); 374 finally 375 Lock.Acquire; 376 end; 377 end; 378 Inc(Counter); 379 finally 380 Lock.Release; 381 end; 382 end; 383 384 procedure TMicroThreadCriticalSection.Release; 385 begin 386 try 387 Lock.Acquire; 388 if Counter > 0 then Dec(Counter) 389 else raise Exception.Create(SReleaseNotAcquiredLock); 390 finally 391 Lock.Release; 392 end; 393 end; 394 395 constructor TMicroThreadCriticalSection.Create; 396 begin 397 Lock := TCriticalSection.Create; 398 end; 399 400 destructor TMicroThreadCriticalSection.Destroy; 401 begin 402 Acquire; 403 Lock.Free; 404 inherited Destroy; 405 end; 406 345 407 { TMicroThreadList } 346 408 … … 363 425 for I := 0 to FMicroThreads.Count - 1 do 364 426 with TMicroThread(FMicroThreads[I]) do begin 365 if (FState = tsBlocked) and (FBlockState = tbsWaitFor) then 427 if (FState = tsBlocked) and (FBlockState = tbsWaitFor) then begin 366 428 FState := tsWaiting; 429 FBlockTime := 0; // Set signaled state using block time variable 430 end; 367 431 end; 368 432 if not FAutoReset then FSignaled := True; … … 377 441 end; 378 442 379 procedure TMicroThreadEvent.WaitFor(Duration: TDateTime);443 function TMicroThreadEvent.WaitFor(Duration: TDateTime): TWaitResult; 380 444 var 381 445 MT: TMicroThread; 382 446 begin 383 447 MT := GetCurrentMicroThread; 384 if Assigned(MT) then MT.WaitForEvent(Self, Duration); 448 if Assigned(MT) then Result := MT.WaitForEvent(Self, Duration) 449 else Result := wrSignaled; 385 450 end; 386 451 … … 422 487 function TMicroThreadManager.Execute(Count: Integer): Integer; 423 488 begin 489 FLoopStart := NowPrecise; 424 490 FStack := StackBottom; 425 491 FStackSize := StackBottom + StackLength; … … 428 494 Yield; 429 495 Result := FExecutedCount; 496 FLoopDuration := NowPrecise - FLoopStart; 430 497 end; 431 498 … … 489 556 mov ebp, ebx 490 557 // We want to call virtual method Execute 491 // but virtual methods can be called only statically558 // but methods can be called only statically from assembler 492 559 // Then static method CallExecute is calling virtual method Execute 493 560 call TMicroThread.CallExecute … … 515 582 FMicroThreadsLock.Acquire; 516 583 FMicroThreads.Delete(FMicroThreads.IndexOf(FCurrentMicroThread)); 517 FCurrentMicroThread .Manager:= nil;584 FCurrentMicroThread := nil; 518 585 finally 519 586 FMicroThreadsLock.Release; … … 562 629 end; 563 630 631 function TMicroThreadManager.GetCurrentMicroThreadId: Integer; 632 begin 633 try 634 FScheduler.FMicroThreadsLock.Acquire; 635 if Assigned(FCurrentMicroThread) then 636 Result := FCurrentMicroThread.Id 637 else Result := 0; 638 finally 639 FScheduler.FMicroThreadsLock.Release; 640 end; 641 end; 642 564 643 { TMicroThreadThread } 565 644 … … 571 650 repeat 572 651 State := ttsRunning; 573 ExecutedCount := Manager.Execute( 10);652 ExecutedCount := Manager.Execute(MainScheduler.BurstCount); 574 653 State := ttsReady; 575 654 if ExecutedCount = 0 then Sleep(1); … … 691 770 end; 692 771 Yield; 693 if FBlockTime < NowPrecise then694 Result := wrTimeoutelse Result := wrSignaled;772 if (FBlockTime <> 0) and (FBlockTime < NowPrecise) then Result := wrTimeout 773 else Result := wrSignaled; 695 774 696 775 try … … 811 890 FMainThreadManager.FScheduler := Self; 812 891 UseMainThread := False; 892 BurstCount := 100; 813 893 end; 814 894 … … 900 980 var 901 981 Executed: Integer; 982 StartTime: TDateTime; 983 Duration: TDateTime; 902 984 begin 903 985 // try 904 Executed := FMainThreadManager.Execute(1); 905 if Executed = 0 then Sleep(1); 986 Duration := 100 * OneMillisecond; 987 StartTime := NowPrecise; 988 Executed := -1; 989 while (Executed <> 0) and ((NowPrecise - StartTime) < Duration) do begin 990 Executed := FMainThreadManager.Execute(BurstCount); 991 end; 992 //if Executed = 0 then Sleep(1); 906 993 // If not terminated then queue next tick else terminate 907 994 if (FState = ssRunning) and FUseMainThread then
Note:
See TracChangeset
for help on using the changeset viewer.