In the Linux kernel, I found the following code:
static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
{
#define HALF_LONG_BITS (BITS_PER_LONG / 2)
return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
}
The code is used to combine syscall arguments into one wider variable, so for example on ia32 the offset of pwritev
is specified in two 32 bit registers.
On x64, loff_t
and unsigned long
are both 64 bit wide. In this case, the high
variable is ignored and only low
is used. On ia32, loff_t
is 64 bit wide and unsigned long
is 32 bit wide. In this case the two arguments high
and low
are combined.
I was wondering why the code bit-shifts twice instead of once. There's a bit more information about this code in the commit message and in an LWN article: System calls and 64-bit architectures, but no explanation for the double bit-shift.
return low;
? – Wolk