From: Cyril Hrubis <chrubis@suse.cz>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v3 3/7] fzsync: Add long running thread support and deviation stats
Date: Tue, 12 Sep 2017 16:41:37 +0200 [thread overview]
Message-ID: <20170912144137.GD29720@rei> (raw)
In-Reply-To: <20170901130121.22821-3-rpalethorpe@suse.com>
Hi!
> +/**
> + * tst_fzsync_pair_info - Print some synchronisation statistics
> + */
> static void tst_fzsync_pair_info(struct tst_fzsync_pair *pair)
> {
> - tst_res(TINFO, "avg_diff = %.5gns, delay = %05ld loops",
> - pair->avg_diff, pair->delay);
> + tst_res(TINFO,
> + "avg_diff = %.0fns, avg_dev = %.0fns, delay = %05ld loops",
> + pair->avg_diff, pair->avg_dev, pair->delay);
> }
>
> /**
> @@ -133,18 +161,15 @@ static inline void tst_fzsync_time_b(struct tst_fzsync_pair *pair)
> }
>
> /**
> - * tst_exp_moving_avg - Exponential moving average
> + * TST_EXP_MOVING_AVG - Exponential moving average
> * @alpha: The preference for recent samples over old ones.
> * @sample: The current sample
> * @prev_avg: The average of the all the previous samples
> *
> * Returns average including the current sample.
> */
> -static inline double tst_exp_moving_avg(double alpha, long sample,
> - double prev_avg)
> -{
> - return alpha * sample + (1.0 - alpha) * prev_avg;
> -}
> +#define TST_EXP_MOVING_AVG(alpha, sample, prev_avg)\
> + (alpha * sample + (1.0 - alpha) * prev_avg)
Why do we define this as a macro instead of static inline function? As
far as I can tell the only difference is that we loose type checks and
introduce possible side effects.
> /**
> * tst_fzsync_pair_update - Recalculate the delay
> @@ -169,8 +194,16 @@ static void tst_fzsync_pair_update(int loop_index, struct tst_fzsync_pair *pair)
> double target = pair->avg_diff_trgt;
> double avg = pair->avg_diff;
>
> + if (pair->a.tv_sec > pair->b.tv_sec)
> + pair->a.tv_nsec += 1000000000;
> + else if (pair->a.tv_sec < pair->b.tv_sec)
> + pair->b.tv_nsec += 1000000000;
Why the else here? These two cases are mutually exclusive.
> diff = pair->a.tv_nsec - pair->b.tv_nsec;
> - avg = tst_exp_moving_avg(pair->avg_alpha, diff, avg);
> + avg = TST_EXP_MOVING_AVG(pair->avg_alpha, diff, avg);
> + pair->avg_dev = TST_EXP_MOVING_AVG(pair->avg_alpha,
> + fabs(diff - avg),
> + pair->avg_dev);
>
> if (!(loop_index & pair->update_gap)) {
> if (avg > target)
> @@ -179,5 +212,87 @@ static void tst_fzsync_pair_update(int loop_index, struct tst_fzsync_pair *pair)
> pair->delay += inc;
> }
>
> + if (!(loop_index & pair->info_gap))
> + tst_fzsync_pair_info(pair);
> +
> pair->avg_diff = avg;
> }
> +
> +/**
> + * tst_fzsync_pair_wait - Wait for the other thread
> + * @our_cntr: The counter for the thread we are on
> + * @other_cntr: The counter for the thread we are synchronising with
> + *
> + * Use this (through tst_fzsync_pair_wait_a() and tst_fzsync_pair_wait_b()) if
> + * you need an additional synchronisation point in a thread or you do not want
> + * to use the delay facility (not recommended). See
> + * tst_fzsync_pair_wait_update().
> + *
> + * Returns a non-zero value if the thread should continue otherwise the
> + * calling thread should exit.
> + */
> +static inline int tst_fzsync_pair_wait(struct tst_fzsync_pair *pair,
> + int *our_cntr, int *other_cntr)
> +{
> + tst_atomic_inc(other_cntr);
> + while (tst_atomic_load(our_cntr) < tst_atomic_load(other_cntr)
> + && !tst_atomic_load(&pair->exit))
> + ;
> +
> + return !tst_atomic_load(&pair->exit);
> +}
> +
> +static inline int tst_fzsync_wait_a(struct tst_fzsync_pair *pair)
> +{
> + return tst_fzsync_pair_wait(pair, &pair->a_cntr, &pair->b_cntr);
> +}
> +
> +static inline int tst_fzsync_wait_b(struct tst_fzsync_pair *pair)
> +{
> + return tst_fzsync_pair_wait(pair, &pair->b_cntr, &pair->a_cntr);
> +}
> +
> +/**
> + * tst_fzsync_pair_wait_update_{a,b} - Wait and then recalculate
> + *
> + * This allows you to have two long running threads which wait for each other
> + * every iteration. So each thread will exit this function at approximately
> + * the same time. It also updates the delay values in a thread safe manner.
> + *
> + * You must call this function in both threads the same number of times each
> + * iteration. So a call in one thread must match with a call in the
> + * other. Make sure that calls to tst_fzsync_pair_wait() and
> + * tst_fzsync_pair_wait_update() happen in the same order in each thread. That
> + * is, make sure that a call to tst_fzsync_pair_wait_update_a() in one thread
> + * corresponds to a call to tst_fzsync_pair_wait_update_b() in the other.
> + *
> + * Returns a non-zero value if the calling thread should continue to loop. If
> + * it returns zero then tst_fzsync_exit() has been called and you must exit
> + * the thread.
> + */
> +static inline int tst_fzsync_wait_update_a(struct tst_fzsync_pair *pair)
> +{
> + static int loop_index;
> +
> + tst_fzsync_pair_wait(pair, &pair->a_cntr, &pair->b_cntr);
> + loop_index++;
> + tst_fzsync_pair_update(loop_index, pair);
> + return tst_fzsync_pair_wait(pair, &pair->a_cntr, &pair->b_cntr);
> +}
> +
> +static inline int tst_fzsync_wait_update_b(struct tst_fzsync_pair *pair)
> +{
> + tst_fzsync_pair_wait(pair, &pair->b_cntr, &pair->a_cntr);
> + return tst_fzsync_pair_wait(pair, &pair->b_cntr, &pair->a_cntr);
> +}
> +
> +/**
> + * tst_fzsync_pair_exit - Signal that the other thread should exit
> + *
> + * Causes tst_fzsync_pair_wait() and tst_fzsync_pair_wait_update() to return
> + * 0.
> + */
> +static inline void tst_fzsync_pair_exit(struct tst_fzsync_pair *pair)
> +{
> + tst_atomic_store(1, &pair->exit);
> +}
> --
> 2.14.1
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
--
Cyril Hrubis
chrubis@suse.cz
next prev parent reply other threads:[~2017-09-12 14:41 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-01 13:01 [LTP] [PATCH v3 1/7] tst_atomic: Add load, store and use __atomic builtins Richard Palethorpe
2017-09-01 13:01 ` [LTP] [PATCH v3 2/7] tst_atomic: Add atomic store and load tests Richard Palethorpe
2017-09-12 13:15 ` Cyril Hrubis
2017-09-01 13:01 ` [LTP] [PATCH v3 3/7] fzsync: Add long running thread support and deviation stats Richard Palethorpe
2017-09-12 14:41 ` Cyril Hrubis [this message]
2017-09-15 9:10 ` Richard Palethorpe
2017-09-15 12:48 ` Cyril Hrubis
2017-09-12 14:43 ` Cyril Hrubis
2017-09-15 10:05 ` Richard Palethorpe
2017-09-15 12:51 ` Richard Palethorpe
2017-09-15 12:54 ` Cyril Hrubis
2017-09-01 13:01 ` [LTP] [PATCH v3 4/7] fzsync: Add functionality test for library Richard Palethorpe
2017-09-12 14:08 ` Cyril Hrubis
2017-09-22 11:43 ` Richard Palethorpe
2017-09-01 13:01 ` [LTP] [PATCH v3 5/7] Convert cve-2016-7117 test to use long running threads Richard Palethorpe
2017-09-01 13:01 ` [LTP] [PATCH v3 6/7] Convert cve-2014-0196 " Richard Palethorpe
2017-09-01 13:01 ` [LTP] [PATCH v3 7/7] Convert cve-2017-2671 " Richard Palethorpe
2017-09-12 12:40 ` [LTP] [PATCH v3 1/7] tst_atomic: Add load, store and use __atomic builtins Cyril Hrubis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170912144137.GD29720@rei \
--to=chrubis@suse.cz \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.