Should TIME be signed or unsigned?

Discussions about the BBC BASIC language, with particular reference to BB4W and BBCSDL
RichardRussell

Should TIME be signed or unsigned?

Post by RichardRussell »

When I introduced 64-bit integers into BBC BASIC I had a choice of whether the legacy 32-bit TIME should be treated as signed or unsigned. I decided to make TIME unsigned, but that has the disadvantage that if a program is left running for more than about 248 days a statement like T% = TIME can fail with 'Number too big' because the value becomes too large to fit in a 32-bit integer variable.

So the question is: would it be better to change TIME back to being signed, as it was before 64-bit integers existed? It will then become negative after 248 days, even if assigned to a 64-bit integer as in t%% = TIME, but perhaps on balance that's less of a problem.
DDRM

Re: Should TIME be signed or unsigned?

Post by DDRM »

My own view would be that, since TIME reports the time since the program started running, having it return a negative number is nonsensical.

I can see why that MIGHT be better than an error, but either way the problem can be resolved if the programmer is aware of it - and if they aren't, the consequences of a negative time are just as likely to be disastrous as an error - presumably, if you are recording it, you are doing something with it.

I wasn't quite clear from your post whether t%% = TIME currently allows you to go to 2^64 centiseconds (a few billion years)?

Best wishes,

D
RichardRussell

Re: Should TIME be signed or unsigned?

Post by RichardRussell »

DDRM wrote: Sat 15 Aug 2020, 11:51the consequences of a negative time are just as likely to be disastrous as an error
I'm not so sure. This issue arose because my Ceefax emulator (Ceefax.bbc) failed with a 'Number too big' error for exactly this reason (it had been left running 'in the background' on an Amazon Fire TV Stick for months). On that device recovering from the error required delving through the menus: Settings... Applications... Manage Installed Applications... Ceefax... Force stop. I'm not even certain a typical user would know this setting existed and where to find it!

Had TIME been signed the error would not have occurred, and the only negative side-effect would have been that Ceefax pages which should have 'expired' (because more than a certain time had elapsed since they were loaded from the web) wouldn't have done so and they wouldn't have been automatically refreshed unless re-selected by the user. So in this specific case, and I admit it is very specific, the page(s) not expiring would have been far less disastrous.

Jonathan Harston has replied at the Discussion Group favouring changing TIME to signed, so I don't know what to do now!
DDRM

Re: Should TIME be signed or unsigned?

Post by DDRM »

Hi Richard,

I don't feel strongly, so if it makes sense to make it signed, go ahead: as long as it is documented, people should be able to cope.

My comments were based on the assumption that if you are monitoring it, there is a reason, and having a sudden dramatic shift to an impossible time is more likely to be a problem than an error (which you can catch if you know it might occur, or test for to prevent - for example by resetting time to 0, while incrementing a "248 day" counter). At least catching an error warns you that something unexpected has happened, and the data afterwards may be nonsensical. I also suspected that it might cause downstream errors, for example trying to reference a negative address in an array/database.

Best wishes,

D
RichardRussell

Re: Should TIME be signed or unsigned?

Post by RichardRussell »

DDRM wrote: Sun 16 Aug 2020, 10:49having a sudden dramatic shift to an impossible time is more likely to be a problem than an error
I think the weakness of that argument is that it has always been possible for TIME to suffer a "dramatic shift to an impossible time" ever since the BBC Micro was released in 1982! BBC BASIC programmers have had more than 38 years to get used to that possibility, and code around it if necessary. If their program fails because of that shift to a negative TIME, they have only themselves to blame!

But the possibility of TIME causing a 'Number too big' error only happened when 64-bit integers were introduced in version 6.00a of BBC BASIC for Windows in 2015. So that's only 5 years, and only in BB4W v6 (and latterly BBCSDL and the Console Mode editions). Even to the present day other versions of BBC BASIC still in use (e.g. Matrix Brandy or ARM BASIC on a Raspberry Pi say) don't suffer from this.

So you seem to be analysing the issue as if one were adding TIME as a new feature today, but that's not the situation we're in. TIME is an original feature of the language, it has always been a signed 32-bit number in all versions except mine (from BB4W v6 onwards). I am proposing that they be brought into line with the rest, but you seem to feel it is better that they remain different.

With it finely balanced between one in favour of the change and one against, the status quo must be the default option, but I would encourage others with an opinion to speak up.
DDRM

Re: Should TIME be signed or unsigned?

Post by DDRM »

RichardRussell wrote: Mon 17 Aug 2020, 12:38 ... the possibility of TIME causing a 'Number too big' error only happened when 64-bit integers were introduced in version 6.00a of BBC BASIC for Windows in 2015. ... the status quo must be the default option...
Hi Richard,

two fair points: I can see that consistency of behaviour is a strong argument in favour.

