Changeset 169 for MicroThreading/UMicroThreading.pas
- Timestamp:
- Feb 11, 2011, 2:16:17 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/UMicroThreading.pas
r168 r169 35 35 SReleaseNotAcquiredLock = 'Release on not acquired lock'; 36 36 SMethodNotAssigned = 'Method for microthread not assigned'; 37 SCriticalSectionDecrement = 'Critical section counter decremented to negative number'; 37 38 38 39 … … 117 118 procedure Yield; 118 119 procedure MTSleep(Duration: TDateTime); // No conflicting name to global Sleep procedure 119 procedure WaitForCriticalSection(CriticalSection: TMicroThreadCriticalSection);120 function WaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;121 120 procedure WaitFor; 122 121 procedure Terminate; … … 236 235 BurstCount: Integer; 237 236 function Add(MicroThread: TMicroThread): Integer; 238 function AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean = False): Integer;237 function AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean = True): Integer; 239 238 procedure Remove(MicroThread: TMicroThread; Free: Boolean = True); 240 239 constructor Create; … … 278 277 procedure MTSleep(Duration: TDateTime); 279 278 procedure MTSynchronize(Method: TThreadMethod); 280 function MTWaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;281 279 procedure Log(Text: string); 282 280 procedure Register; … … 345 343 end; 346 344 347 function MTWaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;348 var349 MT: TMicroThread;350 begin351 MT := GetCurrentMicroThread;352 if Assigned(MT) then Result := MT.WaitForEvent(Event, Duration)353 else raise EMicroThreadError.Create(SNotInMicroThread);354 end;355 356 345 var 357 346 LogLock: TCriticalSection; … … 381 370 begin 382 371 MT := GetCurrentMicroThread; 383 if Assigned(MT) then MT.WaitForCriticalSection(Self) 384 else raise EMicroThreadError.Create(SNotInMicroThread); 372 if Assigned(MT) then 373 try 374 MainScheduler.FMicroThreadsLock.Acquire; 375 Lock.Acquire; 376 Inc(FCounter); 377 if FCounter > 1 then begin 378 FMicroThreads.Add(MT); 379 MT.FBlockState := tbsCriticalSection; 380 MT.FStatePending := tsBlocked; 381 try 382 Lock.Release; 383 MainScheduler.FMicroThreadsLock.Release; 384 MT.Yield; 385 finally 386 MainScheduler.FMicroThreadsLock.Acquire; 387 Lock.Acquire; 388 end; 389 end; 390 finally 391 Lock.Release; 392 MainScheduler.FMicroThreadsLock.Release; 393 end else 394 raise EMicroThreadError.Create(SNotInMicroThread); 385 395 end; 386 396 … … 394 404 // Release one waiting micro thread 395 405 TMicroThread(FMicroThreads[0]).FState := tsWaiting; 406 TMicroThread(FMicroThreads[0]).FStatePending := tsNone; 396 407 FMicroThreads.Delete(0); 397 408 end; 409 if FCounter < 0 then 410 raise EMicroThreadError.Create(SCriticalSectionDecrement); 398 411 finally 399 412 Lock.Release; … … 468 481 begin 469 482 MT := GetCurrentMicroThread; 470 if Assigned(MT) then Result := MT.WaitForEvent(Self, Duration) 471 else raise EMicroThreadError.Create(SNotInMicroThread); 483 if Assigned(MT) then begin 484 try 485 FMicroThreadsLock.Acquire; 486 if Signaled then begin 487 Result := wrSignaled; 488 Exit; 489 end; 490 FMicroThreads.Add(Self); 491 MT.FBlockTime := NowPrecise + Duration; 492 MT.FBlockState := tbsWaitFor; 493 MT.FStatePending := tsBlocked; 494 finally 495 FMicroThreadsLock.Release; 496 end; 497 MT.Yield; 498 if (MT.FBlockTime <> 0) and (MT.FBlockTime < NowPrecise) then 499 Result := wrTimeout else Result := wrSignaled; 500 501 try 502 FMicroThreadsLock.Acquire; 503 FMicroThreads.Remove(Self); 504 finally 505 FMicroThreadsLock.Release; 506 end 507 end else 508 raise EMicroThreadError.Create(SNotInMicroThread); 472 509 end; 473 510 … … 773 810 // Called from another microthread 774 811 while not ((FState = tsBlocked) and (FBlockState = tbsTerminated)) do begin 775 MTSleep(1 );812 MTSleep(1 * OneMillisecond); 776 813 end; 777 814 end else begin … … 792 829 end; 793 830 794 procedure TMicroThread.WaitForCriticalSection(795 CriticalSection: TMicroThreadCriticalSection);796 begin797 try798 FScheduler.FMicroThreadsLock.Acquire;799 CriticalSection.Lock.Acquire;800 Inc(CriticalSection.FCounter);801 if CriticalSection.FCounter > 1 then begin802 CriticalSection.FMicroThreads.Add(Self);803 FBlockState := tbsCriticalSection;804 FStatePending := tsBlocked;805 try806 CriticalSection.Lock.Release;807 FScheduler.FMicroThreadsLock.Release;808 Yield;809 finally810 FScheduler.FMicroThreadsLock.Acquire;811 CriticalSection.Lock.Acquire;812 end;813 end;814 finally815 CriticalSection.Lock.Release;816 FScheduler.FMicroThreadsLock.Release;817 end;818 end;819 820 function TMicroThread.WaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;821 begin822 try823 Event.FMicroThreadsLock.Acquire;824 if Event.Signaled then begin825 Result := wrSignaled;826 Exit;827 end;828 Event.FMicroThreads.Add(Self);829 FBlockTime := NowPrecise + Duration;830 FBlockState := tbsWaitFor;831 FStatePending := tsBlocked;832 finally833 Event.FMicroThreadsLock.Release;834 end;835 Yield;836 if (FBlockTime <> 0) and (FBlockTime < NowPrecise) then Result := wrTimeout837 else Result := wrSignaled;838 839 try840 Event.FMicroThreadsLock.Acquire;841 Event.FMicroThreads.Remove(Self);842 finally843 Event.FMicroThreadsLock.Release;844 end;845 end;846 847 831 constructor TMicroThread.Create(CreateSuspended: Boolean; 848 832 const StackSize: SizeUInt = DefaultStackSize); … … 851 835 FStackSize := StackSize; 852 836 FStack := GetMem(FStackSize); 853 FBasePointer := FStack + FStackSize - SizeOf(Pointer);854 FStackPointer := F BasePointer -SizeOf(Pointer);837 FBasePointer := 0; // FStack + FStackSize - SizeOf(Pointer); 838 FStackPointer := FStack + FStackSize - 2 * SizeOf(Pointer); 855 839 FillChar(FStackPointer^, 2 * SizeOf(Pointer), 0); 856 840
Note:
See TracChangeset
for help on using the changeset viewer.