Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tammo Jan Dijkema
dt_ctrl
Commits
4d0ee609
Commit
4d0ee609
authored
Nov 25, 2014
by
Jeroen Vreeken
Browse files
Improve time measurement
parent
b185a42f
Changes
1
Hide whitespace changes
Inline
Side-by-side
controller/controller/controller_sample.c
View file @
4d0ee609
...
...
@@ -35,6 +35,7 @@
#include <sched.h>
#include <dirent.h>
#include <ctype.h>
#include <inttypes.h>
#include <controller/controller_block.h>
#include <controller/controller_sample.h>
...
...
@@ -50,9 +51,9 @@ static pthread_t controller_sample_thread;
static
bool
controller_sample_thread_running
=
false
;
struct
sample_timing
{
double
min
;
double
max
;
double
avg
;
uint64_t
min
;
uint64_t
max
;
uint64_t
sum
;
long
long
n
;
char
*
name
;
};
...
...
@@ -90,31 +91,21 @@ static void sample_timing_init(struct sample_timing *st, char *name)
{
memset
(
st
,
0
,
sizeof
(
struct
sample_timing
));
st
->
name
=
name
;
st
->
min
=
10000000000ull
;
}
static
void
sample_timing_add
(
struct
sample_timing
*
st
,
struct
timespec
*
t1
,
struct
timespec
*
t2
)
static
void
sample_timing_add
(
struct
sample_timing
*
st
,
uint64_t
t1
,
uint64_t
t2
)
{
double
t
;
int64_t
t
;
t
=
t2
->
tv_nsec
*
1
.
0
-
t1
->
tv_nsec
*
1
.
0
;
t
+=
(
t2
->
tv_sec
-
t1
->
tv_sec
)
*
1000000000
;
if
(
st
->
n
==
0
)
{
st
->
min
=
t
;
st
->
max
=
t
;
st
->
avg
=
t
;
st
->
n
=
1
;
return
;
}
t
=
t2
-
t1
;
if
(
t
>
st
->
max
)
st
->
max
=
t
;
if
(
t
<
st
->
min
)
st
->
min
=
t
;
st
->
avg
=
st
->
avg
*
st
->
n
+
t
;
st
->
sum
+
=
t
;
st
->
n
++
;
st
->
avg
/=
st
->
n
*
1
.
0
;
return
;
}
...
...
@@ -134,27 +125,22 @@ static ssize_t sample_timing_snprintf(struct sample_timing *st,
char
*
dest
,
size_t
n
)
{
return
snprintf
(
dest
,
n
,
"%s
\t
%.3f
\t
%.3f
\t
%.3f"
,
st
->
name
,
st
->
min
/
1000
.
0
,
st
->
avg
/
1000
.
0
,
st
->
max
/
1000
.
0
);
st
->
name
,
(
double
)
st
->
min
/
1000
.
0
,
((
double
)
st
->
sum
/
1000
.
0
)
/
(
double
)
st
->
n
,
(
double
)
st
->
max
/
1000
.
0
);
}
static
int
sample_timing_sane
(
struct
timespec
*
t_exp
,
struct
timespec
*
t_act
)
static
int
sample_timing_sane
(
uint64_t
t_exp
,
uint64_t
t_act
)
{
long
s_diff
;
long
n_diff
;
uint64_t
n_diff
;
s_diff
=
t_act
->
tv_sec
-
t_exp
->
tv_sec
;
if
(
t_exp
>
t_act
)
n_diff
=
t_exp
-
t_act
;
else
n_diff
=
t_act
-
t_exp
;
if
(
s_diff
<
0
)
{
return
-
1
;
}
if
(
s_diff
>
1
)
{
return
1
;
}
n_diff
=
s_diff
*
1000
*
1000
*
1000
;
n_diff
+=
t_act
->
tv_nsec
-
t_exp
->
tv_nsec
;
if
(
n_diff
>
nsec_interval
*
10
)
{
return
1
;
}
...
...
@@ -297,6 +283,15 @@ static void wait_next(struct timespec *t)
#endif
}
static
uint64_t
timestamp
(
void
)
{
struct
timespec
t
;
clock_gettime
(
sample_clock
,
&
t
);
return
(
uint64_t
)
t
.
tv_sec
*
1000000000
+
(
uint64_t
)
t
.
tv_nsec
;
}
/*
This thread should be realtime....
*/
...
...
@@ -304,9 +299,10 @@ static void *sample_thread(void *arg)
{
struct
timespec
t
;
struct
sched_param
param
;
struct
timespec
t_start
;
struct
timespec
t_io
;
struct
timespec
t_end
;
uint64_t
t_trig
;
uint64_t
t_start
;
uint64_t
t_io
;
uint64_t
t_end
;
param
.
sched_priority
=
99
;
sigset_t
sigset
;
struct
sigaction
sigact
;
...
...
@@ -338,8 +334,9 @@ static void *sample_thread(void *arg)
clock_gettime
(
sample_clock
,
&
t
);
t
.
tv_nsec
=
0
;
t
.
tv_sec
++
;
t
.
tv_nsec
+=
nsec_interval
-
1
;
t
.
tv_nsec
-=
t
.
tv_nsec
%
nsec_interval
;
tsnorm
(
&
t
);
while
(
1
)
{
/* Pre sample stuff: */
...
...
@@ -348,8 +345,9 @@ static void *sample_thread(void *arg)
t
.
tv_nsec
+=
nsec_interval
;
tsnorm
(
&
t
);
controller_time_nseconds
=
(
uint64_t
)
t
.
tv_sec
*
1000000000
;
controller_time_nseconds
+=
t
.
tv_nsec
;
t_trig
=
(
uint64_t
)
t
.
tv_sec
*
1000000000
;
t_trig
+=
t
.
tv_nsec
;
controller_time_nseconds
=
t_trig
;
controller_time_seconds
=
t
.
tv_sec
;
controller_time_samplenr
=
t
.
tv_nsec
/
nsec_interval
;
...
...
@@ -357,36 +355,35 @@ static void *sample_thread(void *arg)
(Internal timer or external interrupt) */
wait_next
(
&
t
);
clock_get
time
(
samp
le_clock
,
&
t_start
);
t_start
=
times
t
amp
(
);
/* Do sample stuff */
controller_block_calculate
();
clock_get
time
(
samp
le_clock
,
&
t_io
);
t_io
=
times
t
amp
(
);
controller_block_trace
();
controller_block_param_handle
();
clock_get
time
(
samp
le_clock
,
&
t_end
);
t_end
=
times
t
amp
(
);
if
(
sample_timing_diff_nsec
(
&
t
,
&
t_end
)
>
nsec_interval
)
{
if
(
t_end
-
t_trig
>
nsec_interval
)
{
controller_sampleoverruns
++
;
}
if
(
sample_timing_sane
(
&
t
,
&
t_start
))
{
if
(
sample_timing_sane
(
t
_trig
,
t_start
))
{
log_send
(
LOG_T_ERROR
,
"Time sanity check triggered: %lld.%09ld %lld.%09ld"
,
(
long
long
)
t
.
tv_sec
,
t
.
tv_nsec
,
(
long
long
)
t_start
.
tv_sec
,
t_start
.
tv_nsec
);
t
.
tv_sec
=
t_start
.
tv_sec
;
t
.
tv_nsec
=
(
t_start
.
tv_nsec
/
nsec_interval
)
*
nsec_interval
;
"Time sanity check triggered: %"
PRIu64
" nsec difference"
,
t_start
-
t_trig
);
clock_gettime
(
sample_clock
,
&
t
);
t
.
tv_nsec
-=
(
t
.
tv_nsec
%
nsec_interval
);
log_send
(
LOG_T_WARNING
,
"Using current time for next sampe: %lld.%09ld"
,
(
long
long
)
t
.
tv_sec
,
t
.
tv_nsec
);
}
else
{
sample_timing_add
(
&
st_start
,
&
t
,
&
t_start
);
sample_timing_add
(
&
st_io
,
&
t_start
,
&
t_io
);
sample_timing_add
(
&
st_end
,
&
t
,
&
t_end
);
sample_timing_add
(
&
st_sample
,
&
t_start
,
&
t_end
);
sample_timing_add
(
&
st_start
,
t
_trig
,
t_start
);
sample_timing_add
(
&
st_io
,
t_start
,
t_io
);
sample_timing_add
(
&
st_end
,
t
_trig
,
t_end
);
sample_timing_add
(
&
st_sample
,
t_start
,
t_end
);
}
alarm
(
1
);
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment