Changeset 154 for MicroThreading/UMicroThreading.pas
- Timestamp:
- Jan 27, 2011, 2:15:57 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/UMicroThreading.pas
r153 r154 30 30 TMicroThreadState = (tsWaiting, tsRunning, tsBlocked, tsSuspended, 31 31 tsSleeping); 32 33 { TMicroThreadEvent } 34 35 TMicroThreadEvent = class 36 private 37 FAutoReset: Boolean; 38 FSignaled: Boolean; 39 FMicroThreads: TObjectList; 40 FMicroThreadsLock: TCriticalSection; 41 public 42 procedure SetEvent; 43 procedure ResetEvent; 44 procedure WaitFor(Duration: TDateTime); 45 constructor Create; 46 destructor Destroy; override; 47 property Signaled: Boolean read FSignaled; 48 property AutoReset: Boolean read FAutoReset write FAutoReset; 49 end; 32 50 33 51 { TMicroThread } … … 48 66 FFinished: Boolean; 49 67 FSuspended: Boolean; 68 FBlocked: Boolean; 50 69 FState: TMicroThreadState; 51 70 FScheduler: TMicroThreadScheduler; 52 71 FManager: TMicroThreadManager; 53 72 FId: Integer; 73 FBlockCondition: Boolean; 54 74 procedure CallExecute; 55 75 function GetStackUsed: Integer; … … 58 78 Name: string; 59 79 Priority: Integer; 60 Completion: Single; // Can be used for progress information in range <0, 1>80 Completion: Single; // Can be used for progress information usually in range <0, 1> 61 81 procedure Execute; virtual; 62 82 63 83 procedure Yield; 64 procedure Sleep(Duration: TDateTime);65 function WaitFor Signal(Signal: TEvent): TWaitResult;84 procedure MTSleep(Duration: TDateTime); // No conflicting name to global Sleep procedure 85 function WaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult; 66 86 procedure WaitFor; 67 87 procedure Terminate; … … 86 106 end; 87 107 88 TMicroThread Event= procedure(MicroThread: TMicroThread) of object;89 90 { TMicroThread Method}91 92 TMicroThread Method= class(TMicroThread)93 Method: TMicroThread Event;108 TMicroThreadMethod = procedure(MicroThread: TMicroThread) of object; 109 110 { TMicroThreadSimple } 111 112 TMicroThreadSimple = class(TMicroThread) 113 Method: TMicroThreadMethod; 94 114 procedure Execute; override; 95 115 end; … … 166 186 public 167 187 function Add(MicroThread: TMicroThread): Integer; 168 function AddMethod(Method: TMicroThreadEvent): Integer; 188 function AddMethod(Method: TMicroThreadMethod): Integer; 189 procedure Remove(MicroThread: TMicroThread); 169 190 constructor Create; 170 191 destructor Destroy; override; … … 187 208 MicroThreadStateText: array[TMicroThreadState] of string = ('Waiting', 188 209 'Running', 'Blocked', 'Suspended', 'Sleeping'); 210 211 function GetCurrentMicroThread: TMicroThread; 212 procedure MTSleep(Duration: TDateTime); 213 function MTWaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult; 189 214 190 215 implementation … … 218 243 end; 219 244 end; 245 end; 246 247 function GetCurrentMicroThread: TMicroThread; 248 var 249 I: Integer; 250 begin 251 with MainScheduler do 252 try 253 FThreadPoolLock.Acquire; 254 if MainThreadID = ThreadID then Result := MainThreadManager.CurrentMicroThread 255 else begin 256 I := 0; 257 while (I < FThreadPool.Count) and (TMicroThreadThread(FThreadPool[I]).ThreadID <> ThreadID) do Inc(I); 258 if I < FThreadPool.Count then Result := TMicroThreadThread(FThreadPool[I]).Manager.CurrentMicroThread 259 else Result := nil; 260 end; 261 finally 262 FThreadPoolLock.Release; 263 end; 264 end; 265 266 procedure MTSleep(Duration: TDateTime); 267 var 268 MT: TMicroThread; 269 begin 270 MT := GetCurrentMicroThread; 271 if Assigned(MT) then MT.MTSleep(Duration) 272 else Sleep(Trunc(Duration / OneMillisecond)); 273 end; 274 275 function MTWaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult; 276 var 277 MT: TMicroThread; 278 begin 279 MT := GetCurrentMicroThread; 280 if Assigned(MT) then Result := MT.WaitForEvent(Event, Duration); 281 // else Result := Event.WaitFor(Trunc(Duration / OneMillisecond)); 282 end; 283 284 { TMicroThreadMethod } 285 286 procedure TMicroThreadEvent.SetEvent; 287 var 288 I: Integer; 289 begin 290 for I := 0 to FMicroThreads.Count - 1 do 291 TMicroThread(FMicroThreads[I]).FBlockCondition := True; 292 if not FAutoReset then FSignaled := True; 293 end; 294 295 procedure TMicroThreadEvent.ResetEvent; 296 begin 297 FSignaled := False; 298 end; 299 300 procedure TMicroThreadEvent.WaitFor(Duration: TDateTime); 301 var 302 MT: TMicroThread; 303 begin 304 MT := GetCurrentMicroThread; 305 if Assigned(MT) then MT.WaitForEvent(Self, Duration); 306 end; 307 308 constructor TMicroThreadEvent.Create; 309 begin 310 FMicroThreads := TObjectList.Create; 311 FMicroThreads.OwnsObjects := False; 312 FMicroThreadsLock := TCriticalSection.Create; 313 end; 314 315 destructor TMicroThreadEvent.Destroy; 316 begin 317 FMicroThreadsLock.Free; 318 FMicroThreads.Free; 319 inherited Destroy; 220 320 end; 221 321 … … 390 490 end; 391 491 392 { TMicroThread Method}393 394 procedure TMicroThread Method.Execute;492 { TMicroThreadSimple } 493 494 procedure TMicroThreadSimple.Execute; 395 495 begin 396 496 inherited Execute; … … 433 533 if GetMicroThreadId <> -1 then 434 534 while not FFinished do begin 435 Sleep(1);436 end; 437 end; 438 439 procedure TMicroThread. Sleep(Duration: TDateTime);535 MTSleep(1); 536 end; 537 end; 538 539 procedure TMicroThread.MTSleep(Duration: TDateTime); 440 540 begin 441 541 FWakeUpTime := NowPrecise + Duration; … … 444 544 end; 445 545 446 function TMicroThread.WaitForSignal(Signal: TEvent): TWaitResult; 447 begin 546 function TMicroThread.WaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult; 547 begin 548 try 549 Event.FMicroThreadsLock.Acquire; 550 Event.FMicroThreads.Add(Self); 551 finally 552 Event.FMicroThreadsLock.Release; 553 end; 554 FBlocked := True; 555 Yield; 448 556 repeat 449 Result := Signal.WaitFor(1); 450 Sleep(1); 557 if FState = tsBlocked then MTSleep(1); 451 558 until Result <> wrTimeout; 559 try 560 Event.FMicroThreadsLock.Acquire; 561 Event.FMicroThreads.Remove(Self); 562 finally 563 Event.FMicroThreadsLock.Release; 564 end; 452 565 end; 453 566 … … 520 633 end; 521 634 522 function TMicroThreadScheduler.AddMethod(Method: TMicroThread Event): Integer;523 var 524 NewMicroThread: TMicroThread Method;525 begin 526 NewMicroThread := TMicroThread Method.Create(False);635 function TMicroThreadScheduler.AddMethod(Method: TMicroThreadMethod): Integer; 636 var 637 NewMicroThread: TMicroThreadSimple; 638 begin 639 NewMicroThread := TMicroThreadSimple.Create(False); 527 640 NewMicroThread.Method := Method; 528 641 NewMicroThread.FScheduler := Self; 529 642 Result := Add(NewMicroThread); 643 end; 644 645 procedure TMicroThreadScheduler.Remove(MicroThread: TMicroThread); 646 begin 647 try 648 FMicroThreadsLock.Acquire; 649 FMicroThreads.Remove(MicroThread); 650 finally 651 FMicroThreadsLock.Release; 652 end; 530 653 end; 531 654 … … 664 787 if (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState = tsSleeping) and 665 788 (TMicroThread(FMicroThreads[FRoundRobinIndex]).FWakeupTime < CurrentTime) then 666 TMicroThread(FMicroThreads[FRoundRobinIndex]).FState := tsWaiting else 667 begin 789 TMicroThread(FMicroThreads[FRoundRobinIndex]).FState := tsWaiting 790 else 791 if (TMicroThread(FMicroThreads[FRoundRobinIndex]).FState = tsBlocked) and 792 (TMicroThread(FMicroThreads[FRoundRobinIndex]).FBlockCondition) then 793 TMicroThread(FMicroThreads[FRoundRobinIndex]).FState := tsWaiting 794 else begin 668 795 // Go to next thread 669 796 Inc(I); … … 748 875 initialization 749 876 750 //StaticManagers := TObjectList.Create; 751 //MainScheduler := TMicroThreadScheduler.Create; 877 MainScheduler := TMicroThreadScheduler.Create; 752 878 753 879 finalization 754 880 755 //MainScheduler.Free; 756 //StaticManagers.Free; 881 MainScheduler.Free; 757 882 758 883 end.
Note:
See TracChangeset
for help on using the changeset viewer.