Changeset 169 for MicroThreading
- Timestamp:
- Feb 11, 2011, 2:16:17 PM (14 years ago)
- Location:
- MicroThreading
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/Demo/Demo.lpi
r168 r169 59 59 <ResourceBaseClass Value="Form"/> 60 60 <UnitName Value="UMainForm"/> 61 <EditorIndex Value="1 3"/>62 <WindowIndex Value="0"/> 63 <TopLine Value=" 393"/>64 <CursorPos X=" 29" Y="406"/>61 <EditorIndex Value="12"/> 62 <WindowIndex Value="0"/> 63 <TopLine Value="407"/> 64 <CursorPos X="54" Y="428"/> 65 65 <UsageCount Value="270"/> 66 66 <Loaded Value="True"/> … … 73 73 <EditorIndex Value="0"/> 74 74 <WindowIndex Value="0"/> 75 <TopLine Value=" 885"/>76 <CursorPos X="1" Y=" 897"/>75 <TopLine Value="449"/> 76 <CursorPos X="1" Y="462"/> 77 77 <UsageCount Value="136"/> 78 78 <Loaded Value="True"/> … … 241 241 <Filename Value="../../../../Projekty2/FreePascalManager/trunk/Instance/1/FPC/packages/fcl-base/src/syncobjs.pp"/> 242 242 <UnitName Value="syncobjs"/> 243 <EditorIndex Value="1 2"/>243 <EditorIndex Value="11"/> 244 244 <WindowIndex Value="0"/> 245 245 <TopLine Value="35"/> … … 310 310 <Filename Value="../UStackTrace.pas"/> 311 311 <UnitName Value="UStackTrace"/> 312 <EditorIndex Value="9"/>313 312 <WindowIndex Value="0"/> 314 313 <TopLine Value="17"/> 315 314 <CursorPos X="26" Y="122"/> 316 315 <UsageCount Value="11"/> 317 <Loaded Value="True"/>318 316 </Unit31> 319 317 <Unit32> 320 318 <Filename Value="../../../../Projekty2/FreePascalManager/trunk/Instance/1/FPC/rtl/inc/systemh.inc"/> 321 <EditorIndex Value=" 10"/>319 <EditorIndex Value="9"/> 322 320 <WindowIndex Value="0"/> 323 321 <TopLine Value="974"/> … … 328 326 <Unit33> 329 327 <Filename Value="../../../../Projekty2/FreePascalManager/trunk/Instance/1/FPC/rtl/i386/i386.inc"/> 330 <EditorIndex Value="1 1"/>328 <EditorIndex Value="10"/> 331 329 <WindowIndex Value="0"/> 332 330 <TopLine Value="1135"/> … … 336 334 </Unit33> 337 335 </Units> 338 <JumpHistory Count=" 30" HistoryIndex="29">336 <JumpHistory Count="14" HistoryIndex="13"> 339 337 <Position1> 340 <Filename Value="../U StackTrace.pas"/>341 <Caret Line=" 76" Column="60" TopLine="63"/>338 <Filename Value="../UMicroThreading.pas"/> 339 <Caret Line="854" Column="3" TopLine="847"/> 342 340 </Position1> 343 341 <Position2> 344 <Filename Value="../U StackTrace.pas"/>345 <Caret Line=" 74" Column="17" TopLine="63"/>342 <Filename Value="../UMicroThreading.pas"/> 343 <Caret Line="853" Column="41" TopLine="847"/> 346 344 </Position2> 347 345 <Position3> 348 <Filename Value="../U StackTrace.pas"/>349 <Caret Line=" 63" Column="27" TopLine="49"/>346 <Filename Value="../UMicroThreading.pas"/> 347 <Caret Line="854" Column="1" TopLine="847"/> 350 348 </Position3> 351 349 <Position4> 352 <Filename Value="../U StackTrace.pas"/>353 <Caret Line=" 79" Column="32" TopLine="64"/>350 <Filename Value="../UMicroThreading.pas"/> 351 <Caret Line="855" Column="1" TopLine="847"/> 354 352 </Position4> 355 353 <Position5> 356 <Filename Value="../U StackTrace.pas"/>357 <Caret Line=" 76" Column="66" TopLine="61"/>354 <Filename Value="../UMicroThreadCallStack.pas"/> 355 <Caret Line="67" Column="38" TopLine="46"/> 358 356 </Position5> 359 357 <Position6> 360 <Filename Value="../U StackTrace.pas"/>361 <Caret Line=" 74" Column="1" TopLine="61"/>358 <Filename Value="../UMicroThreadCallStack.pas"/> 359 <Caret Line="66" Column="19" TopLine="47"/> 362 360 </Position6> 363 361 <Position7> 364 <Filename Value="../U StackTrace.pas"/>365 <Caret Line=" 75" Column="1" TopLine="61"/>362 <Filename Value="../UMicroThreadCallStack.pas"/> 363 <Caret Line="67" Column="14" TopLine="47"/> 366 364 </Position7> 367 365 <Position8> 368 <Filename Value="../U StackTrace.pas"/>369 <Caret Line=" 76" Column="1" TopLine="61"/>366 <Filename Value="../UMicroThreadCallStack.pas"/> 367 <Caret Line="66" Column="22" TopLine="44"/> 370 368 </Position8> 371 369 <Position9> 372 <Filename Value="../U StackTrace.pas"/>373 <Caret Line=" 74" Column="1" TopLine="61"/>370 <Filename Value="../UMicroThreadList.pas"/> 371 <Caret Line="138" Column="10" TopLine="121"/> 374 372 </Position9> 375 373 <Position10> 376 <Filename Value=" ../UStackTrace.pas"/>377 <Caret Line=" 75" Column="1" TopLine="61"/>374 <Filename Value="UMainForm.pas"/> 375 <Caret Line="428" Column="43" TopLine="411"/> 378 376 </Position10> 379 377 <Position11> 380 <Filename Value=" ../UMicroThreading.pas"/>381 <Caret Line=" 854" Column="3" TopLine="847"/>378 <Filename Value="UMainForm.pas"/> 379 <Caret Line="116" Column="33" TopLine="103"/> 382 380 </Position11> 383 381 <Position12> 384 <Filename Value=" ../UMicroThreading.pas"/>385 <Caret Line=" 853" Column="41" TopLine="847"/>382 <Filename Value="UMainForm.pas"/> 383 <Caret Line="305" Column="44" TopLine="284"/> 386 384 </Position12> 387 385 <Position13> 388 <Filename Value=" ../UMicroThreading.pas"/>389 <Caret Line=" 854" Column="1" TopLine="847"/>386 <Filename Value="UMainForm.pas"/> 387 <Caret Line="399" Column="54" TopLine="378"/> 390 388 </Position13> 391 389 <Position14> 392 <Filename Value=" ../UMicroThreading.pas"/>393 <Caret Line=" 855" Column="1" TopLine="847"/>390 <Filename Value="UMainForm.pas"/> 391 <Caret Line="428" Column="54" TopLine="407"/> 394 392 </Position14> 395 <Position15>396 <Filename Value="../UStackTrace.pas"/>397 <Caret Line="74" Column="1" TopLine="61"/>398 </Position15>399 <Position16>400 <Filename Value="../UStackTrace.pas"/>401 <Caret Line="75" Column="1" TopLine="61"/>402 </Position16>403 <Position17>404 <Filename Value="../UStackTrace.pas"/>405 <Caret Line="76" Column="1" TopLine="61"/>406 </Position17>407 <Position18>408 <Filename Value="../UStackTrace.pas"/>409 <Caret Line="74" Column="1" TopLine="61"/>410 </Position18>411 <Position19>412 <Filename Value="../UStackTrace.pas"/>413 <Caret Line="75" Column="50" TopLine="61"/>414 </Position19>415 <Position20>416 <Filename Value="../UStackTrace.pas"/>417 <Caret Line="74" Column="45" TopLine="61"/>418 </Position20>419 <Position21>420 <Filename Value="../UStackTrace.pas"/>421 <Caret Line="73" Column="29" TopLine="61"/>422 </Position21>423 <Position22>424 <Filename Value="../UStackTrace.pas"/>425 <Caret Line="76" Column="1" TopLine="61"/>426 </Position22>427 <Position23>428 <Filename Value="../UStackTrace.pas"/>429 <Caret Line="91" Column="1" TopLine="78"/>430 </Position23>431 <Position24>432 <Filename Value="../UMicroThreadCallStack.pas"/>433 <Caret Line="67" Column="38" TopLine="46"/>434 </Position24>435 <Position25>436 <Filename Value="../UStackTrace.pas"/>437 <Caret Line="76" Column="1" TopLine="63"/>438 </Position25>439 <Position26>440 <Filename Value="../UStackTrace.pas"/>441 <Caret Line="78" Column="1" TopLine="63"/>442 </Position26>443 <Position27>444 <Filename Value="../UMicroThreadCallStack.pas"/>445 <Caret Line="66" Column="19" TopLine="47"/>446 </Position27>447 <Position28>448 <Filename Value="../UMicroThreadCallStack.pas"/>449 <Caret Line="67" Column="14" TopLine="47"/>450 </Position28>451 <Position29>452 <Filename Value="../UMicroThreadCallStack.pas"/>453 <Caret Line="66" Column="22" TopLine="44"/>454 </Position29>455 <Position30>456 <Filename Value="../UMicroThreadList.pas"/>457 <Caret Line="138" Column="10" TopLine="121"/>458 </Position30>459 393 </JumpHistory> 460 394 </ProjectOptions> -
MicroThreading/Demo/UMainForm.pas
r166 r169 303 303 procedure TMainForm.CheckBox4Change(Sender: TObject); 304 304 begin 305 CriticalSectionSleepDuration := SpinEdit 4.Value;305 CriticalSectionSleepDuration := SpinEdit6.Value; 306 306 DoCriticalSection := CheckBox4.Checked; 307 307 end; -
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.