On 07/01/2015 18:49, Paul Jarc wrote:
In this case I'm not dealing with the current time. How would I convert between an arbitrary system clock value stored in a time_t/struct timeval/struct timespec, and a TAI[N] value stored in a tai[n]_t?
The fast answer is: if t is the number of seconds in your arbitrary system clock value (be it a time_t or a tv_sec field), you can get the corresponding TAI value in a struct tai a with tai_from_sysclock(&a, (uint64)t + TAI_MAGIC) Then you have to copy micro/nanoseconds by hand, if applicable. I realize this is inconvenient, but arbitrary system clock values is exactly what I don't want to deal with: I want to hide the system clock from applications and provide them with TAI time instead, suitable for computations no matter what your system clock setting is. I understand that a program such as rw-touch may need those conversions though. If you insist, I'll try to come up with something more intuitive.
Do you recommend calling tain_init() at program startup? If the program does a significant amount of work before the first call to tain_now(), will it matter whether the initialization happens before or after that work?
Honestly, I never call tain_init(). It's auto-run at the first tain_now() invocation anyway. And most of all, it's only ever useful with --enable-monotonic, which doesn't really make sense if you're using linear time in your applications, which is probably the case if you're skalibs-aware; and if in one program you really want CLOCK_MONOTONIC, you can use tain_clockmon_init(&offset) at start to store the offset, then tain_clockmon(&a, &offset) to store the current TAI time (according to CLOCK_MONOTONIC) into a. If you call tain_init, or tain_clockmon_init, it does not matter at all when you do it as long as it's before the first call to tain_now or tain_clockmon. The only important thing is that you make sure that your idea of the current time is reasonably accurate, so call tain_now() after doing significant work. But most programs that need to keep track of time are definitely IO-bound, so it really only makes sense to call tain_now() right after blocking primitives and nowhere else. I usually call tain_now_g() once before my main loop, to initialize the global stamp, then iopause_g() is the only timekeeping I need. -- Laurent
