Add ddi_time_after and friends

When comparing times gotten from ddi_get_lbolt, we have to take account of
wrap around of jiffies. Therefore, we cannot use 't1 < t2'. Instead we should
use 't1 - t2 < 0'.

This patch add ddi_time_after and friends to address this issue. They have
strict type restriction, clock_t for vanilla and int64_t for 64 version, to
prevent type conversion from screwing things.

Signed-off-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #335
This commit is contained in:
Chunwei Chen 2014-02-25 17:16:55 +08:00 committed by Brian Behlendorf
parent 6c48cd8ac2
commit 545e9ac00a
2 changed files with 19 additions and 5 deletions

View File

@ -35,6 +35,20 @@
#define ddi_get_lbolt() ((clock_t)jiffies)
#define ddi_get_lbolt64() ((int64_t)get_jiffies_64())
#define ddi_time_before(a, b) (typecheck(clock_t, a) && \
typecheck(clock_t, b) && \
((a) - (b) < 0))
#define ddi_time_after(a, b) ddi_time_before(b, a)
#define ddi_time_before_eq(a, b) (!ddi_time_after(a, b))
#define ddi_time_after_eq(a, b) ddi_time_before_eq(b, a)
#define ddi_time_before64(a, b) (typecheck(int64_t, a) && \
typecheck(int64_t, b) && \
((a) - (b) < 0))
#define ddi_time_after64(a, b) ddi_time_before64(b, a)
#define ddi_time_before_eq64(a, b) (!ddi_time_after64(a, b))
#define ddi_time_after_eq64(a, b) ddi_time_before_eq64(b, a)
#define delay(ticks) schedule_timeout_uninterruptible(ticks)
#define SEC_TO_TICK(sec) ((sec) * HZ)

View File

@ -82,7 +82,7 @@ typedef struct splat_taskq_arg {
atomic_t *count;
int order[SPLAT_TASKQ_ORDER_MAX];
unsigned int depth;
unsigned long expire;
clock_t expire;
taskq_t *tq;
taskq_ent_t *tqe;
spinlock_t lock;
@ -1140,7 +1140,7 @@ splat_taskq_test9_func(void *arg)
splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
ASSERT(tq_arg);
if (ddi_get_lbolt() >= tq_arg->expire)
if (ddi_time_after_eq(ddi_get_lbolt(), tq_arg->expire))
atomic_inc(tq_arg->count);
kmem_free(tq_arg, sizeof(splat_taskq_arg_t));
@ -1228,7 +1228,7 @@ splat_taskq_test10_func(void *arg)
splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
uint8_t rnd;
if (ddi_get_lbolt() >= tq_arg->expire)
if (ddi_time_after_eq(ddi_get_lbolt(), tq_arg->expire))
atomic_inc(tq_arg->count);
/* Randomly sleep to further perturb the system */
@ -1249,7 +1249,7 @@ splat_taskq_test10(struct file *file, void *arg)
int canceled = 0;
int completed = 0;
int blocked = 0;
unsigned long start, cancel;
clock_t start, cancel;
tqas = vmalloc(sizeof(*tqas) * nr_tasks);
if (tqas == NULL)
@ -1327,7 +1327,7 @@ splat_taskq_test10(struct file *file, void *arg)
start = ddi_get_lbolt();
i = 0;
while (ddi_get_lbolt() < start + 5 * HZ) {
while (ddi_time_before(ddi_get_lbolt(), start + 5 * HZ)) {
taskqid_t id;
uint32_t rnd;