FreeMiNT time management

From SpareMiNT Wiki

Jump to: navigation, search

Beginning with kernel version 1.14.8 the time related functions of MiNT have drastically changed. Don't worry if you have missed to read this documentation until now; if you don't use the new facilities you can't mess up anything. The new stuff is 100 % compatible with the old time interface of the kernel.

Contents

[edit] Standard TOS time

Earlier versions of MiNT have inherited the standard TOS time setting (and retrieval) functions. The only difference was that changing the system time required super-user privileges.

The TOS time functions had one major short-coming. The internal representation of a calendar time caused a maximum resolution of two seconds for the system time. Furthermore, timezones were completely ignored; evaluating user-supplied timezone information was left to software.

[edit] New MiNT features

As a default the MiNT kernel clock now ticks in UTC (Universal Time Coordinated, GMT or Greenwich Mean Time is more or less a synonyme for that). You can also tell the kernel about the timezone that you're living in. Programs that request local times from the kernel will get values corrected according to the timezone settings you have supplied.

No, again, don't worry. As long as you haven't set the timezone explicitely, no correction will take place, no mess, the kernel will believe that you live in London/UK and that there is no such thing as daylight savings time.

[edit] How to use them?

The user-level (resp. system-administrator-level) interface to the new time facilities is the `tzinit' program. You should add the following lines to your MiNT configuration file mint.cnf:

# Make the time zone known to the kernel.
exec u:\usr\sbin\tzinit

or

# Make the time zone known to the kernel.
exec u:\usr\sbin\tzinit -u

if your hardware clock run in UTC (see paragraph 4).

As you might have guessed, you should install the tzinit program as /usr/sbin/tzinit but any other place will do.

The `tzinit' program will do two things: First, it evaluates the current setting of the TZ variable and sets the kernel timezone accordingly. It will then check the variable `MINT_CLOCKMODE'. If it doesn't exist, is empty or contains the strings `UTC' or `GMT' it will do nothing. Every other value will cause it to tell the kernel that the time that comes from the hardware-clock is actually a local time (see the discussion in the next section).

Because the `tzinit' program changes kernel time information it needs super-user privileges to run (don't worry about that if you run it from mint.cnf or from one of the /etc/rc files). Insufficient privileges are actually the only possible reasons for `tzinit' to fail.

The `tzinit' program has one major bug: It should actually be a daemon that waits and changes the kernel time information if daylight savings time (DST) for your timezone starts or end while your machine is running. Thus, when your local time changes from DST to standard time or standard time to DST during your machine is running you should reboot. In case your kernel clock ticks in local time you also have to change the hardware clock by hand.

[edit] UTC vs. Local Time

