-
Content Count
1003 -
Joined
-
Last visited
-
Days Won
65
Everything posted by pyscripter
-
TThread always raises OS Errror
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
@Anders Melander @Lars FosdalSo you do not think this OS error is the result of Delphi making a call to an OS (Windows) function with invalid parameters. -
TThread always raises OS Errror
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
@Der schöne GüntherI am not sure about the relevance of your quote. No matter what your thread code is or how you run it (by inheriting from TThread, creating an anonymous thread or whatever), something results in an OS error 87 (it is always the same code) that corresponds to "parameter is incorrect". This OS error has been raised before your thread code has started running. And this has nothing to do with the return code of a thread. This is a problem because if you do any OS stuff in your thread code, and then you want to check whether an error was raised using CheckOSError, an exception will be raised. A workaround would be to always start your thread code with the statement: SetLastError(0); -
Smart Pointers - Generics vrs non-generic implementastion
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
His legacy lives on through people like me using his code... -
Smart Pointers - Generics vrs non-generic implementastion
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
If you want type inference then add a new method: function SmartPtr<T>.Value: T; begin if FGuard <> nil then Result := FGuard.Value else Result := nil; end; Then you can write: var Bob := SmartPtr<TTalking>(TTalking.Create('Bob')).Value; slightly more elegant than having three times TTalking on the same line. -
Experience/opinions on FastMM5
pyscripter replied to Leif Uneus's topic in RTL and Delphi Object Pascal
Funnily enough some of the most popular languages today, Python, JavaScript R and Ruby are single-threaded and you have to go out-of-your-way to use more than one cores. -
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!!