Leaderboard
Popular Content
Showing content with the highest reputation on 05/13/20 in all areas
-
Record Circular References
David Heffernan replied to Bernard's topic in Algorithms, Data Structures and Class Design
Bloody annoying that this can't be done -
Record Circular References
David Heffernan replied to Bernard's topic in Algorithms, Data Structures and Class Design
The argument is that its a single pass compile. So make it two pass. Simples. -
TThread always raises OS Errror
Darian Miller replied to pyscripter's topic in RTL and Delphi Object Pascal
Just out of curiosity, I ran the same test program on the same Windows 10 virtual machine that has many versions of Delphi installed. I built/ran the console project below multiple times on each Delphi version and they all resulted in a GetLastError of 0 when a new thread is spawned: Delphi 5, 7, 2005, 2009, 2010, XE, XE2, XE3, XE4, XE5, XE6, XE7, XE8, 10.0 Seattle, 10.1 Berlin. Delphi 10.2.2 resulted in nearly equal results of 87 and 0 - it seems to switch nearly every time I build the project. Delphi 10.3.3 results in 87 every time that I've built/ran the project. (>20 builds) To narrow it down further, I have Delphi 10.2.0 installed on another VM with the same OS but different patch levels and it comes up with 0 every time. I copied the .exe to the first VM and it always comes up with 0. It does appear that in Delphi 10.2.1 (or 10.2.2) and later there is a change in this (useless) behavior. So - even though it doesn't really matter as we should all agree by now that you should never call GetLastError unless you have a very specific context to do so otherwise the return value is less than useful, it is a tiny bit curious why this is happening only in Delphi 10.2.2 and later on the same OS with the same console project. This is especially true since the code in System provided with Delphi 10.2 and 10.2.2 is seemingly identical when it comes to BeginThread. And the code in System.Classes for ThreadProc seems identical but I didn't spend a lot time trying to figure out the differences. Now it could absolutely be the case that the return value of 87, or 209232, or some other random number could easily occur on a Delphi 5 project and that I simply didn't execute it enough times to see a different result at the start of new thread. However, I did build and execute the same code multiple times per version and there were 16 different versions of Delphi tested which all resulted in 0 every single time. Perhaps it has to do with the size of the executable which seems to be ever-growing in subsequent releases of Delphi, who knows. (and yes, who really cares) It's of little value to anyone. But if you are 'that one guy' with code stretching back 20+years to Delphi 5 which was somehow based on the incorrect assumption that a new thread started with a GetLastError of 0, that assumption started breaking a few years ago around Delphi 10.2.2 for some reason. And since I wasted a little time myself chasing an invalid GetLastError recently based on someone else's code, it tripped my curiosity. program TestGetLastError; {$APPTYPE CONSOLE} uses SysUtils, Classes, Windows; type TMyThread = class(TThread) procedure Execute(); override; end; procedure TMyThread.Execute(); begin WriteLn('GetLastError: ' + IntToStr(GetLastError)); end; var x:TMyThread; begin x := TmyThread.Create(False); Sleep(100); WriteLn('Hit enter to exit'); ReadLn; end. Now that my curiosity has been sufficiently satisfied, I can be done with this. If someone else wants to go deeper, have at it. cheers -
TSslHttpRest - 429 (Too Many Requests) - resend request
Angus Robertson replied to Anxich's topic in ICS - Internet Component Suite
You should be repeating RestRequest and not using DoRequestAsync so the request is properly initialised, missed that, other problems may occur attempting to make this a class. Angus -
TThread always raises OS Errror
Darian Miller replied to pyscripter's topic in RTL and Delphi Object Pascal
No, it's absolutely not a pointless process just because of the topic. If any value changes over time then being curious as to why is not only expected, but typically mandated. This is the case even if your perception is wrong headed, as it's still your perception of reality. The situation is even more difficult if its a very long held perception backed up by years of observation - even if that observation was faulty or insufficient. Changing perception is not easy - and it's rarely changed by blunt force. It's the developers' job to question facts that go against personal perception when analyzing problems. You don't need people hitting you over the head with their own (perceived or real) realities. There is a process that needs to happen to alter a perception. And it's a process that we all have gone through with different topics at different times in our careers. I would assert it's a rather common occurrence that we should all be familiar with - and since that's the case why can't we just provide assistance on the journey and not try to end it quickly because we deem it to be an invalid destination? Every trip is valid as long as there is something learned along the way. If you tried to be helpful and failed to penetrate someone's reality, then being quiet is sometimes the most help you can be so they can figure it out on their own. As such, I'll certainly try to ignore any further comments in this thread. Let's just please not turn this valuable resource into StackExchange. I strongly object to that sort of behavior. -
TThread always raises OS Errror
Darian Miller replied to pyscripter's topic in RTL and Delphi Object Pascal
If the perceived behavior over the last two decades was that a newly created thread always had a GetLastError of 0 and now it's all of sudden 87, there's absolutely nothing wrong with being curious. Now, I don't think it was the perceived behavior of many as it's pretty very likely that most devs haven't really given this specific topic much thought - but, programmers are supposed to be curious and altered behavior (perceived or real) is an obvious red flag that we all have been forcibly trained over the years to instinctively question, regardless of the merits. How many times have we gone a journey chasing a bug that "shouldn't ever happen" when it actually happens "every single time" once we figured out the "obvious"? (only obvious of course after the fact) Occasionally that journey takes a while and it's probably the case that every seasoned developer on the planet has taken that particular trip more than once - blunt force here isn't merited. For fun, you could scan through Windows source code and see what's up behind the scenes and maybe even find out where 87 comes from, if you are curious. https://github.com/pustladi/Windows-2000 https://github.com/Zer0Mem0ry/ntoskrnl -
Panel is no more than a TRectangle (depending style file I think) I don't know why but if you try to change TPanel fill color this does not work with 'windows 10 desktop style' , works during design time with 'default' Stylecollection but not at runtime 🐛something to do with the fact that this TRectangle is at the root and not in a TLayout ? Best suggestion I can do is : use a TRectangle. I do not use anymore TPanel now, preferring Layouts and TRectangle 😉
-
Record Circular References
David Heffernan replied to Bernard's topic in Algorithms, Data Structures and Class Design
I personally don't think you can do better than helpers. That's what I do. -
TSslHttpRest - 429 (Too Many Requests) - resend request
Angus Robertson replied to Anxich's topic in ICS - Internet Component Suite
As I said, you are recursively starting a new HTTP request from the within an event called by that request, you need to start the next request outside the event, either from a timer as I suggested, or by sending a message to a function that starts the next request. Sleep stops messages being processed so defeats the concept of event driven programming, it should only generally only be used in threads that don't do anything else. Angus -
TThread always raises OS Errror
Remy Lebeau replied to pyscripter's topic in RTL and Delphi Object Pascal
(Get|Set)LastError() use thread-local storage internally. The last-error code is stored inside the OS thread object itself. It doesn't matter how you create the thread, calling SetLastError() in one thread context and then calling GetLastError() in another thread context will NEVER work. The last-error simply can't cross thread boundaries. This is documented behavior: https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setlasterror https://docs.microsoft.com/en-us/windows/win32/debug/last-error-code -
TThread always raises OS Errror
David Heffernan replied to pyscripter's topic in RTL and Delphi Object Pascal
The only error here is the code that calls GetLastError and uses the value at a time when its return value is meaningless. All you have to do is to stop doing that. -
Experience/opinions on FastMM5
Arnaud Bouchez replied to Leif Uneus's topic in RTL and Delphi Object Pascal
You are right: FastMM5 challenged me... and since no one responded to my offer about helping it run on FPC/Linux, and also since I wanted something Open Source but not so restrictive, I created https://github.com/synopse/mORMot2/blob/master/src/core/mormot.core.fpcx64mm.pas which is GPL/LGPL and MPL. So you can use it with closed software. It uses the same core algorithms than FastMM4. I like it so much, and missed it so much in FPC... 🙂 I was involved in ScaleMM2, and a per-thread arena for small blocks didn't convince me: it tends to consume too much RAM when you have a lot of threads in your process. Note that a threadvar is what the FPC standard MM uses. I wanted to take the best of FastMM4 (which is very proven, stable and efficient), but drive it a little further in terms of multi-threading and code quality. FastMM4 asm is 32-bit oriented, its x86_64 version was sometimes not very optimized for this target - just see its abuse of globals, not knowledge of micro-op fusion or CPU cache lines and locks, and sparse use of registers. Also focusing on a single compiler and a single CPU, with not all the features of FastMM4 in pascal mode, helped fpcx64mm appear in two days only. Last but not least, I spent a lot of time this last year in x86_64 assembly, so I know which patterns are expected to be faster. The huge regression test suite of mORMot helps having a proven benchmark - much more aggressive and realistic than microbenchmarks (like string concatenation in threads, or even the FastCode benchmark) on which most other MM relies for measurement. When the regression tests are more than twice faster than with the FPC standard MM on Linux - as @ttomas reported - then we are talking. It runs a lot of different scenarios, with more than 43,000,000 individual tests, and several kind of HTTP/TCP servers on the loopback, running in-memory or SQLite databases, processing JSON everywhere, with multiple client threads stressing it. When I run the test on my Linux machine, I have only a few (less than a dozen) system Linux nanosleeps (better than Windows sleep) , and less than 2 ms waiting during a 1 minute of heavy tests - and only for Freemem. I really don't like the microbenchmarks used for testing MM. Like the one published in this forum. For instance IntelTBB is very fast for such benchmarks, but it doesn't release its memory as it should, and it is unusable in practice. I guess that some user code, not written with performance in mind, and e.g. abusing of str := str+'something' patterns would also be more than twice faster. And if your code has to reallocate huge buffers (>256KB) in a loop, using mremap on Linux may make a huge performance boost since no data would be copied at all - Linux mremap() is much better than what Windows or BSD offer! Yes, huge memory blocks are resized by the Linux Kernel by reaffecting its TLB redirection tables, without copying any memory. No need to use AVX512 if you don't copy anything! And plain SSE2 (with non-volatile mov for big buffers) is good enough to saturate the HW memory bandwidth - and faster than ERMS in practice. IMHO there was no need to change the data structures like FastMM5 did - I just tuned/fixed most of its predecessor FastMM4 asm, reserved some additional slots for the smaller blocks (<=80 bytes are now triplets), implemented a safe and efficient spinning, implement some internal instrumentation to catch multi-threading bottlenecks, and then Getmem didn't suffer from contention any more! I knew than FastMM4 plus some tweaks could be faster than anything else - perhaps even FastMM5.