From 1a8e974d732b1ca345b3664fa86e95181d5acfce Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 23 Dec 2015 12:24:52 -0500 Subject: concurrency/future: Store min_wait as an integer to avoid divisions. --- libdimension/concurrency/future.c | 29 ++++++++++------------------- libdimension/internal/future.h | 4 ++-- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/libdimension/concurrency/future.c b/libdimension/concurrency/future.c index 90ffa24..7ef32c0 100644 --- a/libdimension/concurrency/future.c +++ b/libdimension/concurrency/future.c @@ -1,5 +1,5 @@ /************************************************************************* - * Copyright (C) 2009-2014 Tavian Barnes * + * Copyright (C) 2009-2015 Tavian Barnes * * * * This file is part of The Dimension Library. * * * @@ -46,7 +46,7 @@ dmnsn_new_future(void) dmnsn_initialize_mutex(&future->mutex); dmnsn_initialize_cond(&future->cond); - future->min_wait = 1.0; + future->min_wait = 1; future->nthreads = future->nrunning = 1; future->npaused = 0; @@ -101,17 +101,6 @@ dmnsn_future_cancel(dmnsn_future *future) pthread_cancel(future->thread); } -/** - * Get the current progress, without locking anything. - * - * future->mutex must be locked for this call to be safe. - */ -static inline double -dmnsn_future_progress_unlocked(const dmnsn_future *future) -{ - return (double)future->progress/future->total; -} - // Get the current progress of the worker thread, in [0.0, 1.0] double dmnsn_future_progress(const dmnsn_future *future) @@ -120,7 +109,7 @@ dmnsn_future_progress(const dmnsn_future *future) double progress; dmnsn_lock_mutex(&mfuture->mutex); - progress = dmnsn_future_progress_unlocked(mfuture); + progress = (double)future->progress/future->total; dmnsn_unlock_mutex(&mfuture->mutex); return progress; @@ -147,10 +136,11 @@ dmnsn_future_wait(const dmnsn_future *future, double progress) dmnsn_future *mfuture = MUTATE(future); dmnsn_lock_mutex(&mfuture->mutex); - while (dmnsn_future_progress_unlocked(mfuture) < progress) { + size_t iprogress = progress*mfuture->total; + while (mfuture->progress < iprogress) { // Set the minimum waited-on value - if (progress < mfuture->min_wait) { - mfuture->min_wait = progress; + if (iprogress < mfuture->min_wait) { + mfuture->min_wait = iprogress; } dmnsn_cond_wait_safely(&mfuture->cond, &mfuture->mutex); @@ -191,6 +181,7 @@ dmnsn_future_set_total(dmnsn_future *future, size_t total) { dmnsn_lock_mutex(&future->mutex); future->total = total; + future->min_wait = total; dmnsn_unlock_mutex(&future->mutex); } @@ -214,8 +205,8 @@ dmnsn_future_increment(dmnsn_future *future) dmnsn_lock_mutex(&future->mutex); ++future->progress; - if (dmnsn_future_progress_unlocked(future) >= future->min_wait) { - future->min_wait = 1.0; + if (future->progress >= future->min_wait) { + future->min_wait = future->total; dmnsn_cond_broadcast(&future->cond); } diff --git a/libdimension/internal/future.h b/libdimension/internal/future.h index 047523e..5f25027 100644 --- a/libdimension/internal/future.h +++ b/libdimension/internal/future.h @@ -1,5 +1,5 @@ /************************************************************************* - * Copyright (C) 2010-2014 Tavian Barnes * + * Copyright (C) 2010-2015 Tavian Barnes * * * * This file is part of The Dimension Library. * * * @@ -42,7 +42,7 @@ struct dmnsn_future { pthread_cond_t cond; /// Minimum waited-on value. - double min_wait; + size_t min_wait; /// Number of threads working on the future's background task. unsigned int nthreads; -- cgit v1.2.3