Question regarding pwritev/preadv ports

Ben ben@wijen.net
Sun Sep 6 10:09:00 GMT 2015


Hi,

I see several implementations for pwritev:
\misc\pwritev.c
\misc\pwritev64.c
\sysdeps\posix\pwritev.c
\sysdeps\posix\pwritev64.c
\sysdeps\unix\sysv\linux\pwritev.c
\sysdeps\unix\sysv\linux\pwritev64.c
\sysdeps\unix\sysv\linux\generic\wordsize-32\pwritev.c
\sysdeps\unix\sysv\linux\generic\wordsize-32\pwritev64.c
\sysdeps\unix\sysv\linux\mips\mips64\n64\pwritev64.c
\sysdeps\unix\sysv\linux\wordsize-64\pwritev.c
\sysdeps\unix\sysv\linux\wordsize-64\pwritev64.c

I was wondering if there is any way for an application to 'know' 
which implementation is used.
The specific reason is: I want to override the posix implementation 
with a non-atomic one.
(So just iterating over the vector until all is written.)

Could this be done with macro's? __NR_pwritev? __ASSUME_PWRITEV?
Or is there a way to figure out which platforms don't support 
pwritev, so I can override those specifically?


Furthermore, looking at the platform specific implementations,
they need to have the offset split into high and low value, I get that.

What I don't get, are the differences in implementation:
The \sysdeps\unix\sysv\linux\pwritev.c implementation:
#define LO_HI_LONG(val) \
   (off_t) val,								\
   (off_t) ((((uint64_t) (val)) >> (sizeof (long) * 4)) >> (sizeof (long) * 4))

Why are there 2 shifts?

The \sysdeps\unix\sysv\linux\generic\wordsize-32\pwritev.c implementation:
   return SYSCALL_CANCEL (pwritev, fd, vector, count, __ALIGNMENT_ARG
                          __LONG_LONG_PAIR (offset >> 31, offset));

Why not offset >> 32, like the \sysdeps\unix\sysv\linux\pwritev64.c 
implementation:
   return SYSCALL_CANCEL (pwritev, fd,
                          vector, count, __ALIGNMENT_ARG
                          __LONG_LONG_PAIR ((off_t) (offset >> 32),
                                            (off_t) (offset & 0xffffffff)));


Some insight on these, would be greatly appreciated.



More information about the Libc-help mailing list