Changeset 160 for MicroThreading/UMicroThreading.pas
- Timestamp:
- Feb 1, 2011, 10:06:01 AM (14 years ago)
- Location:
- MicroThreading
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading
- Property svn:ignore
-
old new 1 1 lib 2 backup
-
- Property svn:ignore
-
MicroThreading/UMicroThreading.pas
r159 r160 19 19 {$ENDIF}{$ENDIF} 20 20 Classes, ExtCtrls, SysUtils, Contnrs, SyncObjs, DateUtils, Dialogs, Forms, 21 UPlatform, UMicroThreadList ;21 UPlatform, UMicroThreadList, UThreadEx; 22 22 23 23 const 24 DefaultStackSize = $40000; 24 DefaultStackSize = $4000; 25 26 resourcestring 27 SStackOverflow = 'Microthread %d stack error. Pointer %s , range < %s ; %s >'; 28 SNilThreadReference = 'Can''t release nil thread.'; 29 SManagerMicroThreadRunning = 'Manager already have running microthread'; 25 30 26 31 type … … 124 129 { TMicroThreadThread } 125 130 126 TMicroThreadThread = class(TThread )131 TMicroThreadThread = class(TThreadEx) 127 132 Manager: TMicroThreadManager; 128 133 State: TMicroThreadThreadState; … … 171 176 FRoundRobinIndex: Integer; 172 177 FLastId: Integer; 173 FFrequency: Int64;174 178 FMainThreadTerminated: Boolean; 175 179 FMicroThreads: TObjectList; // TList<TMicroThread> … … 196 200 function Add(MicroThread: TMicroThread): Integer; 197 201 function AddMethod(Method: TMicroThreadMethod): Integer; 198 function FindCurrentThread: TThread;199 202 procedure Remove(MicroThread: TMicroThread; Free: Boolean = True); 200 203 constructor Create; … … 217 220 public 218 221 Form: TMicroThreadListForm; 219 constructor Create(AOwner: TComponent); 222 constructor Create(AOwner: TComponent); override; 220 223 end; 221 224 … … 258 261 function GetMicroThreadId: Integer; 259 262 var 260 I: Integer; 261 CurrentStack: Pointer; 262 begin 263 asm 264 mov CurrentStack, sp 265 end; 266 with MainScheduler do begin 267 try 268 FMicroThreadsLock.Acquire; 269 I := 0; 270 while (I < FMicroThreads.Count) and 271 not ((CurrentStack >= TMicroThread(FMicroThreads[I]).FStack) and 272 (CurrentStack <= (TMicroThread(FMicroThreads[I]).FStack + 273 TMicroThread(FMicroThreads[I]).FStackSize))) do Inc(I); 274 if I < FMicroThreads.Count then begin 275 Result := TMicroThread(FMicroThreads[I]).FId; 276 end else Result := -1; 277 finally 278 FMicroThreadsLock.Release; 279 end; 280 end; 263 MT: TMicroThread; 264 begin 265 MT := GetCurrentMicroThread; 266 if Assigned(MT) then Result := MT.Id else Result := -1; 281 267 end; 282 268 283 269 function GetCurrentMicroThread: TMicroThread; 284 270 var 285 I: Integer;271 Thread: TThread; 286 272 begin 287 273 with MainScheduler do … … 289 275 FMicroThreadsLock.Acquire; 290 276 if MainThreadID = ThreadID then Result := MainThreadManager.CurrentMicroThread 291 else Result := TMicroThreadThread(MainScheduler.FindCurrentThread).Manager.CurrentMicroThread; 277 else begin 278 Thread := TThreadEx.CurrentThread; 279 if Assigned(Thread) then 280 Result := TMicroThreadThread(Thread).Manager.CurrentMicroThread 281 else Result := nil; 282 end; 292 283 finally 293 284 FMicroThreadsLock.Release; … … 309 300 begin 310 301 if GetCurrentThreadId <> MainThreadID then begin 311 Thread := MainScheduler.FindCurrentThread;302 Thread := TThreadEx.CurrentThread; 312 303 if Assigned(Thread) then TThread.Synchronize(Thread, Method) 313 304 else raise Exception.Create('Can''t determine thread for id ' + IntToStr(GetCurrentThreadId)); … … 483 474 // but virtual methods can be called only statically 484 475 // Then static method CallExecute is calling virtual method Execute 485 476 call TMicroThread.CallExecute 486 477 487 478 // Restore manager stack … … 555 546 ExecutedCount: Integer; 556 547 begin 557 inherited Execute;558 548 try 559 549 repeat … … 599 589 except 600 590 on E: Exception do 601 ExceptionHandler(Self, E);591 if Assigned(ExceptionHandler) then ExceptionHandler(Self, E); 602 592 end; 603 593 asm … … 632 622 begin 633 623 if not ((FStackPointer > FStack) and (FStackPointer < (FStack + FStackSize))) 634 then raise EStackOverflow.Create(Format('Microthread %d stack error', [FId])); 624 then raise EStackOverflow.Create(Format(SStackOverflow, 625 [FId, IntToHex(Integer(FStackPointer), 8), IntToHex(Integer(FStack), 8), 626 IntToHex(Integer(FStack + FStackSize), 8)])); 635 627 end; 636 628 … … 766 758 NewMicroThread.FScheduler := Self; 767 759 Result := Add(NewMicroThread); 768 end;769 770 function TMicroThreadScheduler.FindCurrentThread: TThread;771 var772 I: Integer;773 begin774 try775 FThreadPoolLock.Acquire;776 I := 0;777 while (I < FThreadPool.Count) and (TMicroThreadThread(FThreadPool[I]).ThreadID <> ThreadID) do Inc(I);778 if I < FThreadPool.Count then Result := TMicroThreadThread(FThreadPool[I])779 else Result := nil;780 finally781 FThreadPoolLock.Release;782 end;783 760 end; 784 761 … … 951 928 if I < FMicroThreads.Count then begin 952 929 if Assigned(Manager.FCurrentMicroThread) then 953 raise Exception.Create( 'Manager have already have running microthread');930 raise Exception.Create(SManagerMicroThreadRunning); 954 931 Selected := TMicroThread(FMicroThreads[FRoundRobinIndex]); 955 932 Selected.FState := tsRunning; … … 965 942 begin 966 943 if not Assigned(MicroThread) then 967 raise Exception.Create( 'Can''t release nil thread.');944 raise Exception.Create(SNilThreadReference); 968 945 try 969 946 FMicroThreadsLock.Acquire;
Note:
See TracChangeset
for help on using the changeset viewer.