delay: use parse_ts for parsing delay value

* delay.c (fill_delay_data): Change intval argument to struct timespec
*val, assign val to ts.
* delay.h (fill_delay_data): Update function declaration.
* filter_qualify.c (parse_delay_token): Parse input with parse_ts,
supply the resulting struct timespec to fill_delay_data.
* tests/delay.c (check_): New function for providing diagnostic in case
of check failure.
(check_delay): Use it.
* tests/delay.test: Check new delay syntax.
This commit is contained in:
Eugene Syromyatnikov 2018-09-02 21:28:41 +02:00
parent 32e987b87a
commit 1a28b6dba2
5 changed files with 40 additions and 23 deletions

View File

@ -66,7 +66,7 @@ alloc_delay_data(void)
}
void
fill_delay_data(uint16_t delay_idx, int intval, bool isenter)
fill_delay_data(uint16_t delay_idx, struct timespec *val, bool isenter)
{
if (delay_idx >= delay_data_vec_size)
error_func_msg_and_die("delay_idx >= delay_data_vec_size");
@ -77,8 +77,7 @@ fill_delay_data(uint16_t delay_idx, int intval, bool isenter)
else
ts = &(delay_data_vec[delay_idx].ts_exit);
ts->tv_sec = intval / 1000000;
ts->tv_nsec = intval % 1000000 * 1000;
*ts = *val;
}
static bool

View File

@ -29,7 +29,7 @@
#define STRACE_DELAY_H
uint16_t alloc_delay_data(void);
void fill_delay_data(uint16_t delay_idx, int intval, bool isenter);
void fill_delay_data(uint16_t delay_idx, struct timespec *val, bool isenter);
bool is_delay_timer_armed(void);
void delay_timer_expired(void);
void arm_delay_timer(const struct tcb *);

View File

@ -92,14 +92,15 @@ parse_delay_token(const char *input, struct inject_opts *fopts, bool isenter)
if (fopts->data.flags & flag) /* duplicate */
return false;
long long intval = string_to_ulonglong(input);
if (intval < 0) /* couldn't parse */
struct timespec tsval;
if (parse_ts(input, &tsval) < 0) /* couldn't parse */
return false;
if (fopts->data.delay_idx == (uint16_t) -1)
fopts->data.delay_idx = alloc_delay_data();
/* populate .ts_enter or .ts_exit */
fill_delay_data(fopts->data.delay_idx, intval, isenter);
fill_delay_data(fopts->data.delay_idx, &tsval, isenter);
fopts->data.flags |= flag;
return true;

View File

@ -28,6 +28,7 @@
*/
#include "tests.h"
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdint.h>
@ -50,6 +51,22 @@ usecs_from_ts(const struct timespec *const ts)
return (int64_t) ts->tv_sec * 1000000 + ts->tv_nsec / 1000;
}
static void
check_(const int64_t got, const bool ge, const int64_t orig, const int nproc,
const int exitcode)
{
const int64_t thresh = (orig * (ge ? nproc - 1 : nproc + 1)) / nproc;
if (ge ? got >= thresh : got <= thresh)
return;
fprintf(stderr, "Got delay of %" PRId64 ", %s than threshold value of "
"%" PRId64 " (expected nominal delay value is %" PRId64
")\n", got, ge ? "less" : "more", thresh, orig);
_exit(exitcode);
}
static void
check_delay(const struct timeval *const tv0,
const struct timespec *const ts,
@ -62,17 +79,10 @@ check_delay(const struct timeval *const tv0,
const int64_t us = usecs_from_ts(ts);
const int64_t us1 = usecs_from_tv(tv1);
if (us - us0 < delay_exit * (nproc - 1) / nproc)
_exit(1);
if (us - us0 > delay_exit * (nproc + 1) / nproc)
_exit(2);
if (us1 - us < delay_enter * (nproc - 1) / nproc)
_exit(3);
if (us1 - us > delay_enter * (nproc + 1) / nproc)
_exit(4);
check_(us - us0, true, delay_exit, nproc, 1);
check_(us - us0, false, delay_exit, nproc, 2);
check_(us1 - us, true, delay_enter, nproc, 3);
check_(us1 - us, false, delay_enter, nproc, 4);
}
static void

View File

@ -3,8 +3,15 @@
. "${srcdir=.}/init.sh"
delay_enter=800000
delay_exit=1600000
run_strace -f -r -egettimeofday \
-einject=gettimeofday:delay_enter=$delay_enter:delay_exit=$delay_exit \
../delay 4 $delay_enter $delay_exit
while read -r denter dexit denter_us dexit_us; do
[ -n denter ] || continue
run_strace -f -r -egettimeofday \
-einject=gettimeofday:delay_enter=$denter:delay_exit=$dexit \
../delay 4 $denter_us $dexit_us
done <<-EOF
800000 1600000 800000 1600000
8e5 1.6s 800000 1600000
800ms 1.6e+6us 800000 1600000
+8e8ns .16E7 800000 1600000
EOF