Changeset 147 for MicroThreading/UMicroThreading.pas
- Timestamp:
- Jan 26, 2011, 8:06:25 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/UMicroThreading.pas
r146 r147 34 34 FStackSize: Integer; 35 35 FBasePointer: Pointer; 36 FWake upTime: TDateTime;36 FWakeUpTime: TDateTime; 37 37 FTerminated: Boolean; 38 38 FExecuted: Boolean; // At first go through Execute method, then switch context 39 39 FFinished: Boolean; 40 FSuspended: Boolean; 41 FState: TMicroThreadState; 42 FScheduler: TMicroThreadScheduler; 43 FManager: TMicroThreadManager; 44 FId: Integer; 40 45 public 41 Id: Integer;42 46 Name: string; 43 47 Priority: Integer; 44 State: TMicroThreadState;45 Manager: TMicroThreadManager;46 Scheduler: TMicroThreadScheduler;47 48 Completion: Single; // Can be used for progress information in range <0, 1> 48 49 procedure Execute; virtual; 49 50 50 // Internal execution51 51 procedure Yield; 52 52 procedure Sleep(Duration: TDateTime); 53 53 function WaitForSignal(Signal: TEvent): TWaitResult; 54 55 // External execution56 54 procedure WaitFor; 57 55 procedure Terminate; 58 56 procedure Start; 59 procedure Stop; 57 procedure Resume; 58 procedure Suspend; 60 59 61 60 constructor Create(CreateSuspended: Boolean; 62 61 const StackSize: SizeUInt = DefaultStackSize); 63 62 destructor Destroy; override; 63 property Id: Integer read FId; 64 property State: TMicroThreadState read FState; 64 65 property ExecutionTime: TDateTime read FExecutionTime; 65 66 property FreeOnTerminate: Boolean read FFreeOnTerminate 66 67 write FFreeOnTerminate; 67 68 property Terminated: Boolean read FTerminated; 69 property Scheduler: TMicroThreadScheduler read FScheduler; 70 property Manager: TMicroThreadManager read FManager; 68 71 end; 69 72 … … 80 83 81 84 TMicroThreadSchedulerPoolThread = class(TThread) 82 Scheduler: TMicroThreadScheduler;83 85 Manager: TMicroThreadManager; 84 86 procedure Execute; override; 87 constructor Create(CreateSuspended: Boolean; 88 const StackSize: SizeUInt = DefaultStackSize); 89 destructor Destroy; override; 85 90 end; 86 91 87 92 TThreadPool = class(TObjectList) 88 89 93 end; 90 94 … … 116 120 ThreadPool: TThreadPool; 117 121 RoundRobinIndex: Integer; 118 LastId: Integer;122 FLastId: Integer; 119 123 FFrequency: Int64; 120 FThreadPoolSize: Integer;121 124 FTerminated: Boolean; 122 125 function GetMicroThreadCount: Integer; … … 171 174 TMicroThread(MicroThreads[I]).FStackSize))) do Inc(I); 172 175 if I < MicroThreads.Count then begin 173 Result := TMicroThread(MicroThreads[I]). Id;176 Result := TMicroThread(MicroThreads[I]).FId; 174 177 end else Result := -1; 175 178 finally … … 194 197 var 195 198 I: Integer; 196 Time: TDateTime;197 begin 198 Time := Scheduler.GetNow;199 CurrentTime: TDateTime; 200 begin 201 CurrentTime := Scheduler.GetNow; 199 202 if Assigned(CurrentMicroThread) then begin 200 CurrentMicroThread.FExecutionEndTime := Time;203 CurrentMicroThread.FExecutionEndTime := CurrentTime; 201 204 CurrentMicroThread.FExecutionTime := CurrentMicroThread.FExecutionTime + 202 205 (CurrentMicroThread.FExecutionEndTime - CurrentMicroThread.FExecutionStartTime); 203 if CurrentMicroThread. State = tsRunning then204 CurrentMicroThread. State := tsWaiting;206 if CurrentMicroThread.FState = tsRunning then 207 CurrentMicroThread.FState := tsWaiting; 205 208 StaticMicroThread := CurrentMicroThread; 206 209 asm … … 212 215 mov [eax].TMicroThread.FBasePointer, edx 213 216 end; 214 StaticManager := CurrentMicroThread. Manager;217 StaticManager := CurrentMicroThread.FManager; 215 218 asm 216 219 // Restore scheduler stack … … 221 224 mov ebp, edx 222 225 end; 223 CurrentMicroThread. Manager := nil;226 CurrentMicroThread.FManager := nil; 224 227 CurrentMicroThread := nil; 225 228 end; … … 228 231 229 232 if Assigned(CurrentMicroThread) and (FExecutedCount < FExecuteCount) then begin 230 CurrentMicroThread. Manager := Self;233 CurrentMicroThread.FManager := Self; 231 234 Inc(FExecutedCount); 232 235 asm … … 240 243 if not CurrentMicroThread.FExecuted then begin 241 244 CurrentMicroThread.FExecuted := True; 242 CurrentMicroThread. State := tsRunning;243 CurrentMicroThread.FExecutionStartTime := Time;245 CurrentMicroThread.FState := tsRunning; 246 CurrentMicroThread.FExecutionStartTime := CurrentTime; 244 247 StaticMicroThread := CurrentMicroThread; 245 248 asm … … 257 260 end; 258 261 //FSelected.Method(FSelected); 259 StaticManager := CurrentMicroThread. Manager;262 StaticManager := CurrentMicroThread.FManager; 260 263 asm 261 264 // Restore scheduler stack … … 266 269 mov ebp, edx 267 270 end; 268 CurrentMicroThread. Manager := nil;269 CurrentMicroThread.FExecutionEndTime := Time;271 CurrentMicroThread.FManager := nil; 272 CurrentMicroThread.FExecutionEndTime := CurrentTime; 270 273 CurrentMicroThread.FExecutionTime := CurrentMicroThread.FExecutionTime + 271 274 (CurrentMicroThread.FExecutionEndTime - CurrentMicroThread.FExecutionStartTime); … … 285 288 if CurrentMicroThread.State = tsWaiting then begin 286 289 // Execute selected thread 287 CurrentMicroThread. State := tsRunning;288 CurrentMicroThread.FExecutionStartTime := Time;290 CurrentMicroThread.FState := tsRunning; 291 CurrentMicroThread.FExecutionStartTime := CurrentTime; 289 292 FTempPointer := CurrentMicroThread.FStackPointer; 290 293 asm … … 334 337 end; 335 338 339 constructor TMicroThreadSchedulerPoolThread.Create(CreateSuspended: Boolean; 340 const StackSize: SizeUInt); 341 begin 342 inherited; 343 Manager := TMicroThreadManager.Create; 344 end; 345 346 destructor TMicroThreadSchedulerPoolThread.Destroy; 347 begin 348 Manager.Free; 349 inherited Destroy; 350 end; 351 336 352 { TMicroThreadMethod } 337 353 … … 352 368 procedure TMicroThread.Yield; 353 369 begin 354 Manager.Yield;370 FManager.Yield; 355 371 end; 356 372 … … 365 381 procedure TMicroThread.Sleep(Duration: TDateTime); 366 382 begin 367 FWakeUpTime := Scheduler.GetNow + Duration;368 State := tsSleeping;383 FWakeUpTime := FScheduler.GetNow + Duration; 384 FState := tsSleeping; 369 385 Yield; 370 386 end; … … 387 403 FExecutionTime := 0; 388 404 FTerminated := False; 389 if CreateSuspended then 390 State := tsSuspended; 405 if CreateSuspended then begin 406 FState := tsSuspended; 407 FSuspended := True; 408 end else FSuspended := False; 391 409 FFreeOnTerminate := True; 392 410 end; … … 395 413 begin 396 414 FTerminated := True; 415 end; 416 417 procedure TMicroThread.Start; 418 begin 419 FState := tsWaiting; 397 420 end; 398 421 … … 405 428 end; 406 429 407 procedure TMicroThread.Start; 408 begin 409 State := tsWaiting; 410 end; 411 412 procedure TMicroThread.Stop; 413 begin 414 State := tsSuspended; 430 procedure TMicroThread.Resume; 431 begin 432 FSuspended := False; 433 if FState = tsSuspended then 434 FState := tsWaiting; 435 end; 436 437 procedure TMicroThread.Suspend; 438 begin 439 FSuspended := True; 440 //Yield; 415 441 end; 416 442 … … 440 466 function TMicroThreadScheduler.Add(MicroThread: TMicroThread): Integer; 441 467 begin 442 Inc( LastId);443 MicroThread. Scheduler := Self;444 MicroThread. Id :=LastId;468 Inc(FLastId); 469 MicroThread.FScheduler := Self; 470 MicroThread.FId := FLastId; 445 471 Result := MicroThreads.Add(MicroThread); 446 472 end; … … 452 478 NewMicroThread := TMicroThreadMethod.Create(False); 453 479 NewMicroThread.Method := Method; 454 NewMicroThread. Scheduler := Self;480 NewMicroThread.FScheduler := Self; 455 481 Result := Add(NewMicroThread); 456 482 end; … … 482 508 var 483 509 Executed: Integer; 510 I: Integer; 484 511 begin 485 512 FTerminated := False; 513 for I := 0 to ThreadPool.Count - 1 do 514 TMicroThreadSchedulerPoolThread(ThreadPool[I]).Start; 486 515 repeat 487 516 Executed := MainThreadManager.Execute(10); … … 492 521 493 522 procedure TMicroThreadScheduler.Stop; 494 begin 523 var 524 I: Integer; 525 begin 526 for I := 0 to ThreadPool.Count - 1 do 527 TMicroThreadSchedulerPoolThread(ThreadPool[I]).Terminate; 495 528 FTerminated := True; 496 529 end; … … 499 532 var 500 533 I: Integer; 501 begin 534 CurrentTime: TDateTime; 535 begin 536 CurrentTime := GetNow; 502 537 Result := nil; 503 538 try … … 510 545 (TMicroThread(MicroThreads[RoundRobinIndex]).State <> tsWaiting) do begin 511 546 // WakeUp sleeping threads 512 if (TMicroThread(MicroThreads[RoundRobinIndex]). State = tsSleeping) and513 (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < Time) then514 TMicroThread(MicroThreads[RoundRobinIndex]). State := tsWaiting else547 if (TMicroThread(MicroThreads[RoundRobinIndex]).FState = tsSleeping) and 548 (TMicroThread(MicroThreads[RoundRobinIndex]).FWakeupTime < CurrentTime) then 549 TMicroThread(MicroThreads[RoundRobinIndex]).FState := tsWaiting else 515 550 begin 516 551 // Go to next thread … … 541 576 function TMicroThreadScheduler.GetThreadPoolSize: Integer; 542 577 begin 543 Result := FThreadPoolSize;578 Result := ThreadPool.Count; 544 579 end; 545 580 546 581 procedure TMicroThreadScheduler.SetThreadPoolSize(const AValue: Integer); 547 begin 548 FThreadPoolSize := AValue; 582 var 583 I: Integer; 584 NewThread: TMicroThreadSchedulerPoolThread; 585 begin 586 if AValue > ThreadPool.Count then begin 587 ThreadPool.Capacity := AValue; 588 while ThreadPool.Count < AValue do begin 589 NewThread := TMicroThreadSchedulerPoolThread.Create(True); 590 NewThread.Manager.Scheduler := Self; 591 ThreadPool.Add(NewThread); 592 end; 593 end else 594 ThreadPool.Count := AValue; 549 595 end; 550 596
Note:
See TracChangeset
for help on using the changeset viewer.