Boost logo

Boost :

From: Darryl Green (darryl.green_at_[hidden])
Date: 2004-04-27 04:38:29


Jeff Garland <jeff <at> crystalclearsoftware.com> writes:

>
 
I've been offline a while. Still interested in improving time support in boost
threads though.

> On Tue, 20 Apr 2004 08:16:06 +0000 (UTC), Darryl Green wrote
>
> > xtime is a very "c" sort
> > of a creature and seems to lack basic type safety. Wouldn't it be
> > better to have a different time type for each clock type? A common
> > duration type could be used.
>
> I might suggest boost::posix_time::time_duration and its breathren. Then you
> could expressions like:
>
> time_duration td = milliseconds(100)+microseconds(20);

I agree boost::posix_time::time_duration would be fine to use as a duration
representation. Broadly speaking, time_duration would be used where posix uses
the timespec struct.
>
> Bill and I had a discussion about moving toward this in the future, but never
> had a chance to do this.

Ok - but what is the time part of this then? xtime is a duration since some
epoch. Do you mean to directly replace xtime with a duration type?

I think xtime needs replacing with a number of distinct clock types. If we
simply use a duration type everywhere, there is a possibility that someone
passes a duration intended to represent a time when used with epoch A to a
function that is using clock/epoch B. This strikes me as something that should
be detected at compile time. If all times use the same duration type it is
obviously simple enough to perform sensible conversions where needed.

> > The root of this lies in the fact that xtime's TIME_UTC is
> > "wallclock" time, while the relative time used by the windows Wait..
> > functions is a "tick count" (afaik) and isn't affected by changing
>
> As far as I know, all timers are relative...

Sorry:
The root of this lies in the fact that xtime's TIME_UTC is
"wallclock" time, while the duration passed to the windows Wait..
functions is used by a "tick count" clock with an undefined epoch (afaik).

>
> In general the separation of the clock from the representation of time is the
> correct approach. date_time does this because there is a recognition that
> different platforms (and systems) have different clock sources that can be
> adapted to produces a particular time representation with different
resolution
> and accuracy attributes. From what I'm reading here this is exactly the
issue
> you are facing...

It seems ptime is "clock independent" in that it can be constructed from
(potentially at least) a number of clock types. However, this seems not to
address all the issues that arise when trying to deal with various "timers"
or "clocks" for realtime systems. The clock and timer concepts are not
altogether orthogonal in that time representations imply/know the epoch, which
is also a property of the clock.

The ptime type is fine for "wallclock" time but the other times I am
considering have an epoch rather arbitrarily based on some previous event
occuring on the system on which they are running (eg. system start or process
start). "Converting" between these times should be possible by doing something
like:

time<up_time> start_time(); // construct time at start of epoch
time<up_time> now_time(up_time_clock::now());
time<utc_time> time_of_day(utc_clock::now()); // time now

cout << "system start time was " << time_of_day - (now_time - start_time) <<
endl;

The duration (now_time - start_time) is clock independent.

cout << now_time << endl; should probably print something like
P1234H56M78,123456789S or perhaps just P4445838.123456789S or
4445838.123456789 if the system has been up for about 51 days. This represents
the time as the period since the start of its epoch, which would seem to be
the only "universal" representation possible.

As an example using boost thread:

extern bool something_done;
void start_something();

condition<up_time> cond;
mutex m;
lock lk<m>;

bool done_by(time<up_time> tm)
{
  while (!something_done) {
    if (!cond.timed_wait(lk, tm))
        return false;
  }
  return true;
}

int main(int, char*[])
{
  time<up_time> a(minutes(5)); // construct from duration since epoch
  time<utc_time> b(date(min_date), minutes(5)); // using posix_time-like ctor

  start_something();
  if (done_by(a))
     cout << "Did something within 5 minutes of system start." << endl;

  if (done_by(b)) // won't compile
     cout << "This is a very early computer!" << endl;

  return 0;
}

For a more realistic use case, consider a remote telemetry unit (RTU) that has
a reasonably precise but innacurate clock (it is inaccurate when it has sat in
low power state for months or years before being powered up and being expected
to start running timing critical software). Every now and again this device
communicates with a host system with an accurate clock. The RTU will
immediately "jump" its clock to match the host. It transfers recorded data to
the host only after setting its own clock. The historical data has all been
stored with an "uptime" timestamp, which is converted to utc as part of
marshalling. The uptime clock is fine for this as the system doesn't have any
persistent data storage. The system doesn't really need/use an RTC that runs
while it is powered off, though it may have one so it can report on how long
it has been turned off etc. Most timers on the system are not concerned about
time of day and want to time out in 10s from now (for example) regardless of
whether the system time is adjusted (in either direction) by eg. 3 days during
that interval.

Have I somehow drawn the clock/time/duration distinctions in the wrong places,
or is the above a reasonable approach? I've had a look at the implementation
of date_time and I think it might fit ok with the model I was thinking of
where any time type is basically identical except for some sort of clock
dependent trait/policy.

Using date_time this would be time_system. This looks like a reasonable place
to start but the base_time seems to require that:

A time has a date component.
A time has a zone.

I guess one could write a time_system that had only a vestigial concept of
date and zone? Is there a way of making a pure day based date (no fancy julian
date calcs)?

Regards
Darryl Green.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk