-
Content Count
3710 -
Joined
-
Last visited
-
Days Won
185
Posts posted by David Heffernan
-
-
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
-
-
10 minutes ago, Kas Ob. said:It merely does add push REG at the begining and pop REG at the end, for rbx it is saved already in code and doesn't need this.
Wrong. It also lets the compiler out the meta data, the unwind data, needed to restore the register in case of an exception. Read Allen's article.
-
CAS from OTL does restore rbx, but it should do so using .pushnv, for the reasons that Allen's article explains.
-
1
-
-
8 hours ago, Kas Ob. said:The assembly is good and had nothing to be fixed.
No it is not. It modifies rbx and does not restore it.
-
11 minutes ago, Anders Melander said:Regardless the obstacle is probably more a question of resources and priorities.
This is the point that I've been making all along.
-
1
-
-
33 minutes ago, Vandrovnik said:I believe Anders is right.
Class reference is just a pointer - its size is known. When you use this class as a member of another class (fChild: tChild, where tChild is a class), you cannot reference its members in properties (property x: integer read fChild.x). If fChild is a record (fChild: tChild, where tChild is a record), you can reference its members in properties, like in Anders' example (property x: integer read fChild.x).
Not being able to do that one thing would hardly invalidate the entire enterprise. We'd still be able to use the type as procedure argument which is the main thing we are striving for.
But the whole argument is predicted on this single pass. It's no big deal to pass over each type section twice to process forward declarations. Won't make a blind bit of difference to performance.
Bottom line is that it is perfectly possible to do this if Emba wanted to.
-
55 minutes ago, Anders Melander said:It isn't. The type and offset of the members needs to be known too:
type TMyRecord = record Foo: integer; Bar: string; end; TMyClass = class private FFooBar: TMyRecord; public property Foo: integer read FFooBar.Foo; property Bar: string read FFooBar.Bar; end;
If what you say were true, then class forward references would not exist.
-
I can't see where RBX is restored in that InterlockedCompareExchange128 code. It's a NV register. Function needs to start with .PUSHNV RBX
I can't vouch for the rest of what it does.
-
12 hours ago, pyscripter said:Whilst still not perfect it helps a lot in 32 bits with say up to 100 threads.
You can't be doing multithreaded programming where "whilst still not perfect" as a valid statement. It's got to be right.
-
Not sure it's relevant but that x64 should use .PUSHNV to preserve rbx. And I think that also makes .NOFRAME incorrect.
-
1
-
Front-end vs Back-end question
in Network, Cloud and Web
Posted · Edited by David Heffernan
Depends on all sorts of things. I guess people are finding it hard to get motivated to write it all down.