From cec47afae217cea36779d7dea4437b35dee63be2 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 29 Sep 2010 17:49:49 -0400 Subject: Make parts of the progress API internal. --- libdimension/Makefile.am | 2 +- libdimension/dimension-impl.h | 2 +- libdimension/dimension/progress.h | 14 +--------- libdimension/progress-impl.h | 54 +++++++++++++++++++++++++++++++++++++++ libdimension/progress-struct.h | 44 ------------------------------- libdimension/progress.c | 43 ++++++++++++------------------- 6 files changed, 74 insertions(+), 85 deletions(-) create mode 100644 libdimension/progress-impl.h delete mode 100644 libdimension/progress-struct.h diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am index 73fb010..36517ee 100644 --- a/libdimension/Makefile.am +++ b/libdimension/Makefile.am @@ -75,7 +75,7 @@ libdimension_la_SOURCES = $(nobase_include_HEADERS) \ platform.h \ point_light.c \ progress.c \ - progress-struct.h \ + progress-impl.h \ prtree.c \ prtree.h \ raytrace.c \ diff --git a/libdimension/dimension-impl.h b/libdimension/dimension-impl.h index 0329dbc..7d1f943 100644 --- a/libdimension/dimension-impl.h +++ b/libdimension/dimension-impl.h @@ -23,7 +23,7 @@ #define _GNU_SOURCE #include "dimension.h" -#include "progress-struct.h" +#include "progress-impl.h" #include "platform.h" #include "threads.h" #include "prtree.h" diff --git a/libdimension/dimension/progress.h b/libdimension/dimension/progress.h index 53dfc37..043f014 100644 --- a/libdimension/dimension/progress.h +++ b/libdimension/dimension/progress.h @@ -30,12 +30,7 @@ typedef struct dmnsn_progress dmnsn_progress; -/* Allocate a new progress object */ -dmnsn_progress *dmnsn_new_progress(void); -/* For failed returns from *_async() functions */ -void dmnsn_delete_progress(dmnsn_progress *progress); - -/* Join the worker thread and returns it's integer return value in addition to +/* Join the worker thread and return it's integer return value in addition to deleting `progress' */ int dmnsn_finish_progress(dmnsn_progress *progress); @@ -44,11 +39,4 @@ double dmnsn_get_progress(const dmnsn_progress *progress); /* Wait for the progress to be >= prog, in a better way than spinlocking */ void dmnsn_wait_progress(const dmnsn_progress *progress, double prog); -/* Create a new level of loop nesting */ -void dmnsn_new_progress_element(dmnsn_progress *progress, unsigned int total); -/* Increment the progress counter; should only be called from innermost loop */ -void dmnsn_increment_progress(dmnsn_progress *progress); -/* Instantly complete the progress */ -void dmnsn_done_progress(dmnsn_progress *progress); - #endif /* DIMENSION_PROGRESS_H */ diff --git a/libdimension/progress-impl.h b/libdimension/progress-impl.h new file mode 100644 index 0000000..ef5ad42 --- /dev/null +++ b/libdimension/progress-impl.h @@ -0,0 +1,54 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * . * + *************************************************************************/ + +#ifndef DIMENSION_IMPL_PROGRESS_H +#define DIMENSION_IMPL_PROGRESS_H + +/* Allocate a new progress object */ +dmnsn_progress *dmnsn_new_progress(void); + +/* Create a new level of loop nesting */ +void dmnsn_new_progress_element(dmnsn_progress *progress, unsigned int total); +/* Increment the progress counter; should only be called from innermost loop */ +void dmnsn_increment_progress(dmnsn_progress *progress); +/* Instantly complete the progress */ +void dmnsn_done_progress(dmnsn_progress *progress); + +struct dmnsn_progress { + /* Array of progress elements. Progress is given by P(0), where + P(i) = (elements[i].progress + P(i + 1))/elements[i].total. */ + dmnsn_array *elements; + + /* The worker thread */ + pthread_t thread; + + /* Read-write synchronization */ + pthread_rwlock_t *rwlock; + + /* Condition variable for waiting for a particular amount of progress */ + pthread_cond_t *cond; + pthread_mutex_t *mutex; + + /* Minimum waited-on value */ + volatile double min_wait; + volatile double *min_waitp; /* Hack for const values */ +}; + +#endif /* DIMENSION_IMPL_PROGRESS_H */ diff --git a/libdimension/progress-struct.h b/libdimension/progress-struct.h deleted file mode 100644 index 06c63be..0000000 --- a/libdimension/progress-struct.h +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************* - * Copyright (C) 2010 Tavian Barnes * - * * - * This file is part of The Dimension Library. * - * * - * The Dimension Library is free software; you can redistribute it and/ * - * or modify it under the terms of the GNU Lesser General Public License * - * as published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Library is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this program. If not, see * - * . * - *************************************************************************/ - -#ifndef DIMENSION_IMPL_PROGRESS_STRUCT_H -#define DIMENSION_IMPL_PROGRESS_STRUCT_H - -struct dmnsn_progress { - /* Array of progress elements. Progress is given by P(0), where - P(i) = (elements[i].progress + P(i + 1))/elements[i].total. */ - dmnsn_array *elements; - - /* The worker thread */ - pthread_t thread; - - /* Read-write synchronization */ - pthread_rwlock_t *rwlock; - - /* Condition variable for waiting for a particular amount of progress */ - pthread_cond_t *cond; - pthread_mutex_t *mutex; - - /* Minimum waited-on value */ - volatile double min_wait; - volatile double *min_waitp; /* Hack for const values */ -}; - -#endif /* DIMENSION_IMPL_PROGRESS_STRUCT_H */ diff --git a/libdimension/progress.c b/libdimension/progress.c index aeac2ac..f7a8b62 100644 --- a/libdimension/progress.c +++ b/libdimension/progress.c @@ -65,29 +65,6 @@ dmnsn_new_progress() return progress; } -/* Delete a dmnsn_progress*, which has not yet been associated with a thread */ -void -dmnsn_delete_progress(dmnsn_progress *progress) -{ - if (progress) { - if (pthread_rwlock_destroy(progress->rwlock) != 0) { - dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking rwlock."); - } - if (pthread_mutex_destroy(progress->mutex) != 0) { - dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking mutex."); - } - if (pthread_cond_destroy(progress->cond) != 0) { - dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking condition variable."); - } - - dmnsn_free(progress->rwlock); - dmnsn_free(progress->mutex); - dmnsn_free(progress->cond); - dmnsn_delete_array(progress->elements); - dmnsn_free(progress); - } -} - /* Join the worker thread and delete `progress'. */ int dmnsn_finish_progress(dmnsn_progress *progress) @@ -96,6 +73,7 @@ dmnsn_finish_progress(dmnsn_progress *progress) int retval = -1; if (progress) { + /* Get the thread's return value */ if (pthread_join(progress->thread, &ptr) != 0) { /* Medium severity because an unjoined thread likely means that the thread is incomplete or invalid */ @@ -103,10 +81,23 @@ dmnsn_finish_progress(dmnsn_progress *progress) } else if (ptr) { retval = *(int *)ptr; dmnsn_free(ptr); - /* Wake up all waiters */ - dmnsn_done_progress(progress); } - dmnsn_delete_progress(progress); + + /* Free the progress object */ + if (pthread_rwlock_destroy(progress->rwlock) != 0) { + dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking rwlock."); + } + if (pthread_mutex_destroy(progress->mutex) != 0) { + dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking mutex."); + } + if (pthread_cond_destroy(progress->cond) != 0) { + dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking condition variable."); + } + dmnsn_free(progress->rwlock); + dmnsn_free(progress->mutex); + dmnsn_free(progress->cond); + dmnsn_delete_array(progress->elements); + dmnsn_free(progress); } return retval; -- cgit v1.2.3