top | item 41684857

(no title)

darkhelmet | 1 year ago

Every time I see people struggling with this, I am so incredibly glad that I forced the issue for FreeBSD when I did the initial amd64 port. I got to set the fundamental types in the ABI and decided to look forward rather than backward.

The amd64 architecture did have some interesting features that made this much easier than it might have been for other cpu architectures. One of which was the automatic cast of 32 bit function arguments to 64 bit during the function call. In most cases, if you passed a 32 bit time integer to a function expecting a 64 bit time_t, it Just Worked(TM) during the platform bringup. This meant that a lot of the work on the loose ends could be deferred.

We did have some other 64 bit platforms at the time, but they did not have a 64 bit time_t. FreeBSD/amd64 was the first in its family, back in 2003/2004/2005. If I remember correctly, sparc64 migrated to 64 bit time_t.

The biggest problem that I faced was that (at the time) tzcode was not 64 bit safe. It used some algorithms in its 'struct tm' normalization that ended up in some rather degenerate conditions, eg: iteratively trying to calculate the day/month/year for time_t(2^62). IIRC, I cheated rather than change tzcode significantly, and made it simply fail for years before approx 1900, or after approx 10000. I am pretty sure that this has been fixed upstream in tzcode long ago.

We did have a few years of whackamole with occasional 32/64 time mixups where 3rd party code would be sloppy in its handling of int/long/time_t when handling data structures in files or on the network.

But for the most part, it was a non-issue for us. Being able to have 64 bit time_t on day 1 avoided most of the problem. Doing it from the start was easy. Linux missed a huge opportunity to do the same when it began its amd64/x86_64 port.

Aside: I did not finish 64 bit ino_t at the time. 32 bit inode numbers were heavily exposed in many, many places. Even on-disk file systems, directory structures in UFS, and many, many more. There was no practical way to handle it for FreeBSD/amd64 from the start while it was a low-tier platform without being massively disruptive to the other tier-1 architectures. I did the work - twice - but somebody else eventually finished it - and fixed a number of other unfortunately short constants as well (eg: mountpoint path lengths etc).

discuss

order

jabl|1 year ago

AFAIU all 64-bit Linux ports have used 64-bit time_t, off_t, ino_t from the beginning. All this is about transitioning 32-bit Linux to 64-bit time_t.

Netch|1 year ago

FreeBSD was also more radical in dealing with off_t which became 64 bits since 2.0. Linux still has rudiments of old size in its 32-bit versions.

> One of which was the automatic cast of 32 bit function arguments to 64 bit during the function call.

AFAIU this works only for unsigned arguments (as loading to %edi clears upper part of %rdi). SysV ABI spec for x86-64 says nothing about extending all values in registers or stack to full 64-bit value, and comment on boolean (only LS byte contains something significant) suggests this is a common rule.

nwallin|1 year ago

> Every time I see people struggling with this, I am so incredibly glad that I forced the issue for FreeBSD when I did the initial amd64 port. I got to set the fundamental types in the ABI and decided to look forward rather than backward.

Hold on. You're saying that when amd64 happened, FreeBSD ported i386 time_t to 64 bits as well? That's wild. Were other 32 bit architectures ported to 64 bit time_t as well, like the Motorola 68000 and sparc32?