mbgtools-lx  4.2.8
chk_time_info.c
Go to the documentation of this file.
1 
2 /**************************************************************************
3  *
4  * $Id: chk_time_info.c 1.5 2019/02/08 10:13:17 martin REL_M $
5  *
6  * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
7  *
8  * Description:
9  * System time checking support functions.
10  *
11  * -----------------------------------------------------------------------
12  * $Log: chk_time_info.c $
13  * Revision 1.5 2019/02/08 10:13:17 martin
14  * Made code more portable.
15  * Account for renamed symbols.
16  * Added some comments.
17  * Revision 1.4 2017/07/05 09:00:14 martin
18  * Use safe string functions from str_util.c.
19  * Account for PCPS_HRT_BIN_FRAC_SCALE renamed
20  * to MBG_FRAC32_UNITS_PER_SEC.
21  * Revision 1.3 2013/07/30 12:55:33 martin
22  * Updated file description.
23  * Revision 1.2 2013/03/04 16:01:01 martin
24  * Use common function setup_hr_time_cycles_from_timestamp_cycles().
25  * Made snprint_chk_time_info() more flexible.
26  * Revision 1.1 2012/05/29 09:52:26 martin
27  * Initial revision.
28  *
29  **************************************************************************/
30 
31 #define _CHK_TIME_INFO
32  #include <chk_time_info.h>
33 #undef _CHK_TIME_INFO
34 
35 #include <str_util.h>
36 #include <toolutil.h>
37 
38 #include <stdio.h>
39 
40 
41 
42 // This variable needs to be instantiated and set up by
43 // the main project. If the cycles frequenc hasn't been
44 // determined, i.e. its value is 0, the cycles differences
45 // can't be converted to time intervals, and thus the latency
46 // of the calls can't be compensated.
48 
49 
50 
51 static /*HDR*/
61 {
63  p->entries++;
64 
65  if ( ++( p->index ) >= MAX_CYCLES_FILTER_ENTRIES )
66  p->index = 0;
67 
68  // update the sum of filter entries
69  p->sum -= p->cyc[p->index]; // subtract oldest sample
70  p->cyc[p->index] = cyc; // save new sample
71  p->sum += cyc; // add new sample
72 
73  return p->sum / p->entries; // return mean value
74 
75 } /* do_filter */
76 
77 
78 
79 /*HDR*/
115 int mbg_chk_time_info( MBG_DEV_HANDLE dh, MBG_CHK_TIME_INFO *p, CYCLES_FILTER_DATA *p_filter, int fast_ts_only )
116 {
117  MBG_PC_CYCLES tmp;
118  PCPS_TIME_STAMP *p_ref_ts;
119  MBG_PC_CYCLES *p_ref_cyc;
120  MBG_SYS_TIME_CYCLES *p_sys_tic;
121  int rc;
122 
123  memset( p, 0, sizeof( *p ) );
124 
125  if ( fast_ts_only )
126  {
127  // We are to read the current system time and the time stamp
128  // as ::PCPS_TIME_STAMP_CYCLES from a device.
130 
131  rc = mbg_get_time_info_tstamp( dh, &tsi );
132 
133  // For subsequent processing we have to conver this to the
134  // same data format that is used if the flag has not been set.
137  }
138  else
139  rc = mbg_get_time_info_hrt( dh, &p->hrti );
140 
141  if ( mbg_rc_is_error( rc ) )
142  return rc;
143 
144 
145  // Setup some pointers to make subsequent code clearer.
146  p_ref_ts = &p->hrti.ref_hr_time_cycles.t.tstamp; // the reference timestamp from the device
147  p_ref_cyc = &p->hrti.ref_hr_time_cycles.cycles; // the reference time cycles
148  p_sys_tic = &p->hrti.sys_time_cycles; // the system time cycles
149 
150  // Convert both timestamps to floating point format.
151 
152  p->d_sys = (double) p_sys_tic->sys_time.secs + ( (double) p_sys_tic->sys_time.nano_secs / NSEC_PER_SEC );
153  p->d_ref = (double) p_ref_ts->sec + ( ( (double) p_ref_ts->frac ) / (double) MBG_FRAC32_UNITS_PER_SEC );
154 
155  // Compute the cycles deltas and limit.
156  p->ltcy_cyc = mbg_delta_pc_cycles( p_ref_cyc, &p_sys_tic->cyc_after );
157  p->exec_cyc = mbg_delta_pc_cycles( &p_sys_tic->cyc_after, &p_sys_tic->cyc_before );
158  p->exec_cyc_limit = p_filter ? do_filter( p_filter, p->exec_cyc ) : 0;
159 
160  if ( cyc_freq )
161  {
162  // If the cycles frequency is known, also
163  // compute the cycles deltas and limit as [s].
164  p->ltcy_sec = ( (double) p->ltcy_cyc ) / (double) cyc_freq;
165  p->exec_sec = ( (double) p->exec_cyc ) / (double) cyc_freq;
166  p->exec_sec_limit = ( (double) p->exec_cyc_limit ) / (double) cyc_freq;
167  }
168 
169  // The system timestamp and device timestamp have been read
170  // after each other, with associated cycles numbers.
171  // Use the delta cycles to normalize the device timestamp
172  // and relate it to the system timestamp.
173  p->d_ref_comp = p->d_ref - p->ltcy_sec;
174 
175  // Try to set the limit to 1.7 of the mean execution cycles.
176  tmp = ( 7 * p->exec_cyc_limit ) / 10;
177 
178  // If execution takes only a few cycles make sure the limit
179  // is above the mean number of cycles.
180  if ( tmp == 0 )
181  tmp++;
182 
183  p->exec_cyc_limit += tmp;
184 
185  return MBG_SUCCESS;
186 
187 } // mbg_chk_time_info
188 
189 
190 
191 /*HDR*/
206 int snprint_chk_time_info( char *s, size_t max_len, const MBG_CHK_TIME_INFO *p, const PCPS_DEV *p_dev,
207  int frac_digits, int print_raw )
208 {
209  size_t n = 0;
210 
211  if ( p_dev )
212  n += snprintf_safe( &s[n], max_len - n, "%-9s: ", _pcps_type_name( p_dev ) );
213 
214  n += mbg_snprint_hr_tstamp( &s[n], max_len - n, &p->hrti.ref_hr_time_cycles.t.tstamp, 0, 0 ); // raw timestamp?
215 
216  n += snprintf_safe( &s[n], max_len - n, " %.*f %.*f ",
217  frac_digits, p->d_ref,
218  frac_digits, p->d_sys );
219 
220  n += snprintf_safe( &s[n], max_len - n, "%+.*f, ltcy: ",
221  frac_digits, p->d_ref_comp - p->d_sys );
222 
223 
224  if ( cyc_freq ) // print latency and execution time in microseconds
225  {
226  n += snprintf_safe( &s[n], max_len - n, "%.2f us, exec: %.2f us, limit: %.2f us",
227  p->ltcy_sec * 1e6, p->exec_sec * 1e6, p->exec_sec_limit * 1e6 );
228  }
229  else // print latency and execution time in cycles only
230  {
231  n += snprintf_safe( &s[n], max_len - n, "%" PRIi64 " cyc, exec: %" PRIi64 " cyc, limit: %" PRIi64 " cyc",
232  (int64_t) p->ltcy_cyc, (int64_t) p->exec_cyc,
233  (int64_t) p->exec_cyc_limit );
234  }
235 
236  if ( print_raw )
237  n += snprintf_safe( &s[n], max_len - n, ", raw: %+.*f",
238  frac_digits, p->d_ref - p->d_sys );
239 
240  return _int_from_size_t( n );
241 
242 } // snprint_chk_time_info
243 
int mbg_snprint_hr_tstamp(char *s, size_t max_len, const PCPS_TIME_STAMP *p, long utc_offs, int show_raw)
Print date and time from a PCPS_TIME_STAMP structure to a string.
Definition: toolutil.c:799
MBG_PC_CYCLES exec_cyc
Computed execution time of the call, in [cycles].
Definition: chk_time_info.h:88
#define MAX_CYCLES_FILTER_ENTRIES
Definition: chk_time_info.h:57
MBG_SYS_TIME_CYCLES sys_time_cycles
system time stamp plus associated cycles
Definition: pcpsdev.h:1421
static MBG_PC_CYCLES do_filter(CYCLES_FILTER_DATA *p, MBG_PC_CYCLES cyc)
Compute the mean value of a number of cycles.
Definition: chk_time_info.c:60
PCPS_HR_TIME t
Definition: pcpsdev.h:1395
System time plus associated cycles counter values.
Definition: pcpsdev.h:386
MBG_PC_CYCLES cycles
Definition: pcpsdev.h:1394
PCPS_SECONDS sec
seconds since 1970, usually UTC scale
Definition: pcpsdefs.h:974
#define _int_from_size_t(_n)
Definition: words.h:662
double d_ref
Raw reference timestamp in floating point format, [s].
Definition: chk_time_info.h:96
static int print_raw
Definition: mbgcmptime.c:63
MBG_PC_CYCLES cyc_before
cycles count before sys time is read
Definition: pcpsdev.h:388
double exec_sec_limit
Execution time limit, in [s]. Only available if cycles frequency is known.
Definition: chk_time_info.h:93
int index
Index of the "current" cycles value.
Definition: chk_time_info.h:72
double d_ref_comp
Compensated reference timestamp in floating point format, [s].
Definition: chk_time_info.h:97
MBG_SYS_TIME_CYCLES sys_time_cycles
system timestamp plus associated cycles
Definition: pcpsdev.h:1448
MBG_TIME_INFO_HRT hrti
System time, device time, and cycles read from the driver.
Definition: chk_time_info.h:85
double ltcy_sec
Computed latency of the call, in [s]. Only available if cycles frequency is known.
Definition: chk_time_info.h:91
A structure to store the results of the mbg_chk_time_info routine.
Definition: chk_time_info.h:83
_MBG_API_ATTR int _MBG_API mbg_get_time_info_hrt(MBG_DEV_HANDLE dh, MBG_TIME_INFO_HRT *p)
Read both system time and associated device time from the kernel driver.
Definition: mbgdevio.c:7626
High resolution device time stamp, system time, and associated cycles counts.
Definition: pcpsdev.h:1445
MBG_PC_CYCLES sum
The current sum of the cycles values.
Definition: chk_time_info.h:70
MBG_PC_CYCLES exec_cyc_limit
Execution time limit, in [cycles], computed based on usual execution time.
Definition: chk_time_info.h:89
MBG_PC_CYCLES cyc[32]
The last recent values to be filtered.
Definition: chk_time_info.h:69
PCPS_FRAC_32 frac
binary fractions of second, see PCPS_FRAC_32
Definition: pcpsdefs.h:975
double exec_sec
Computed execution time of the call, in [s]. Only available if cycles frequency is known...
Definition: chk_time_info.h:92
PCPS_TIME_STAMP tstamp
High resolution time stamp (UTC)
Definition: pcpsdefs.h:1087
MBG_SYS_TIME sys_time
system time stamp
Definition: pcpsdev.h:390
PCPS_TIME_STAMP_CYCLES ref_tstamp_cycles
HR timestamp from the card, plus cycles.
Definition: pcpsdev.h:1447
__int64 int64_t
Definition: words.h:249
MBG_PC_CYCLES ltcy_cyc
Computed latency of the call, in [cycles].
Definition: chk_time_info.h:87
static int frac_digits
Definition: mbgsvcd.c:91
#define MBG_FRAC32_UNITS_PER_SEC
Constant used to convert e.g. PCPS_TIME_STAMP::frac values.
Definition: mbgtime.h:400
#define MBG_SUCCESS
Error codes used with Meinberg devices and drivers.
Definition: mbgerror.h:259
PCPS_HR_TIME_CYCLES ref_hr_time_cycles
HR time read from the card, plus cycles.
Definition: pcpsdev.h:1420
MBG_PC_CYCLES cyc_after
cycles count after sys time has been read
Definition: pcpsdev.h:389
MBG_PC_CYCLES_FREQUENCY cyc_freq
Definition: mbgcmptime.c:72
int entries
The number of cycles values already saved.
Definition: chk_time_info.h:71
uint64_t MBG_PC_CYCLES_FREQUENCY
Definition: mbgpccyc.h:98
static __mbg_inline MBG_PC_CYCLES mbg_delta_pc_cycles(const MBG_PC_CYCLES *p1, const MBG_PC_CYCLES *p2)
Definition: mbgpccyc.h:296
int mbg_chk_time_info(MBG_DEV_HANDLE dh, MBG_CHK_TIME_INFO *p, CYCLES_FILTER_DATA *p_filter, int fast_ts_only)
Read and evaluate a system timestamp / reference timestamp pair.
#define NSEC_PER_SEC
Definition: mbgtime.h:264
A high resolution time stamp.
Definition: pcpsdefs.h:972
#define _pcps_type_name(_d)
Definition: pcpsdev.h:1068
int snprintf_safe(char *s, size_t max_len, const char *fmt,...)
A portable, safe implementation of snprintf()
Definition: str_util.c:156
#define mbg_rc_is_error(_rc)
Definition: mbgerror.h:617
int64_t nano_secs
[nanoseconds]
Definition: words.h:628
_MBG_API_ATTR int _MBG_API mbg_get_time_info_tstamp(MBG_DEV_HANDLE dh, MBG_TIME_INFO_TSTAMP *p)
Read both system time and associated device timestamp from the kernel driver.
Definition: mbgdevio.c:7659
int64_t secs
[seconds], usually since 1970-01-01 00:00:00
Definition: words.h:627
int snprint_chk_time_info(char *s, size_t max_len, const MBG_CHK_TIME_INFO *p, const PCPS_DEV *p_dev, int frac_digits, int print_raw)
Print info from a MBG_CHK_TIME_INFO structure into a string buffer.
int64_t MBG_PC_CYCLES
Generic types to hold PC cycle counter values.
Definition: mbgpccyc.h:97
A structure to keep filter data for cycles values.
Definition: chk_time_info.h:67
double d_sys
System timestamp in floating point format, [s].
Definition: chk_time_info.h:95
static __mbg_inline void setup_hr_time_cycles_from_timestamp_cycles(PCPS_HR_TIME_CYCLES *p_ht_c, const PCPS_TIME_STAMP_CYCLES *p_ts_c)
Definition: pcpsdev.h:1500
Device info structure.
Definition: pcpsdev.h:1043