Changeset 166 for MicroThreading
- Timestamp:
- Feb 9, 2011, 1:35:28 PM (14 years ago)
- Location:
- MicroThreading
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/Demo/Demo.lpi
r164 r166 59 59 <ResourceBaseClass Value="Form"/> 60 60 <UnitName Value="UMainForm"/> 61 <IsVisibleTab Value="True"/>62 61 <EditorIndex Value="9"/> 63 62 <WindowIndex Value="0"/> 64 <TopLine Value="3 32"/>65 <CursorPos X="2 3" Y="342"/>63 <TopLine Value="393"/> 64 <CursorPos X="29" Y="406"/> 66 65 <UsageCount Value="270"/> 67 66 <Loaded Value="True"/> … … 71 70 <Filename Value="../UMicroThreading.pas"/> 72 71 <UnitName Value="UMicroThreading"/> 72 <IsVisibleTab Value="True"/> 73 73 <EditorIndex Value="0"/> 74 74 <WindowIndex Value="0"/> 75 <TopLine Value="9 86"/>76 <CursorPos X="1 9" Y="1000"/>75 <TopLine Value="914"/> 76 <CursorPos X="11" Y="928"/> 77 77 <UsageCount Value="136"/> 78 78 <Loaded Value="True"/> … … 130 130 <TopLine Value="25"/> 131 131 <CursorPos X="41" Y="39"/> 132 <UsageCount Value="3 7"/>132 <UsageCount Value="38"/> 133 133 <Loaded Value="True"/> 134 134 </Unit9> … … 142 142 <TopLine Value="53"/> 143 143 <CursorPos X="61" Y="61"/> 144 <UsageCount Value="2 3"/>144 <UsageCount Value="24"/> 145 145 <Loaded Value="True"/> 146 146 <LoadedDesigner Value="True"/> … … 245 245 <TopLine Value="35"/> 246 246 <CursorPos X="18" Y="45"/> 247 <UsageCount Value="1 2"/>247 <UsageCount Value="13"/> 248 248 <Loaded Value="True"/> 249 249 </Unit24> … … 254 254 <TopLine Value="548"/> 255 255 <CursorPos X="1" Y="561"/> 256 <UsageCount Value="1 1"/>256 <UsageCount Value="12"/> 257 257 <Loaded Value="True"/> 258 258 </Unit25> … … 263 263 <TopLine Value="798"/> 264 264 <CursorPos X="1" Y="821"/> 265 <UsageCount Value="1 1"/>265 <UsageCount Value="12"/> 266 266 <Loaded Value="True"/> 267 267 </Unit26> … … 272 272 <TopLine Value="65"/> 273 273 <CursorPos X="29" Y="75"/> 274 <UsageCount Value="1 1"/>274 <UsageCount Value="12"/> 275 275 <Loaded Value="True"/> 276 276 </Unit27> … … 282 282 <TopLine Value="1398"/> 283 283 <CursorPos X="15" Y="1309"/> 284 <UsageCount Value="1 0"/>284 <UsageCount Value="11"/> 285 285 <Loaded Value="True"/> 286 286 </Unit28> … … 291 291 <TopLine Value="2161"/> 292 292 <CursorPos X="33" Y="2161"/> 293 <UsageCount Value="1 0"/>293 <UsageCount Value="11"/> 294 294 <Loaded Value="True"/> 295 295 </Unit29> … … 297 297 <JumpHistory Count="30" HistoryIndex="29"> 298 298 <Position1> 299 <Filename Value=" UMainForm.pas"/>300 <Caret Line=" 374" Column="21" TopLine="368"/>299 <Filename Value="../UMicroThreading.pas"/> 300 <Caret Line="939" Column="1" TopLine="932"/> 301 301 </Position1> 302 302 <Position2> 303 <Filename Value=" UMainForm.pas"/>304 <Caret Line=" 373" Column="21" TopLine="367"/>303 <Filename Value="../UMicroThreading.pas"/> 304 <Caret Line="940" Column="1" TopLine="932"/> 305 305 </Position2> 306 306 <Position3> 307 <Filename Value=" UMainForm.pas"/>308 <Caret Line=" 372" Column="21" TopLine="366"/>307 <Filename Value="../UMicroThreading.pas"/> 308 <Caret Line="941" Column="1" TopLine="932"/> 309 309 </Position3> 310 310 <Position4> 311 <Filename Value="../UMicroThread List.pas"/>312 <Caret Line="94 " Column="84" TopLine="83"/>311 <Filename Value="../UMicroThreading.pas"/> 312 <Caret Line="942" Column="1" TopLine="932"/> 313 313 </Position4> 314 314 <Position5> 315 <Filename Value="../UMicroThread List.pas"/>316 <Caret Line=" 17" Column="7" TopLine="4"/>315 <Filename Value="../UMicroThreading.pas"/> 316 <Caret Line="944" Column="1" TopLine="932"/> 317 317 </Position5> 318 318 <Position6> 319 <Filename Value="../UMicroThread List.pas"/>320 <Caret Line=" 15" Column="38" TopLine="7"/>319 <Filename Value="../UMicroThreading.pas"/> 320 <Caret Line="946" Column="1" TopLine="932"/> 321 321 </Position6> 322 322 <Position7> 323 <Filename Value="../UMicroThread List.pas"/>324 <Caret Line=" 17" Column="12" TopLine="4"/>323 <Filename Value="../UMicroThreading.pas"/> 324 <Caret Line="937" Column="1" TopLine="932"/> 325 325 </Position7> 326 326 <Position8> 327 <Filename Value="../UMicroThread List.pas"/>328 <Caret Line=" 18" Column="12" TopLine="4"/>327 <Filename Value="../UMicroThreading.pas"/> 328 <Caret Line="938" Column="1" TopLine="932"/> 329 329 </Position8> 330 330 <Position9> 331 <Filename Value="../UMicroThread List.pas"/>332 <Caret Line=" 19" Column="12" TopLine="4"/>331 <Filename Value="../UMicroThreading.pas"/> 332 <Caret Line="846" Column="1" TopLine="833"/> 333 333 </Position9> 334 334 <Position10> 335 <Filename Value="../UMicroThread List.pas"/>336 <Caret Line=" 20" Column="12" TopLine="4"/>335 <Filename Value="../UMicroThreading.pas"/> 336 <Caret Line="859" Column="1" TopLine="837"/> 337 337 </Position10> 338 338 <Position11> 339 <Filename Value="../UMicroThread List.pas"/>340 <Caret Line=" 21" Column="12" TopLine="4"/>339 <Filename Value="../UMicroThreading.pas"/> 340 <Caret Line="847" Column="1" TopLine="837"/> 341 341 </Position11> 342 342 <Position12> 343 <Filename Value="../UMicroThread List.pas"/>344 <Caret Line=" 22" Column="12" TopLine="4"/>343 <Filename Value="../UMicroThreading.pas"/> 344 <Caret Line="848" Column="1" TopLine="837"/> 345 345 </Position12> 346 346 <Position13> 347 <Filename Value=" UMainForm.pas"/>348 <Caret Line=" 372" Column="21" TopLine="26"/>347 <Filename Value="../UMicroThreading.pas"/> 348 <Caret Line="849" Column="1" TopLine="837"/> 349 349 </Position13> 350 350 <Position14> 351 <Filename Value="../UMicroThread List.pas"/>352 <Caret Line=" 23" Column="12" TopLine="13"/>351 <Filename Value="../UMicroThreading.pas"/> 352 <Caret Line="850" Column="1" TopLine="837"/> 353 353 </Position14> 354 354 <Position15> 355 <Filename Value="../UMicroThread List.pas"/>356 <Caret Line=" 68" Column="3" TopLine="53"/>355 <Filename Value="../UMicroThreading.pas"/> 356 <Caret Line="851" Column="1" TopLine="837"/> 357 357 </Position15> 358 358 <Position16> 359 <Filename Value="../UMicroThread List.pas"/>360 <Caret Line=" 69" Column="1" TopLine="53"/>359 <Filename Value="../UMicroThreading.pas"/> 360 <Caret Line="852" Column="1" TopLine="837"/> 361 361 </Position16> 362 362 <Position17> 363 <Filename Value=" UMainForm.pas"/>364 <Caret Line="85 " Column="15" TopLine="69"/>363 <Filename Value="../UMicroThreading.pas"/> 364 <Caret Line="853" Column="1" TopLine="837"/> 365 365 </Position17> 366 366 <Position18> 367 <Filename Value="../UMicroThread List.pas"/>368 <Caret Line=" 9" Column="43" TopLine="1"/>367 <Filename Value="../UMicroThreading.pas"/> 368 <Caret Line="854" Column="1" TopLine="837"/> 369 369 </Position18> 370 370 <Position19> 371 <Filename Value="../UMicroThread List.pas"/>372 <Caret Line=" 72" Column="1" TopLine="53"/>371 <Filename Value="../UMicroThreading.pas"/> 372 <Caret Line="857" Column="1" TopLine="837"/> 373 373 </Position19> 374 374 <Position20> 375 375 <Filename Value="../UMicroThreading.pas"/> 376 <Caret Line=" 1006" Column="18" TopLine="991"/>376 <Caret Line="858" Column="1" TopLine="837"/> 377 377 </Position20> 378 378 <Position21> 379 379 <Filename Value="../UMicroThreading.pas"/> 380 <Caret Line=" 1010" Column="26" TopLine="991"/>380 <Caret Line="859" Column="1" TopLine="837"/> 381 381 </Position21> 382 382 <Position22> 383 383 <Filename Value="../UMicroThreading.pas"/> 384 <Caret Line=" 1009" Column="22" TopLine="991"/>384 <Caret Line="939" Column="1" TopLine="926"/> 385 385 </Position22> 386 386 <Position23> 387 387 <Filename Value="../UMicroThreading.pas"/> 388 <Caret Line=" 1004" Column="43" TopLine="991"/>388 <Caret Line="940" Column="1" TopLine="926"/> 389 389 </Position23> 390 390 <Position24> 391 <Filename Value=" UMainForm.pas"/>392 <Caret Line=" 337" Column="23" TopLine="327"/>391 <Filename Value="../UMicroThreading.pas"/> 392 <Caret Line="941" Column="1" TopLine="926"/> 393 393 </Position24> 394 394 <Position25> 395 <Filename Value=" UMainForm.pas"/>396 <Caret Line=" 338" Column="23" TopLine="328"/>395 <Filename Value="../UMicroThreading.pas"/> 396 <Caret Line="942" Column="1" TopLine="926"/> 397 397 </Position25> 398 398 <Position26> 399 <Filename Value=" UMainForm.pas"/>400 <Caret Line=" 339" Column="23" TopLine="329"/>399 <Filename Value="../UMicroThreading.pas"/> 400 <Caret Line="938" Column="45" TopLine="926"/> 401 401 </Position26> 402 402 <Position27> 403 <Filename Value=" UMainForm.pas"/>404 <Caret Line=" 338" Column="23" TopLine="328"/>403 <Filename Value="../UMicroThreading.pas"/> 404 <Caret Line="940" Column="1" TopLine="914"/> 405 405 </Position27> 406 406 <Position28> 407 <Filename Value=" UMainForm.pas"/>408 <Caret Line=" 339" Column="23" TopLine="329"/>407 <Filename Value="../UMicroThreading.pas"/> 408 <Caret Line="901" Column="32" TopLine="888"/> 409 409 </Position28> 410 410 <Position29> 411 <Filename Value=" UMainForm.pas"/>412 <Caret Line=" 340" Column="23" TopLine="330"/>411 <Filename Value="../UMicroThreading.pas"/> 412 <Caret Line="236" Column="43" TopLine="236"/> 413 413 </Position29> 414 414 <Position30> 415 <Filename Value=" UMainForm.pas"/>416 <Caret Line=" 341" Column="23" TopLine="331"/>415 <Filename Value="../UMicroThreading.pas"/> 416 <Caret Line="926" Column="22" TopLine="913"/> 417 417 </Position30> 418 418 </JumpHistory> … … 455 455 </CompilerOptions> 456 456 <Debugging> 457 <BreakPoints Count="3">458 <Item1>459 <Source Value="../UMicroThreading.pas"/>460 <Line Value="280"/>461 </Item1>462 <Item2>463 <Source Value="../../../../Programy/Lazarus/0.9.31_2.4.3/fpc/2.4.3/source/rtl/win/sysutils.pp"/>464 <Line Value="1036"/>465 </Item2>466 <Item3>467 <Source Value="../UMicroThreading.pas"/>468 <Line Value="321"/>469 </Item3>470 </BreakPoints>471 457 <Watches Count="2"> 472 458 <Item1> -
MicroThreading/Demo/UMainForm.lfm
r164 r166 17 17 Top = 8 18 18 Width = 802 19 ActivePage = TabSheet 219 ActivePage = TabSheet1 20 20 Anchors = [akTop, akLeft, akRight, akBottom] 21 TabIndex = 021 TabIndex = 1 22 22 TabOrder = 0 23 23 object TabSheet2: TTabSheet … … 107 107 object TabSheet1: TTabSheet 108 108 Caption = 'Job control' 109 ClientHeight = 4 93109 ClientHeight = 474 110 110 ClientWidth = 794 111 111 object ButtonAddWorkers: TButton … … 113 113 Height = 25 114 114 Top = 7 115 Width = 1 04115 Width = 120 116 116 Caption = 'Add workers' 117 117 OnClick = ButtonAddWorkersClick … … 128 128 end 129 129 object Label4: TLabel 130 Left = 1 24130 Left = 140 131 131 Height = 14 132 132 Top = 14 … … 148 148 object Memo1: TMemo 149 149 Left = 316 150 Height = 2 44150 Height = 225 151 151 Top = 14 152 152 Width = 294 … … 165 165 end 166 166 object Label12: TLabel 167 Left = 1 23167 Left = 140 168 168 Height = 14 169 169 Top = 38 … … 299 299 ParentColor = False 300 300 end 301 end 302 object Button6: TButton 303 Left = 9 304 Height = 25 305 Top = 38 306 Width = 121 307 Caption = 'Add method workers' 308 OnClick = Button6Click 309 TabOrder = 7 301 310 end 302 311 end -
MicroThreading/Demo/UMainForm.pas
r164 r166 33 33 Button4: TButton; 34 34 Button5: TButton; 35 Button6: TButton; 35 36 ButtonAddWorkers: TButton; 36 37 ButtonClearMicroThreads: TButton; … … 77 78 procedure Button4Click(Sender: TObject); 78 79 procedure Button5Click(Sender: TObject); 80 procedure Button6Click(Sender: TObject); 79 81 procedure ButtonSchedulerStartStopClick(Sender: TObject); 80 82 procedure Button2Click(Sender: TObject); … … 105 107 procedure ShowException(Sender: TObject; E: Exception); 106 108 procedure DoShowException; 109 procedure MethodWorker; 107 110 public 108 111 DoWriteToMemo: Boolean; … … 171 174 begin 172 175 RaiseException := True; 176 end; 177 178 procedure TMainForm.Button6Click(Sender: TObject); 179 var 180 I: Integer; 181 begin 182 //Scheduler.FMicroThreads.Clear; 183 for I := 0 to SpinEdit1.Value - 1 do begin 184 MainScheduler.AddMethod(MethodWorker, False); 185 end; 173 186 end; 174 187 … … 363 376 ShowMessage('Exception "' + LastException.Message + '" in class "' + 364 377 LastExceptionSender.ClassName + '"') 378 end; 379 380 procedure TMainForm.MethodWorker; 381 var 382 I: Integer; 383 Q: Integer; 384 begin 385 for I := 0 to MainForm.Iterations - 1 do begin 386 Q := 0; 387 while Q < 100000 do Inc(Q); 388 if MainForm.DoWriteToMemo then 389 MainForm.Memo1.Lines.Add(IntToStr(GetCurrentMicroThread.Id) + ': ' + IntToStr(Trunc(GetCurrentMicroThread.Completion * 100)) + ' %'); 390 if MainForm.DoWaitForEvent then MainForm.Event.WaitFor(MainForm.WaitForEventDuration * OneMillisecond); 391 if MainForm.DoSleep then MTSleep(MainForm.SleepDuration * OneMillisecond); 392 if MainForm.RaiseException then begin 393 MainForm.RaiseException := False; 394 raise Exception.Create('Exception from microthread'); 395 end; 396 if MainForm.DoCriticalSection then begin 397 try 398 MainForm.Lock.Acquire; 399 MTSleep(MainForm.CriticalSectionSleepDuration * OneMillisecond); 400 finally 401 MainForm.Lock.Release; 402 end; 403 end; 404 //WorkerSubRoutine; 405 GetCurrentMicroThread.Completion := I / MainForm.Iterations; 406 GetCurrentMicroThread.Yield; 407 end; 365 408 end; 366 409 -
MicroThreading/UMicroThreading.pas
r164 r166 32 32 SManagerReferenceLost = 'Reference to manager lost'; 33 33 SCantDetermineThreadID = 'Can''t determine thread for id %d'; 34 SNotInThread = 'Not in thread'; 35 SReleaseNotAcquiredLock = 'Release not acquired lock'; 34 SNotInMicroThread = 'Not in microthread'; 35 SReleaseNotAcquiredLock = 'Release on not acquired lock'; 36 SMethodNotAssigned = 'Method for microthread not assigned'; 36 37 37 38 38 39 type 40 EMicroThreadError = class(Exception); 41 39 42 TMicroThread = class; 40 43 TMicroThreadScheduler = class; … … 43 46 TMicroThreadState = (tsNone, tsWaiting, tsRunning, tsBlocked, tsSuspended); 44 47 TMicroThreadBlockState = (tbsNone, tbsSleeping, tbsWaitFor, tbsTerminating, 45 tbsTerminated );48 tbsTerminated, tbsCriticalSection); 46 49 47 50 { TMicroThreadCriticalSection } 48 51 49 52 TMicroThreadCriticalSection = class 53 private 54 FMicroThreads: TObjectList; 50 55 Lock: TCriticalSection; 51 Counter: Integer; 56 FCounter: Integer; 57 public 52 58 procedure Acquire; 53 59 procedure Release; … … 111 117 procedure Yield; 112 118 procedure MTSleep(Duration: TDateTime); // No conflicting name to global Sleep procedure 119 procedure WaitForCriticalSection(CriticalSection: TMicroThreadCriticalSection); 113 120 function WaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult; 114 121 procedure WaitFor; … … 141 148 142 149 TMicroThreadSimple = class(TMicroThread) 143 Method: T MicroThreadMethod;150 Method: TProcedureOfObject; 144 151 procedure Execute; override; 145 152 end; … … 228 235 BurstCount: Integer; 229 236 function Add(MicroThread: TMicroThread): Integer; 230 function AddMethod(Method: T MicroThreadMethod): Integer;237 function AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean = False): Integer; 231 238 procedure Remove(MicroThread: TMicroThread; Free: Boolean = True); 232 239 constructor Create; … … 263 270 'Running', 'Blocked', 'Suspended'); 264 271 MicroThreadBlockStateText: array[TMicroThreadBlockState] of string = ('None', 265 'Sleeping', 'WaitFor', 'Terminating', 'Terminated' );272 'Sleeping', 'WaitFor', 'Terminating', 'Terminated', 'CriticalSection'); 266 273 MicroThreadThreadStateText: array[TMicroThreadThreadState] of string = ( 267 274 'Ready', 'Running', 'Terminated'); … … 294 301 begin 295 302 MT := GetCurrentMicroThread; 296 if Assigned(MT) then Result := MT.Id else Result := -1; 303 if Assigned(MT) then Result := MT.Id 304 else Result := -1; 297 305 end; 298 306 … … 322 330 MT := GetCurrentMicroThread; 323 331 if Assigned(MT) then MT.MTSleep(Duration) 324 else Sleep(Trunc(Duration / OneMillisecond));332 else raise EMicroThreadError.Create(SNotInMicroThread); 325 333 end; 326 334 … … 332 340 Thread := TThreadEx.CurrentThread; 333 341 if Assigned(Thread) then TThread.Synchronize(Thread, Method) 334 else raise E xception.Create(Format(SCantDetermineThreadID, [GetCurrentThreadId]));342 else raise EMicroThreadError.Create(Format(SCantDetermineThreadID, [GetCurrentThreadId])); 335 343 end else Method; 336 344 end; … … 342 350 MT := GetCurrentMicroThread; 343 351 if Assigned(MT) then Result := MT.WaitForEvent(Event, Duration) 344 else begin 345 while not Event.Signaled do begin 346 Sleep(1); 347 Application.ProcessMessages; 348 end; 349 //raise Exception.Create(SNotInThread); 350 // else Result := Event.WaitFor(Trunc(Duration / OneMillisecond)); 351 end; 352 else raise EMicroThreadError.Create(SNotInMicroThread); 352 353 end; 353 354 … … 374 375 375 376 procedure TMicroThreadCriticalSection.Acquire; 376 begin 377 try 377 var 378 MT: TMicroThread; 379 Event: TMicroThreadEvent; 380 begin 381 MT := GetCurrentMicroThread; 382 if Assigned(MT) then MT.WaitForCriticalSection(Self) 383 else raise EMicroThreadError.Create(SNotInMicroThread); 384 end; 385 386 procedure TMicroThreadCriticalSection.Release; 387 begin 388 try 389 MainScheduler.FMicroThreadsLock.Acquire; 378 390 Lock.Acquire; 379 while Counter > 0 do begin 380 try 381 Lock.Release; 382 MTSleep(1 * OneMillisecond); 383 finally 384 Lock.Acquire; 385 end; 386 end; 387 Inc(Counter); 391 Dec(FCounter); 392 if FMicroThreads.Count > 0 then begin 393 // Release one waiting micro thread and lower counter 394 TMicroThread(FMicroThreads[0]).FState := tsWaiting; 395 FMicroThreads.Delete(0); 396 end; 388 397 finally 389 398 Lock.Release; 390 end; 391 end; 392 393 procedure TMicroThreadCriticalSection.Release; 394 begin 395 try 399 MainScheduler.FMicroThreadsLock.Release; 400 end; 401 end; 402 403 constructor TMicroThreadCriticalSection.Create; 404 begin 405 Lock := TCriticalSection.Create; 406 FMicroThreads := TObjectList.Create; 407 FMicroThreads.OwnsObjects := False; 408 end; 409 410 destructor TMicroThreadCriticalSection.Destroy; 411 begin 412 try 413 MainScheduler.FMicroThreadsLock.Acquire; 396 414 Lock.Acquire; 397 if Counter > 0 then Dec(Counter) 398 else raise Exception.Create(SReleaseNotAcquiredLock); 415 416 while FMicroThreads.Count > 0 do begin 417 // Release one waiting micro thread and lower counter 418 TMicroThread(FMicroThreads[0]).FState := tsWaiting; 419 FMicroThreads.Delete(0); 420 end; 399 421 finally 400 422 Lock.Release; 401 end; 402 end; 403 404 constructor TMicroThreadCriticalSection.Create; 405 begin 406 Lock := TCriticalSection.Create; 407 end; 408 409 destructor TMicroThreadCriticalSection.Destroy; 410 begin 411 Acquire; 423 MainScheduler.FMicroThreadsLock.Release; 424 end; 425 FMicroThreads.Free; 412 426 Lock.Free; 413 427 inherited Destroy; … … 456 470 MT := GetCurrentMicroThread; 457 471 if Assigned(MT) then Result := MT.WaitForEvent(Self, Duration) 458 else Result := wrSignaled;472 else raise EMicroThreadError.Create(SNotInMicroThread); 459 473 end; 460 474 … … 689 703 begin 690 704 inherited Execute; 691 Method(Self); 705 if Assigned(Method) then Method 706 else raise EMicroThreadError.Create(SMethodNotAssigned); 692 707 end; 693 708 … … 700 715 except 701 716 on E: Exception do 702 if Assigned(ExceptionHandler) then ExceptionHandler(Self, E); 717 if Assigned(ExceptionHandler) then 718 if GetCurrentThreadId = MainThreadID then ExceptionHandler(Self, E) 719 else ExceptionHandler(TThreadEx.CurrentThread, E); 703 720 end; 704 721 asm … … 745 762 procedure TMicroThread.Yield; 746 763 begin 747 if not Assigned(FManager) then748 raise Exception.Create(SManagerReferenceLost);764 // if not Assigned(FManager) then 765 // raise EMicroThreadError.Create(SManagerReferenceLost); 749 766 if FStatePending = tsNone then 750 767 FStatePending := tsWaiting; … … 774 791 FStatePending := tsBlocked; 775 792 Yield; 793 end; 794 795 procedure TMicroThread.WaitForCriticalSection( 796 CriticalSection: TMicroThreadCriticalSection); 797 begin 798 try 799 CriticalSection.Lock.Acquire; 800 Inc(CriticalSection.FCounter); 801 if CriticalSection.FCounter > 1 then begin 802 CriticalSection.FMicroThreads.Add(Self); 803 FBlockState := tbsCriticalSection; 804 FStatePending := tsBlocked; 805 try 806 CriticalSection.Lock.Release; 807 Yield; 808 finally 809 CriticalSection.Lock.Acquire; 810 end; 811 end; 812 finally 813 CriticalSection.Lock.Release; 814 end; 776 815 end; 777 816 … … 862 901 function TMicroThreadScheduler.Add(MicroThread: TMicroThread): Integer; 863 902 begin 864 Inc(FLastId);865 MicroThread.FScheduler := Self;866 MicroThread.FId := FLastId;867 903 try 868 904 FMicroThreadsLock.Acquire; 905 Inc(FLastId); 906 MicroThread.FScheduler := Self; 907 MicroThread.FId := FLastId; 869 908 Result := FMicroThreads.Add(MicroThread); 870 909 finally … … 873 912 end; 874 913 875 function TMicroThreadScheduler.AddMethod(Method: T MicroThreadMethod): Integer;914 function TMicroThreadScheduler.AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean): Integer; 876 915 var 877 916 NewMicroThread: TMicroThreadSimple; 878 begin 879 NewMicroThread := TMicroThreadSimple.Create(False); 880 NewMicroThread.Method := Method; 881 NewMicroThread.FScheduler := Self; 882 Result := Add(NewMicroThread); 917 CurrentMT: TMicroThread; 918 begin 919 try 920 NewMicroThread := TMicroThreadSimple.Create(False); 921 NewMicroThread.Method := Method; 922 NewMicroThread.FScheduler := Self; 923 NewMicroThread.FreeOnTerminate := not WaitForFinish; 924 if WaitForFinish then begin 925 CurrentMT := GetCurrentMicroThread; 926 while not ((NewMicroThread.FState = tsBlocked) and 927 (NewMicroThread.FBlockState = tbsTerminated)) do begin 928 try 929 FMicroThreadsLock.Release; 930 if Assigned(CurrentMT) then CurrentMT.MTSleep(1 * OneMillisecond) 931 else begin 932 Sleep(1); 933 Application.ProcessMessages; 934 end; 935 finally 936 FMicroThreadsLock.Acquire; 937 end; 938 end; 939 end; 940 finally 941 if WaitForFinish then NewMicroThread.Free; 942 end; 883 943 end; 884 944 … … 1066 1126 end; 1067 1127 if I < FMicroThreads.Count then begin 1068 if Assigned(Manager.FCurrentMicroThread) then1069 raise Exception.Create(SManagerMicroThreadRunning);1128 // if Assigned(Manager.FCurrentMicroThread) then 1129 // raise EMicroThreadError.Create(SManagerMicroThreadRunning); 1070 1130 Selected := TMicroThread(FMicroThreads[FRoundRobinIndex]); 1071 1131 Selected.FState := tsRunning; … … 1080 1140 procedure TMicroThreadScheduler.ReleaseMicroThread(MicroThread: TMicroThread); 1081 1141 begin 1082 if not Assigned(MicroThread) then1083 raise Exception.Create(SNilThreadReference);1142 // if not Assigned(MicroThread) then 1143 // raise EMicroThreadError.Create(SNilThreadReference); 1084 1144 try 1085 1145 FMicroThreadsLock.Acquire;
Note:
See TracChangeset
for help on using the changeset viewer.