Skip to content

Commit

Permalink
Support systems without clock_gettime()
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Edmonds committed Apr 23, 2016
1 parent 5bddf64 commit c5f0912
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 35 deletions.
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ AX_PTHREAD([
])

AC_SEARCH_LIBS([clock_gettime], [rt])
AC_CHECK_FUNCS([clock_gettime])

AC_SEARCH_LIBS([socket], [socket])

AC_CHECK_DECLS([fread_unlocked, fwrite_unlocked, fflush_unlocked])
Expand Down
7 changes: 4 additions & 3 deletions fstrm/fstrm-private.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 by Farsight Security, Inc.
* Copyright (c) 2013-2016 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,6 +36,7 @@
#include "libmy/my_alloc.h"
#include "libmy/my_memory_barrier.h"
#include "libmy/my_queue.h"
#include "libmy/my_time.h"
#include "libmy/read_bytes.h"
#include "libmy/vector.h"

Expand Down Expand Up @@ -162,15 +163,15 @@ fstrm__rdwr_write_control(struct fstrm_rdwr *,

/* time */

#if HAVE_CLOCK_GETTIME
bool fstrm__get_best_monotonic_clock_gettime(clockid_t *);

bool fstrm__get_best_monotonic_clock_pthread(clockid_t *);

bool fstrm__get_best_monotonic_clocks(clockid_t *clkid_gettime,
clockid_t *clkid_pthread,
char **errstr_out);

int fstrm__pthread_cond_timedwait(clockid_t, pthread_cond_t *, pthread_mutex_t *, unsigned);
#endif

/* queue */

Expand Down
31 changes: 25 additions & 6 deletions fstrm/iothr.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 by Farsight Security, Inc.
* Copyright (c) 2013-2016 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -81,9 +81,11 @@ struct fstrm_iothr {
/* Whether the I/O thread is shutting down. */
volatile bool shutting_down;

#if HAVE_CLOCK_GETTIME
/* Optimal clockid_t's. */
clockid_t clkid_gettime;
clockid_t clkid_pthread;
#endif

/*
* Conditional variable and lock, used by producer thread
Expand Down Expand Up @@ -262,13 +264,15 @@ fstrm_iothr_init(const struct fstrm_iothr_options *opt,
iothr->queue_ops = &my_queue_mutex_ops;
}

#if HAVE_CLOCK_GETTIME
/* Detect best clocks. */
if (!fstrm__get_best_monotonic_clocks(&iothr->clkid_gettime,
&iothr->clkid_pthread,
NULL))
{
goto fail;
}
#endif

/* Initialize the input queues. */
iothr->queues = my_calloc(iothr->opt.num_input_queues,
Expand All @@ -290,8 +294,10 @@ fstrm_iothr_init(const struct fstrm_iothr_options *opt,
res = pthread_condattr_init(&ca);
assert(res == 0);

#if HAVE_CLOCK_GETTIME
res = pthread_condattr_setclock(&ca, iothr->clkid_pthread);
assert(res == 0);
#endif

res = pthread_cond_init(&iothr->cv, &ca);
assert(res == 0);
Expand Down Expand Up @@ -544,13 +550,16 @@ fstrm__iothr_maybe_open(struct fstrm_iothr *iothr)
if (likely(iothr->opened))
return;

int rv;
time_t since;
struct timespec ts;

/* Check if the reopen interval has expired yet. */
rv = clock_gettime(iothr->clkid_gettime, &ts);
#if HAVE_CLOCK_GETTIME
int rv = clock_gettime(iothr->clkid_gettime, &ts);
assert(rv == 0);
#else
my_gettime(-1, &ts);
#endif
since = ts.tv_sec - iothr->last_open_attempt;
if (since < (time_t) iothr->opt.reopen_interval)
return;
Expand Down Expand Up @@ -598,9 +607,19 @@ fstrm__iothr_thr(void *arg)
if (count != 0)
continue;

res = fstrm__pthread_cond_timedwait(iothr->clkid_pthread,
&iothr->cv, &iothr->cv_lock,
iothr->opt.flush_timeout);
struct timespec ts;
#if HAVE_CLOCK_GETTIME
int rv = clock_gettime(iothr->clkid_pthread, &ts);
assert(rv == 0);
#else
my_gettime(-1, &ts);
#endif
ts.tv_sec += iothr->opt.flush_timeout;

pthread_mutex_lock(&iothr->cv_lock);
res = pthread_cond_timedwait(&iothr->cv, &iothr->cv_lock, &ts);
pthread_mutex_unlock(&iothr->cv_lock);

if (res == ETIMEDOUT)
fstrm__iothr_flush_output(iothr);
}
Expand Down
21 changes: 4 additions & 17 deletions fstrm/time.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 by Farsight Security, Inc.
* Copyright (c) 2013-2016 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,8 @@

#include "fstrm-private.h"

#if HAVE_CLOCK_GETTIME

bool
fstrm__get_best_monotonic_clock_pthread(clockid_t *c)
{
Expand Down Expand Up @@ -125,19 +127,4 @@ fstrm__get_best_monotonic_clocks(clockid_t *clkid_gettime,
return true;
}

int
fstrm__pthread_cond_timedwait(clockid_t clock_id,
pthread_cond_t *cond,
pthread_mutex_t *mutex,
unsigned seconds)
{
int res;
struct timespec ts;
res = clock_gettime(clock_id, &ts);
assert(res == 0);
ts.tv_sec += seconds;
pthread_mutex_lock(mutex);
res = pthread_cond_timedwait(cond, mutex, &ts);
pthread_mutex_unlock(mutex);
return res;
}
#endif /* HAVE_CLOCK_GETTIME */
12 changes: 9 additions & 3 deletions t/test_fstrm_io_file.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 by Farsight Security, Inc.
* Copyright (c) 2013-2016 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -272,7 +272,13 @@ main(int argc, char **argv)
assert(0); /* not reached */
}

my_gettime(CLOCK_MONOTONIC, &ts_a);
#if HAVE_CLOCK_GETTIME
const clockid_t clock = CLOCK_MONOTONIC;
#else
const int clock = -1;
#endif
my_gettime(clock, &ts_a);


printf("creating %u producer threads\n", num_threads);
for (unsigned i = 0; i < num_threads; i++)
Expand All @@ -285,7 +291,7 @@ main(int argc, char **argv)
printf("destroying fstrm_iothr object\n");
fstrm_iothr_destroy(&iothr);

my_gettime(CLOCK_MONOTONIC, &ts_b);
my_gettime(clock, &ts_b);
my_timespec_sub(&ts_a, &ts_b);
elapsed = my_timespec_to_double(&ts_b);
printf("completed in %.2f seconds\n", elapsed);
Expand Down
11 changes: 8 additions & 3 deletions t/test_fstrm_io_unix.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 by Farsight Security, Inc.
* Copyright (c) 2013-2016 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -443,7 +443,12 @@ main(int argc, char **argv)
assert(0); /* not reached */
}

my_gettime(CLOCK_MONOTONIC, &ts_a);
#if HAVE_CLOCK_GETTIME
const clockid_t clock = CLOCK_MONOTONIC;
#else
const int clock = -1;
#endif
my_gettime(clock, &ts_a);

printf("creating %u producer threads\n", num_threads);
for (unsigned i = 0; i < num_threads; i++)
Expand All @@ -459,7 +464,7 @@ main(int argc, char **argv)
printf("joining consumer thread\n");
pthread_join(test_consumer.thr, (void **) NULL);

my_gettime(CLOCK_MONOTONIC, &ts_b);
my_gettime(clock, &ts_b);
my_timespec_sub(&ts_a, &ts_b);
elapsed = my_timespec_to_double(&ts_b);
printf("completed in %.2f seconds\n", elapsed);
Expand Down
11 changes: 8 additions & 3 deletions t/test_queue.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 by Farsight Security, Inc.
* Copyright (c) 2013-2016 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -235,7 +235,12 @@ run_test(void)
pthread_t thr_p;
pthread_t thr_c;

my_gettime(CLOCK_MONOTONIC, &ts_a);
#if HAVE_CLOCK_GETTIME
const clockid_t clock = CLOCK_MONOTONIC;
#else
const int clock = -1;
#endif
my_gettime(clock, &ts_a);

pthread_create(&thr_p, NULL, thr_producer, NULL);
pthread_create(&thr_c, NULL, thr_consumer, NULL);
Expand All @@ -247,7 +252,7 @@ run_test(void)
send_shutdown_message(q);
pthread_join(thr_c, (void **) &cs);

my_gettime(CLOCK_MONOTONIC, &ts_b);
my_gettime(clock, &ts_b);

res = check_stats(ps, cs);
print_stats(&ts_a, &ts_b, ps, cs);
Expand Down

0 comments on commit c5f0912

Please sign in to comment.