-
Content Count
920 -
Joined
-
Last visited
-
Days Won
56
Everything posted by pyscripter
-
Threads in PPL thread pool not returning to idle as expected
pyscripter replied to GeMeMe's topic in RTL and Delphi Object Pascal
I was not aware of that. It is certainly wrong now. -
Threads in PPL thread pool not returning to idle as expected
pyscripter replied to GeMeMe's topic in RTL and Delphi Object Pascal
I finally got to the bottom of this issue and I have a simple fix. See https://quality.embarcadero.com/browse/RSP-28200 Please test and vote for it. -
I revisited this thread and tested the code below: program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Threading, System.Diagnostics; var SW:TStopWatch; type TThreadPoolStatsHelper = record helper for TThreadPoolStats function Formatted: string; end; function TThreadPoolStatsHelper.Formatted: string; begin Result := Format('Worker: %2d, Min: %2d, Max: %2d, Idle: %2d, Retired: %2d, Suspended: %2d, CPU(Avg): %3d, CPU: %3d', [self.WorkerThreadCount, self.MinLimitWorkerThreadCount, self.MaxLimitWorkerThreadCount, self.IdleWorkerThreadCount, self.RetiredWorkerThreadCount, self.ThreadSuspended, self.AverageCPUUsage, self.CurrentCPUUsage]); end; procedure Load; begin TParallel.For(0, 99999999, procedure(i: Integer) var T:Single; begin T:=Sin(i/PI); end); end; begin try Writeln('PPL Test ---------------'); Writeln('Before: '+ TThreadPoolStats.Current.Formatted); SW:=TStopWatch.StartNew; Load; Writeln('Finished in '+SW.Elapsed.ToString); Sleep(1000); Writeln('After: '+TThreadPoolStats.Current.Formatted); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; ReadLn; end. This is the output 32-bits PPL Test --------------- Before: Worker: 0, Min: 8, Max: 200, Idle: 0, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 Finished in 00:00:00.7620933 After: Worker: 8, Min: 8, Max: 200, Idle: 7, Retired: 0, Suspended: 0, CPU(Avg): 8, CPU: 15 64-bits PPL Test --------------- Before: Worker: 0, Min: 8, Max: 200, Idle: 0, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 Finished in 00:00:14.0655228 After: Worker: 8, Min: 8, Max: 200, Idle: 7, Retired: 0, Suspended: 0, CPU(Avg): 85, CPU: 1 Can anyone explain the huge difference in times? (it was consistent over many runs).
-
Yes you are right...
-
Oh I get it. sin is highly optimized in 32-bits but apparently not in 64-bits.
-
Locations vs Values: using RTTI to work with value types
pyscripter posted a topic in RTL and Delphi Object Pascal
I was looking at an old blog post by Barry Kelly. In particular the function: function TLocation.FieldRef(const name: string): TLocation; var f: TRttiField; begin if FType is TRttiRecordType then begin f := FType.GetField(name); Result.FLocation := PByte(FLocation) + f.Offset; Result.FType := f.FieldType; end else if FType is TRttiInstanceType then begin f := FType.GetField(name); Result.FLocation := PPByte(FLocation)^ + f.Offset; Result.FType := f.FieldType; end else raise Exception.CreateFmt('Field reference applied to type %s, which is not a record or class', [FType.Name]); end; I am puzzled by the line: Result.FLocation := PPByte(FLocation)^ + f.Offset; If Flocation is an object (FType is TRttiInstance type) and I am having a record field inside the object, the Result.FLocation should be PByte(FLocation) + f.offset, i.e. the same as for FType is TRttiRecord. Barry Kelly is probably the guy that wrote the Rtti stuff, so he knows what he is talking about. What I am missing? -
Locations vs Values: using RTTI to work with value types
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
@Attila Kovacs Thanks I missed that. Now I get it. The key is in class function TLocation.FromValue(C: TRttiContext; const AValue: TValue): TLocation; begin Result.FType := C.GetType(AValue.TypeInfo); Result.FLocation := AValue.GetReferenceToRawData; end; If AValue contains an object, Flocation would a pointer to a pointer. That was not the case in my testing. He could do the dereferencing in this function of course. -
Another free one is at https://github.com/ekot1/DelphiSVG/commits/master
-
How to get PTypeInfo of TRttiProperty / TRttiField
pyscripter replied to aehimself's topic in Algorithms, Data Structures and Class Design
GetProperty(Name).PropertyType.Handle -
https://github.com/ase379/gpprofile2017 A revamped version of the good old instrumenting profiler by @Primož Gabrijelčič.
-
I can confirm that the workaround worked.
-
I have just been told that this is a reported bug with Catalina 10.15.4. and there is a workaround I am going to try. @Dave NottageHow come this did not affect you?
-
@Dave NottageThanks for responding I am in Delphi 10.3.3. Here is what I see in verbose mode when I select Add New SDK as above and then press OK. The -version -skd happens while the dialog is showing. Nothing seems to happen when I press OK. Do I need to download the SDK in the Mac? The XCode version is 11.4.
-
@Dave NottageThanks for responding I am in Delphi 10.3.3. Here is what I see in verbose mode when I select Add New SDK as above and then press OK. The -version -skd happens while the dialog is showing. Nothing seems to happen when I press OK. Do I need to download the SDK in the Mac? The XCode version is 11.4.
-
Difference between Pred and -1
pyscripter replied to John Kouraklis's topic in RTL and Delphi Object Pascal
You can add an extension method if you wish to do that using a class helper. (Low as well). -
RegExpressions and preUnGreedy
pyscripter replied to Jacek Laskowski's topic in RTL and Delphi Object Pascal
See workaround in https://quality.embarcadero.com/browse/RSP-22372. -
Threads in PPL thread pool not returning to idle as expected
pyscripter replied to GeMeMe's topic in RTL and Delphi Object Pascal
@Freds I see. There are two ways to grow the pool. One by GrowWorkerPool and another by TThreadPool.TThreadPoolMonitor.GrowThreadPoolIfStarved, so you create the ThreadPoolMonitor after the initial threads are created and then it undertakes the growing or the Pool. Actually the problem with CPU usage was related to this method: procedure TThreadPool.GrowWorkerPool; begin if ShouldGrowPool then begin TMonitor.Enter(FQueue); try if ShouldGrowPool then if FRetiredWorkerThreadCount = 0 then CreateWorkerThread else ResurrectRetiredThread; finally TMonitor.Exit(FQueue); end; end else CreateMonitorThread; end; CreateMonitorThread was never called. If you change the above to: procedure TThreadPool.GrowWorkerPool; begin if ShouldGrowPool then begin TMonitor.Enter(FQueue); try if ShouldGrowPool then if FRetiredWorkerThreadCount = 0 then CreateWorkerThread else ResurrectRetiredThread; finally TMonitor.Exit(FQueue); end; if FMonitorThreadStatus = [] then CreateMonitorThread; end else CreateMonitorThread; end; then CPU usage is reported OK. -
Threads in PPL thread pool not returning to idle as expected
pyscripter replied to GeMeMe's topic in RTL and Delphi Object Pascal
No, The change was done to make sure that Parallel.For works OK and produces the same result. I am puzzled though by the reported CPU usages. The Task Monitor shows that CPU usage is close to 100%. -
Threads in PPL thread pool not returning to idle as expected
pyscripter replied to GeMeMe's topic in RTL and Delphi Object Pascal
For me the following change to System.Threading appears to resolve the issue: function TThreadPool.ShouldGrowPool: Boolean; begin Result := {(FWorkerThreadCount < FMinLimitWorkerThreadCount) and }(FIdleWorkerThreadCount < FQueuedRequestCount) and (FWorkerThreadCount < Self.FMaxLimitWorkerThreadCount); end; The condition FWorkerThreadCount < FMinLimitWorkerThreadCount does not appear to make sense. A slightly modified Load function: procedure Load; Var Sum : Double; begin Sum := 0; Monitor := TObject.Create; try TParallel.For(0, 99999999, procedure(i: Integer) var T:double; begin T:=Sin(i/PI); TMonitor.Enter(Monitor); Sum := Sum + T; TMonitor.Exit(Monitor); end); Writeln('Sum = ', Sum); finally Monitor.Free; end; end; produced the following results for multiple runs: PPL Test --------------- Before: Worker: 0, (Min: 8..Max: 200), Idle: 0, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 Sum = 1.37111034277419E+0000 Finished in 00:00:03.8990212 After: Worker: 17, (Min: 8..Max: 200), Idle: 17, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 ------------------------ PPL Test --------------- Before: Worker: 17, (Min: 8..Max: 200), Idle: 17, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 Sum = 1.37111034276774E+0000 Finished in 00:00:03.8069356 After: Worker: 17, (Min: 8..Max: 200), Idle: 17, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 ------------------------ PPL Test --------------- Before: Worker: 17, (Min: 8..Max: 200), Idle: 17, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 Sum = 1.37111034277633E+0000 Finished in 00:00:03.8392113 After: Worker: 17, (Min: 8..Max: 200), Idle: 17, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 ------------------------ PPL Test --------------- Before: Worker: 17, (Min: 8..Max: 200), Idle: 17, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 Sum = 1.37111034277271E+0000 Finished in 00:00:03.8729582 After: Worker: 17, (Min: 8..Max: 200), Idle: 17, Retired: 0, Suspended: 0, CPU(Avg): 0, CPU: 0 ------------------------ -
@Attila KovacsI tried your suggestion and it works!!
-
ActiveMQ + OpenWire for Delphi?
pyscripter replied to David Schwartz's topic in Network, Cloud and Web
https://github.com/danieleteti/delphistompclient -
https://quality.embarcadero.com/browse/RSP-26633 The report contains a solution.
-
Unknown function at TMethodImplementationIntercept
pyscripter posted a topic in RTL and Delphi Object Pascal
I am getting a bug report with the following stack list. Exception class: EOSError Exception message: System Error. Code: 1400. Invalid window handle. Exception address: 004305B8 Stack list, generated 10/12/2019 10:45:33 AM [004305B3]{PyScripter.exe} Unknown function at __dbk_fcall_wrapper [005F08C1]{PyScripter.exe} Unknown function at TMethodImplementationIntercept [005B6961]{PyScripter.exe} Unknown function at TMethodImplementationIntercept .... TMethodImplementationIntercept is defined in RTTI.pas but it does not appear to be used anywhere and I am not calling this function. { This function has been added to be used from .s .c files in order to avoid use mangled names} procedure TMethodImplementationIntercept(const obj:TMethodImplementation; AFrame: Pointer); cdecl; begin obj.Intercept(AFrame); end; exports TMethodImplementationIntercept; Any idea what might be going on? -
Unknown function at TMethodImplementationIntercept
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
Yes indeed. THANK YOU! I am normally including jdbg info into the executable, but for some reason this was not included. -
See my post on this very topic.