diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2013-03-19 20:20:03 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2013-03-19 20:20:03 -0400 |
commit | 4f9122668d0edd36fbf2ef683d7dafd6b77ac24f (patch) | |
tree | deffede27e1025ee3a72a76e7dae7b4681d32eee /libdimension/future.c | |
parent | a842f979c219ef245b09c4607aacc36fbca3f66b (diff) | |
download | dimension-4f9122668d0edd36fbf2ef683d7dafd6b77ac24f.tar.xz |
Don't use pointer indirection to emulate mutable for futures.
We can just cast away the const, as they're all on the heap anyway.
Diffstat (limited to 'libdimension/future.c')
-rw-r--r-- | libdimension/future.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/libdimension/future.c b/libdimension/future.c index f645944..6ea15ae 100644 --- a/libdimension/future.c +++ b/libdimension/future.c @@ -26,6 +26,13 @@ #include "dimension-internal.h" #include <pthread.h> +/** + * Since C doesn't support anything like C++'s mutable, we fake it by casting + * away the constness. This is okay since all valid dmnsn_futures live on the + * heap, so cannot be const. + */ +#define MUTATE(future) ((dmnsn_future *)future) + /* Allocate a new dmnsn_future* */ dmnsn_future * dmnsn_new_future(void) @@ -34,14 +41,10 @@ dmnsn_new_future(void) future->progress = 0; future->total = 1; - future->mutex = dmnsn_malloc(sizeof(pthread_mutex_t)); - dmnsn_initialize_mutex(future->mutex); + dmnsn_initialize_mutex(&future->mutex); + dmnsn_initialize_cond(&future->cond); - future->cond = dmnsn_malloc(sizeof(pthread_cond_t)); - dmnsn_initialize_cond(future->cond); - - future->min_wait = dmnsn_malloc(sizeof(double)); - *future->min_wait = 1.0; + future->min_wait = 1.0; return future; } @@ -62,15 +65,8 @@ dmnsn_future_join(dmnsn_future *future) } /* Free the future object */ - - dmnsn_free(future->min_wait); - - dmnsn_destroy_cond(future->cond); - dmnsn_free(future->cond); - - dmnsn_destroy_mutex(future->mutex); - dmnsn_free(future->mutex); - + dmnsn_destroy_cond(&future->cond); + dmnsn_destroy_mutex(&future->mutex); dmnsn_free(future); } @@ -99,11 +95,12 @@ dmnsn_future_progress_unlocked(const dmnsn_future *future) double dmnsn_future_progress(const dmnsn_future *future) { + dmnsn_future *mfuture = MUTATE(future); double progress; - dmnsn_lock_mutex(future->mutex); - progress = dmnsn_future_progress_unlocked(future); - dmnsn_unlock_mutex(future->mutex); + dmnsn_lock_mutex(&mfuture->mutex); + progress = dmnsn_future_progress_unlocked(mfuture); + dmnsn_unlock_mutex(&mfuture->mutex); return progress; } @@ -112,24 +109,26 @@ dmnsn_future_progress(const dmnsn_future *future) void dmnsn_future_wait(const dmnsn_future *future, double progress) { - dmnsn_lock_mutex(future->mutex); - while (dmnsn_future_progress_unlocked(future) < progress) { + dmnsn_future *mfuture = MUTATE(future); + + dmnsn_lock_mutex(&mfuture->mutex); + while (dmnsn_future_progress_unlocked(mfuture) < progress) { /* Set the minimum waited-on value */ - if (progress < *future->min_wait) - *future->min_wait = progress; + if (progress < mfuture->min_wait) + mfuture->min_wait = progress; - dmnsn_cond_wait(future->cond, future->mutex); + dmnsn_cond_wait(&mfuture->cond, &mfuture->mutex); } - dmnsn_unlock_mutex(future->mutex); + dmnsn_unlock_mutex(&mfuture->mutex); } /* Set the total number of loop iterations */ void dmnsn_future_set_total(dmnsn_future *future, size_t total) { - dmnsn_lock_mutex(future->mutex); + dmnsn_lock_mutex(&future->mutex); future->total = total; - dmnsn_unlock_mutex(future->mutex); + dmnsn_unlock_mutex(&future->mutex); } /* Increment the number of completed loop iterations */ @@ -141,22 +140,22 @@ dmnsn_future_increment(dmnsn_future *future) on cancellation */ pthread_testcancel(); - dmnsn_lock_mutex(future->mutex); + dmnsn_lock_mutex(&future->mutex); ++future->progress; - if (dmnsn_future_progress_unlocked(future) >= *future->min_wait) { - *future->min_wait = 1.0; - dmnsn_cond_broadcast(future->cond); + if (dmnsn_future_progress_unlocked(future) >= future->min_wait) { + future->min_wait = 1.0; + dmnsn_cond_broadcast(&future->cond); } - dmnsn_unlock_mutex(future->mutex); + dmnsn_unlock_mutex(&future->mutex); } /* Immediately set to 100% completion */ void dmnsn_future_done(dmnsn_future *future) { - dmnsn_lock_mutex(future->mutex); + dmnsn_lock_mutex(&future->mutex); future->progress = future->total; - dmnsn_cond_broadcast(future->cond); - dmnsn_unlock_mutex(future->mutex); + dmnsn_cond_broadcast(&future->cond); + dmnsn_unlock_mutex(&future->mutex); } |