Best wishes,

D
Soruk
Posts: 23
Joined: Mon 30 Jul 2018, 20:24

Re: Should TIME be signed or unsigned?

Post by Soruk »

RichardRussell wrote: Mon 17 Aug 2020, 12:38
DDRM wrote: Sun 16 Aug 2020, 10:49having a sudden dramatic shift to an impossible time is more likely to be a problem than an error
Even to the present day other versions of BBC BASIC still in use (e.g. Matrix Brandy or ARM BASIC on a Raspberry Pi say) don't suffer from this.
You could offer an extension (e.g. via SYS) that offers access to a 64-bit timer. Matrix Brandy implements the RISC OS call SYS "OS_ReadMonotonicTime" TO result, and extends to the possibility of returning a 64-bit value, and this implementation is easily wrapped into a FN if you needed it that way.
RichardRussell

Re: Should TIME be signed or unsigned?

Post by RichardRussell »

Soruk wrote: Wed 02 Sep 2020, 11:12 You could offer an extension (e.g. via SYS) that offers access to a 64-bit timer.
Well, if a 64-bit timer exists (i.e. one is provided by the OS) then it will already be available via a SYS call. In my BASICs (I don't know the current situation with Matrix Brandy) virtually any OS API function can be called by SYS!

I'd also want to remind you that neither BBC BASIC for Windows nor BBC BASIC for SDL 2.0 supports 'custom' SYS functions: the SYS statement is for accessing API functions (typically in DLLs in the case of Windows and in .so shared objects in the case of Linux) only.

But in general I don't think a 64-bit timer is provided. In BBC BASIC for Windows I call the GetTickCount API as the source of TIME and in BBC BASIC for SDL 2.0 I call SDL_GetTicks; they are both 32-bits only.

There are functions which read the CPU's Performance Counter, providing 64-bits or more of resolution, but that's typically not calibrated to real-time so isn't really suitable.
Soruk
Posts: 23
Joined: Mon 30 Jul 2018, 20:24

Re: Should TIME be signed or unsigned?

Post by Soruk »

RichardRussell wrote: Wed 02 Sep 2020, 11:53
Soruk wrote: Wed 02 Sep 2020, 11:12 You could offer an extension (e.g. via SYS) that offers access to a 64-bit timer.
Well, if a 64-bit timer exists (i.e. one is provided by the OS) then it will already be available via a SYS call. In my BASICs (I don't know the current situation with Matrix Brandy) virtually any OS API function can be called by SYS!

I'd also want to remind you that neither BBC BASIC for Windows nor BBC BASIC for SDL 2.0 supports 'custom' SYS functions: the SYS statement is for accessing API functions (typically in DLLs in the case of Windows and in .so shared objects in the case of Linux) only.

But in general I don't think a 64-bit timer is provided. In BBC BASIC for Windows I call the GetTickCount API as the source of TIME and in BBC BASIC for SDL 2.0 I call SDL_GetTicks; they are both 32-bits only.

There are functions which read the CPU's Performance Counter, providing 64-bits or more of resolution, but that's typically not calibrated to real-time so isn't really suitable.
On Linux (EDIT: The same code works on my Windows builds), the underlying struct used by clock_gettime() is

Code: Select all

           struct timespec {
               time_t   tv_sec;        /* seconds */
               long     tv_nsec;       /* nanoseconds */
           };
whereby both time_t and long are 64 bits on a 64-bit system (and 32 bits on 32-bit).
My code for reading the timer (which I run in its own thread, updating basicvars.centiseconds) is basically:

Code: Select all

  struct timespec tv;

    clock_gettime(CLOCK_MONOTONIC, &tv);

    /* tv.tv_sec  = Seconds */
    /* tv.tv_nsec = Nanoseconds */

    basicvars.centiseconds = (((uint64)tv.tv_sec * 100) + ((uint64)tv.tv_nsec / 10000000));
The casting to uint64 is to ensure the calculations are done in 64 bits, even when compiled on 32-bit hardware.
RichardRussell

Re: Should TIME be signed or unsigned?

Post by RichardRussell »

Soruk wrote: Wed 02 Sep 2020, 12:05 On Linux (EDIT: The same code works on my Windows builds)
On Linux, yes, but clock_gettime is not available in Windows (if it seems to be for you, it's probably because you are using cygwin or msys2 rather than the native msvcrt library). There are some suggested workarounds here but they are vulnerable to discontinuities if the system clock is changed (rather as you found before switching to CLOCK_MONOTONIC).

It seems to me highly unlikely that any program actually needs more than 32-bits of TIME. Yes it does become negative after just over 248 days, but if that really is a concern it's not too difficult to incorporate an allowance for it. As I said, BBC BASIC programmers have had 38 years to get used to this 'limitation'!