-
Content Count
3536 -
Joined
-
Last visited
-
Days Won
175
Posts posted by David Heffernan
-
-
35 minutes ago, Lars Fosdal said:It could, if more people actually bothered to.
But, yeah... I hear you.It's a shockingly bad way for a software house to prioritise. It's susceptible to an effect known as self selection. As worthwhile as a Twitter poll.
-
1
-
1
-
-
No. That's not what Invalidate does. It marks the paint box as invalid. And then when the message queue is next empty, a paint event gets synthesised.
The thing is, at some point you need to make the main thread wake up and do something. What's your plan for doing that? Perhaps what you want to do is note that an update is required with a flag and then check that on an update timer in the main thread. That would be a sensible approach if the frequency of updates from the threads was very high.
Bear in mind that in the OP you suggested sending a message from the worker thread to the main thread. Have you now decided that you don't want to do that?
-
26 minutes ago, Jacek Laskowski said:Calling Queue from the thread is a bad idea here. There are several threads, each of them processes some data, and one visual control displays them. If each thread is forcing a refresh, it will be a heavy load. And if the light gets messages, even from a few threads, it will decide how to refresh itself.
Dude, it was you that wanted to have the worker thread notify the main thread! That's literally what you asked in the OP.
26 minutes ago, Jacek Laskowski said:How to handle the message the parent got? I don't know who the parent will be?
Why would you opt to send a message to the parent? I only said that because you can't send a message to the paint box since it isn't windowed. Which is why Queue or Synchronize are cleaner.
Ultimately, you need to call Invalidate on the paint box, from the main thread. And you need to decide what is going to trigger that to happen. I gave you some examples, and of course there are other ways. But your have to make you own mind up.
-
1 hour ago, Lars Fosdal said:Vote like the feature depends on it!
Like that works!
-
You'd have to post the message to the parent. But why bother. Just use TThread.Queue.
-
6 hours ago, Vincent Parrett said:Or avoid Synchronize and send custom message to the control using PostMessage(control.handle,...) and call invalidate in the message handler.
Use TThread.Queue, not least because the paint box isn't windowed.
-
You never send a WM_PAINT message to a control. You invalidate in. For a plain Win32 control that means calling InvalidateRect. For a VCL control that means calling Invalidate.
You don't want to call that from a thread. Use Synchronize to execute code on the UI thread.
-
6 hours ago, pyscripter said:Right now the quality portal is updated at a frenetic rate. There was a very large number of fixes, I think more than in any other previous version, and I was quite pleased that quite a few of my reports have been resolved, some of the unexpectedly:
- System.AnsiStrings AdjustLineBreaks not exported
- Memory leak in TInvokeableVariantType.DispInvoke
- Optimize TInvokeableVariantType.DispInvoke
- Wrongly premultiplied TWICImage when assigning a Bitmap with aDefined
- TButtonedEdit is not styled properly
System.Threading got some attention with the famous Cancel and Wait issue resolved.
Issues I would like to see fixed now and consider critical are:
- TThreadedQueue and TMonitor issue, possible solution
- InterlockedCompareExchange128 doesn't restore RBX
- Threading - Incorrect calculation of IdleWorkerThreadCount
On the plus side these can be readily fixed yourself for your programs.
I mean, I've been running with a patched RTL for years that fixes all the design flaws in handling of floating point control flags.
At least we have access to the RTL source code and so can apply fixes easily using code hooks.
-
Depends on all sorts of things. I guess people are finding it hard to get motivated to write it all down.
-
1
-
-
This sounds like a whole layer of extra complexity for no gain.
Frankly I'm not surprised that you seem to find everything so challenging when you choose to introduce layer on layer of complexity.
-
47 minutes ago, miab said:But only OLE will ensure 100% compatibility MSOffice format.
Nah, that's not true.
-
Automating Word for document preparation is known to be somewhat brittle. More robust is to generate Word documents directly without invoking Word at all. There are good libraries for doing that. That's the point.
If you are going to rely on Word for this then it pays to be very careful about the version that you use. Switching to Office 365 is simply asking for trouble.
-
43 minutes ago, Leif Uneus said:Sorry @DavidHeffernan, but in the file posted by @pyscript his proposed function InterlockedCompareExchange128 returns a boolean.
OK. I've been working to the definition in the Delphi RTL.
-
17 minutes ago, Leif Uneus said:The function returns a boolean, one byte in size.
Wrong. It returns a Bool, which is LongBool, the 4 byte boolean.
The right fix is for Emba to change it to Boolean.
-
You can't have read the documentation. Because you aren't calling ShutdownBlockReasonCreate.
I know that you want to solve this quickly. But that expectation is unrealistic. It will take you time to wade through this, try it out, read and understand example code, etc.
For sure one of us could write you some examples but unless you understand it will you really be able to integrate it into your code? Just because you don't understand this now does not mean that you can't learn it. It just requires self belief and persistence.
-
You aren't doing what the documentation I linked to instructs you to do.
-
Getting notification isn't really what concerns you. You know how to do that. What you need to be able to do is block shutdown until you have finished saving any data. The way that is handled changed in Vista. The documentation you need starts here:
https://docs.microsoft.com/en-us/windows/win32/shutdown/system-shutdown
-
2
-
-
It's astonishing that Emba's InterlockedCompareExchange128 returns a BOOL, i.e. a 4 byte boolean, LongBool. They are presumably trying to copy this one from MS https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchange128 which is actually implemented as an intrinsic.
But look at the MS function's return type. Yup, it's BOOLEAN which is a single byte. The Emba version should use Boolean rather than Bool as the return type. It's a screw-up from top to bottom.
Anyone might think that they just write this stuff and don't test it ......
-
SETZ BL XOR EAX, EAX MOV AL,BL
Don't you just need
SETZ AL MOVZX EAX, AL
Also, .NOFRAME is wrong here. You need the frame to preserve RBX. At least that's how I understand it.
-
1
-
-
1 minute ago, Anders Melander said:Thanks but that can't be the only problem with it.
My tests fail even with that detail fixed but passes with the OmniThreadLibrary CAS. I can't spot what the problem is.
Has anybody looked at the equivalent for msvc, gcc, clang, etc?
-
7 hours ago, pyscripter said:I have packaged the fix as a stand-alone unit (see attached). You just add this unit to your project. Uses the CAS function from OmniThreadLibrary. It would still be nice to fix InterlockedCompareExchange128 .
I submitted a QP report for InterlockedCompareExchange128 not restoring rbx
-
1
-
-
6 minutes ago, Anders Melander said:I always start with registers and then refactor the code to use symbols to make it readable. I guess I should keep the register names in a comment.
To me it is much cleaner to comment at the top of the routine which register each parameter travels in, and then stick to registers. That allows you to see teg register usage directly rather than having an extra level of indirection.
-
7 minutes ago, Anders Melander said:Beware that this does not align memory allocated from the heap. For that you can use the following:
{$ifdef CPUX64} SetMinimumBlockAlignment(mba16Byte); {$else CPUX64} SetMinimumBlockAlignment(mba8Byte); {$endif CPUX64}
This works for me:
function InterlockedCompareExchange128(Destination: Pointer; ExchangeHigh, ExchangeLow: Int64; ComparandResult: Pointer): Bool; stdcall; asm .NOFRAME .PUSHNV R10 .PUSHNV RAX .PUSHNV RBX .PUSHNV RCX MOV R10,Destination MOV RBX,ExchangeLow MOV RCX,ExchangeHigh MOV RDX,[ComparandResult+8] MOV RAX,[ComparandResult] LOCK CMPXCHG16B [R10] SETZ AL end;
The PUSHNV RBX is translated to push RBX + pop RBX. The others do nothing.
You are restoring volatile registers there. That's wrong. Most egregious is where you restore rax which has the return value.
Ah, i read the bit where you say "the others do nothing". I guess the compiler knows they are volatile / used for param/return passing. I'd remove them all the same.
You really must stop using parameter names in asm because it obfuscates the fact they they live in registers, and which ones.
-
Probably remove that +8. But I'm guessing there. I'd never write asm using variable names. You simply have to write the whole thing using registers to keep track of what it where.
-
1
-
TPainBox, Handle and PostMessage()
in VCL
Posted
Invalidate doesn't send a message. It marks the control as needing repainting and then that paint message is synthesised the next time the message queue is emptied.