You have the choice if you want the kernel clock to tick in UTC or in local time. Both alternatives have pros and cons:

  • UTC - This is the standard for `real' Eunuchs machines. A major advantage is that you never have to change the hardware clock whether or not DST applies or not. If you sometimes run Linux or NetBSD on your machine you will also welcome this possibility because these operating systems feel much more comfortable with a hardware clock ticking in UTC.
  • local time - Deprecated, but probably better if you run other non-Eunuchs-like operatings systems, too. If your hardware clock is actually fed by some radio time signal or other source that provides the time in local representation you also may need this setting. The major disadvantage: You have to ensure that you change the hardware clock whenever DST starts or ends (when running UTC it is sufficient to reboot).

[edit] The TZ Environment Variable

The TZ environment variable is superseeded by the MiNTLib timezone database. It's strictly recommended to remove any TZ environment variable and to install the timezone database.

[edit] Other user-visible changes

The kernel time now has an accuracy of approximately 26 microseconds and a resolution of 1 microsecond (the old interface provided a maximum accuracy of 2 seconds). Provided that your software gets adapted to the new MiNT features you will see that the accuracy is increased.

If you are not a programmer or not particularly interested in the internals you can skip the rest of this file.

[edit] Obsoleted system calls

TOS provides four time related system calls:

  • Tgettime - Get the time of the day.
  • Tgetdate - Get the current date.
  • Tsettime - Set the time of the day. Under MiNT this call is reserved to the super-user.
  • Tsetdate - Set the current date. This is of course also reserved to the super-use under MiNT.

It was common understanding among software developers that these facilities return the time and date in local time representation and that time and date values passed to the time setting functions also expect the time in local representation.

These facilities are still supported by the MiNT kernel for compatibility reasons but their use is deprecated now. Yet, software that still uses these calls can rely on the old behavior, i.e. Tsettime and Tsetdate still expect local times, and Tgettime and Tgetdate still return local times.

[edit] New system calls

With MiNT 1.14.8 two new system calls are introduced in the kernel:

long Tgettimeofday (long tv, long tzp);
long Tsettimeofday (long tv, long tzp);

The opcode for Tgettimeofday is 0x155, the opcode for Tsettimeofday is 0x156. Please change your library binding if you want to use them.

The argument TV is actually a pointer to the following structure:

struct timeval {
   long int tv_sec;
   long int tv_usec;
};

The argument TZP is a pointer to the structure

struct timezone {
   long int tz_minuteswest;
   long int tz_dsttime; 
};

The member TV_SEC of the TV argument holds the number of seconds elapsed since the epoch. The epoch is "Thu, Jan 1 1970 00:00:00 UTC". The member TV_USEC of TV holds the fractional part of TV_SEC measured in microseconds.

The member TZ_MINUTESWEST of TZ holds the offset to UTC in second. Timezones east of the zero-meridian (e.g. Eastern Europe) have a negative value, timezones west of the zero-meridian (e.g. America) have a positive value. The member TZ_DSTTIME is non-zero if daylight savings time applies during some part of the year.

Implementors of library bindings should be aware that the definition of `struct timezone' is non-standard. The members are actually `int' and not `long int'(this applies only to struct timezone; the members of `struct timeval' are always longs). 16-bit libraries will have to copy the contents of the structure that TZP points to.

You may safely pass NULL for either arguments. This isn't considered an error.

Both functions return zero for success or a negative error value for failure (in fact Tgettimeofday can never fail). The following error conditions are defined:

  • EACCDN - An attempt was made by a user without super-user privileges to change the system time or system timezone.
  • ERANGE - One of the arguments is out of range. Note that the kernel time cannot be set to dates before Jan 1 1980 00:00:00 and after some day in 2038 (yep, MAX_LONG seconds since the epoch). Timezone offsets must be in the range of +/- 720 minutes.

The TZ_DSTTIME member of TZP is stored but not evaluated within the kernel. Beware not to misunderstand its meaning: If non-zero it simply signifies that daylight savings time apply during some part of the year, not necessarily now. In other words: If it is non-zero someday it should be non-zero during the entire year.

The Ssystem call has a new command `CLOCK_MODE' (see the file `ssystem.doc' for details). This command allows to retrieve or set the kernel clock mode, i.e. to specify whether the hardware clock is meant to run in UTC or in local time.

[edit] Future enhancements

It is planned to make MiNT compliant with the kernel time keeping model described in RFC1305. This model is already successfully implemented in operating systems such as SunOS, Ultrix, OSF/1, HP-UX and Linux. Please expect the internal realization to change in the future.

[edit] Bugs

Many, many time-keeping variables inside the kernel use the old TOS format (which is more or less derived from MS-DOS). This was probably short-sighted and it causes difficulties now: You can really confuse the system if you keep on changing the system timezone or the kernel clock mode too often. Timestamps can get corrupted and processes that rely on precise timing can get confused. Thus, you are strongly discouraged to change the system timezone or the kernel clock mode from somewhere else than `mint.cnf'. In mint.cnf you should call the `tzinit' program as soon as possible.

Personal tools
Resources