Interlocked features for Int64 are bound to {$ifdef cpu64}
While Int64 data type is supported under i386 FPC the interlocked features aren't included in FPC RTL.
Can I writeup a bug for this or is this due to another problem?
Thanks.

Mailing lists / fpc-devel / 2010-10
23 messages · 8 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Interlocked features for Int64 are bound to {$ifdef cpu64}
While Int64 data type is supported under i386 FPC the interlocked features aren't included in FPC RTL.
Can I writeup a bug for this or is this due to another problem?
Thanks.
32 bit CPUs can do at most InterlockedCompareExchange as native 64 bit operation. Everything else must be emulated.
And the functionality necessary for InterlockedCompareExchange64 is only available natively on i386, afaik. The system unit's interface is platform-independent. It could be added to the rtl/i386/cpu.pp unit if someone submits a patch, I guess.
Jonas
Interlocked features for Int64 are bound to {$ifdef cpu64} While Int64 data type is…
I have a 64bit cpu here running 32bit Windows 7. I was compiling my project under Windows 7 to do some debugging when I came across the problem when trying to lock increment int64 variables for transactions and bytecounts (general counter purposes).
I modified the systemh.inc that maps Increment(int64)/Decrement(int64) etc. to map to "external" cooresponding 64 procedures.
I had tried overloading in the i386.inc unit but the compiler said it found matching parameter functions and those changes didn't take. I've compiled FPC.
Compiling my app I realize that there is no overloaded InterlockedIncrement(int64) for cpu64. Which means presently I have to use {ifdef cpu64} {$else} {$endif} everywhere in my code. This is not pleasant. There should be one call to all the interlocked features.
Ok if I change? I think having two calls per Increment*64 and Increment*. If I'm compiling for cpu64 then use the 64 bit routines otherwise just use the other ones. And in the rare occatsion that I need Int64 on i386 just assume that I'll have the actual ability in the CPU to access assembler features presently coded.
Objections? Why?
Why must such general counters ever be 64 bit? With one such event per second the progam…
My SCS project which is a scalable unified collaboration and communication server that uses counting for transactions and network consumption across all implemented protocols. Bytes, when aggregated can clearly exceed the 2GB limitation within seconds. Partial transactions (PTX) can exceed over 30,000 per second and full transactions (TX) are typically 50% of that... But these numbers need to add up. Meaning the aggregate TX count must be of some proportion of the PTX otherwise they are bogus.
Int64 or QWord w/o locking or CAS is a serious issue for me. I absolutely need this feature or my transaction/byte counts will be off per node per cluster and can lead to misinformation in the consumption reports.
For the time being though I can restrict the scale on i386 architecture since I tried to re-map the methods in the system.inc file to no avail. It appears that FPC does not include the Interlocked*64 methods inside the RTL.
Hans-Peter Diettrich wroteWhy must such general counters ever be 64 bit?
Well, for starters overflow will occur easily without them.
With one such event per second the progam must run for 8 hours, in order to overflow an 16 bit counter. With 32 bits this will happen only after 20000 days, or about 60 years.
I honestly cannot think of one event per second in my projects with the exception of timer triggered events in with a coarse granularity setting. Most of the 'bean' counting done in the cluster solution is done for server management and reporting.
Still needing help...
I propose to add the 64 bit CAS for all 32 bit archs (if available): the 64 bit CAS instruction on a 32 bit target makes makes a lot "lock-free" algorithms simpler.
So you can build your 64 bit interlockedincrement yourself (there is no native on any 32 bit target I'am aware of).
I have a 64bit cpu here running 32bit Windows 7. I was compiling my project under…
I have a 64bit cpu here running 32bit Windows 7. I was compiling my project under Windows 7 to do some debugging when I came across the problem when trying to lock increment int64 variables for transactions and bytecounts (general counter purposes).
Why must such general counters ever be 64 bit?
With one such event per second the progam must run for 8 hours, in order to overflow an 16 bit counter. With 32 bits this will happen only after 20000 days, or about 60 years.
DoDi
Are you counting up only? Then you can use the 32-bit version of the InterlockedIncrement on the lower word only. If this turns out to be zero (the new value is returned) after the operation, you know you also have to increment the high word. Even with 30'000 transactions per second it takes about 9 hours until the lower word will be zero again, so the probability of a race condition happening here is very close to zero.
Well, you still need to stop any reader from using the value while you do that. Assuming that your read frequency is much lower than the number of transactions per second, it shouldn't be a big problem to lock out the reader for a couple of nanoseconds.
Vinzent.
Yes. Only counting up in this case *but* one of my other stats is UPTIME. Meaning we want to brag about how long the application is running w/o re-starting :-) So restarting the app every time the counter rolls over, just isn't feasible for this application.
I propose to add the 64 bit CAS for all 32 bit archs (if available): the 64 bit CAS…
I get your logic, and agree, but why not just have ONE call for all the data types. Why must I use Interlocked*64(...Int64) for the x64 cpu and Interlocked*(...Int64) for the i386 code? Can't we just consolidate them all to Interlocked*(..._type):_type ???
I didn't say "restart", I said "lock out the reader for a moment". Maybe it's easier to grasp if I put it in some pseudo-code:
-- 8< --
Lock_Readers;
if InterlockedIncrement (Lower_32_Bit) = 0 then // Counter just rolled
over.
begin
// !!! Race condition if the counter rolls over twice while doing this.
// But with a 32 bit counter and 30'000 counts per second this
// can only happen if this code needs several /hours/ to execute.
InterlockedIncrement (Upper_32_Bit);
end;
Unlock_Readers;
-- 8< --So you're updating the value without locking and only need to lock out the readers once in nine hours or so to ensure they /always/ get a consistent value.
Vinzent.
I get your logic, and agree, but why not just have ONE call for all the data types. Why…
Andrew Brunner wroteI get your logic, and agree, but why not just have ONE call for all the data types. Why must I use Interlocked*64(...Int64) for the x64 cpu and Interlocked*(...Int64) for the i386 code? Can't we just consolidate them all to Interlocked*(..._type):_type ???
Nevermind. If the x64 cpu uses a dedicated CAS instruction I would want to execute that way rather than via the i386 compat route.
On Wed, 27 Oct 2010 23:26:00 +0200, Andrew Brunner I didn't say "restart", I said "lock…
I'm not wanting to place locks all over the place when we have cpu locks.
My current largest issue is that due to source from from x86_64.inc
function InterLockedIncrement64 (var Target: int64) : int64; assembler; asm
{$ifdef win64}
movq %rcx,%rax
{$else win64}
movq %rdi,%rax
{$endif win64}
movq $1,%rdx
xchgq %rdx,%rax
lock
xaddq %rax, (%rdx)
incq %rax
end;
This code should not be excluded from me under i386 mode. How many 32 bit versions of FPC / Lazarus are out there with access to x64 cpu instructions. Coder: caveat emptor here. I drop my argument for the merging of Interlocked*64 to just Interlocked but I really think it would be good to have access to this code. Which presently any working with i386 build of FPC are not even if in my project options (Lazarus) i set -dcpu64.
So here I am with x64 cpu but with i386 build of Windows/FPC/Laz I cannot execute Interlocked*64(..) on my machine...
And I didn't want you to take the code literally. Usually someone encapsulates such specifics. And well, if you can live with a race condition that might return momentarily bogus counter values every couple of hours, you may as well leave them out.
On a 32-bit CPU 64-bit reads are not necessarily atomic, so it won't matter anyway. :P
Vinzent.
My current largest issue is that due to source from from x86_64.inc function…
None. The x64 instructions are not available to 32 bit code.
I propose to add the 64 bit CAS for all 32 bit archs (if available): the 64 bit CAS…
CMPXCHG8B works on probably most x86 architectures
Yes. That's what I wrote ;) because there is no interlockedincrement, one can use the 64 Bit CAS (implemented by CMPXCHG8B) to do the interlockedincrement64. But I don't want to provide a interlockedincrement64 on 32 bit platfroms by default because it requires cas with a while loop so it actually polls.
Ah, *Increment. Sorry, was a bit quick there :)
I tried to use the assembly code from the x64 unit on a i386 build of FPC but FPC throws error on compile. Why are the specific x64 instructions being blocked? The cpu running the code has the ability to execute the instructions. I don't see why the compiler is making the assumption that the code will cause an error. Is there a switch at compile time of FPC that removes all references to supported assembly instructions on i386 build? Shouldn't the application be able to pass instructions to the cpu regardless of what build I used to create the binary exe?
Under Windows there are functions for interlocked*(Int64).
The either the application developer or possibly the end-user should be able to activate x64 instructions either at compile time or run time (with no respect to 64 bit binary). Obviously a 64 bit app would have blind access to X64 cpu instructions.
I want access to a few of these instructions either at runtime or compile time. What about removing the limitation and creating a boolean variable for x64cpu_detected or something and the developers worry about misuse. Is this at all possible?
Hi,
Andrew Brunner wroteI tried to use the assembly code from the x64 unit on a i386 build of FPC but FPC throws error on compile. Why are the specific x64 instructions being blocked? The cpu running the code has the ability
In general, the 32 and 64 bit instructions partially use the same opcode for different actual instructions depending on the processor mode. The code segment selector contains information about the type of instruction set used.
It might be worth a try to hack a REX prefix in 32 bit assembly and see what happens, but I'd assume that either you get an invalid opcode exception or the prefix is just ignored.
What you expect can only be done on more regular ISAs like PowerPC where you have different instruction encodings for different data sizes.
Complaints about the x86 ISA please direct to AMD and/or Intel :)
Under Windows there are functions for interlocked*(Int64).
They very likely use cmpxchg8b.
As maybe already mentioned it may be possible to provide such functionality on x86 processors only. Otoh, some other 32 bit architectures do not have such an instruction iirc, at least 32 bit powerpc, and armv5 or earlier (I think for armv6 something like that has been added).
The either the application developer or possibly the end-user should be able to activate x64 instructions either at compile time or run time (with no respect to 64 bit binary). Obviously a 64 bit app would have blind access to X64 cpu instructions.
See above. That will not work.
Thomas
Some small addition:
code
Actually, the REX prefix uses the 32 bit inc/dec opcode space (0x40-0x4f)
- so you *will* get an invalid opcode in the best case, and if you are lucky, some unwanted program behavior.
Hth,
Thomas
For those following I've done a lot of reading and it just doesn't seem doable. So for cross CPU support I'm just creating a class for statisics which will break down the transaction components in their thousands and support up to PiBs. This way I'll set a write barrier and then use the CAS with each group represented by a WORD type. Doing it this way should give me ability to acquire access to the granularity I need when ever I need it.
Thanks for all the ideas/feedback but I don't think changes to FPC are in order.