[babl] Made BablFishPath thread safe.
- From: Øyvind Kolås <ok src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [babl] Made BablFishPath thread safe.
- Date: Sat, 21 Nov 2009 16:52:13 +0000 (UTC)
commit c000b0a87a3002480c5588eb98db219be42054c8
Author: �yvind Kolås <pippin gimp org>
Date: Sat Nov 21 16:47:24 2009 +0000
Made BablFishPath thread safe.
Refactored static variables away and added a lock to protect state
keeping inside the individual BablFormat when permutating possible
conversion paths.
babl/babl-fish-path.c | 101 +++++++++++++++++++++++++++++--------------------
babl/babl-internal.c | 3 +
babl/babl-internal.h | 1 +
3 files changed, 64 insertions(+), 41 deletions(-)
---
diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c
index c7f28c2..756e673 100644
--- a/babl/babl-fish-path.c
+++ b/babl/babl-fish-path.c
@@ -26,21 +26,27 @@
#define BABL_MAX_NAME_LEN 1024
-typedef struct _FishPathInstrumentation {
- Babl *fmt_rgba_double;
- double *test;
- void *source;
- void *destination;
- void *ref_destination;
- double *destination_rgba_double;
- double *ref_destination_rgba_double;
- Babl *fish_rgba_to_source;
- Babl *fish_reference;
- Babl *fish_destination_to_rgba;
- double reference_cost;
- int init_instrumentation_done;
+typedef struct _FishPathInstrumentation
+{
+ Babl *fmt_rgba_double;
+ double *test;
+ void *source;
+ void *destination;
+ void *ref_destination;
+ double *destination_rgba_double;
+ double *ref_destination_rgba_double;
+ Babl *fish_rgba_to_source;
+ Babl *fish_reference;
+ Babl *fish_destination_to_rgba;
+ double reference_cost;
+ int init_instrumentation_done;
} FishPathInstrumentation;
+typedef struct PathContext {
+ Babl *fish_path;
+ Babl *to_format;
+ BablList *current_path;
+} PathContext;
static void
init_path_instrumentation (FishPathInstrumentation *fpi,
@@ -64,7 +70,8 @@ process_conversion_path (BablList *path,
long n);
static void
-get_conversion_path (Babl *current_format,
+get_conversion_path (PathContext *pc,
+ Babl *current_format,
int current_length,
int max_length);
@@ -132,14 +139,12 @@ static int max_path_length (void)
* implemented by recursive function get_conversion_path ().
*/
-static Babl *fish_path;
-static Babl *to_format;
-static BablList *current_path;
static void
-get_conversion_path (Babl *current_format,
- int current_length,
- int max_length)
+get_conversion_path (PathContext *pc,
+ Babl *current_format,
+ int current_length,
+ int max_length)
{
if (current_length > max_length)
{
@@ -147,7 +152,7 @@ get_conversion_path (Babl *current_format,
* depth, let's bail out */
return;
}
- else if ((current_length > 0) && (current_format == to_format))
+ else if ((current_length > 0) && (current_format == pc->to_format))
{
/* We have found a candidate path, let's
* see about it's properties */
@@ -156,9 +161,9 @@ get_conversion_path (Babl *current_format,
double path_error = 1.0;
int i;
- for (i = 0; i < babl_list_size (current_path); i++)
+ for (i = 0; i < babl_list_size (pc->current_path); i++)
{
- path_error *= (1.0 + babl_conversion_error ((BablConversion *) current_path->items[i]));
+ path_error *= (1.0 + babl_conversion_error ((BablConversion *) pc->current_path->items[i]));
}
if (path_error - 1.0 <= legal_error ()) /* check this before the next;
@@ -167,18 +172,18 @@ get_conversion_path (Babl *current_format,
{
FishPathInstrumentation fpi;
memset (&fpi, 0, sizeof (fpi));
- get_path_instrumentation (&fpi, current_path, &path_cost, &ref_cost, &path_error);
+ get_path_instrumentation (&fpi, pc->current_path, &path_cost, &ref_cost, &path_error);
if ((path_cost < ref_cost) && /* do not use paths that took longer to compute than reference */
- (path_cost < fish_path->fish_path.cost) &&
+ (path_cost < pc->fish_path->fish_path.cost) &&
(path_error <= legal_error ()))
{
/* We have found the best path so far,
* let's copy it into our new fish */
- fish_path->fish_path.cost = path_cost;
- fish_path->fish.error = path_error;
- babl_list_copy (current_path,
- fish_path->fish_path.conversion_list);
+ pc->fish_path->fish_path.cost = path_cost;
+ pc->fish_path->fish.error = path_error;
+ babl_list_copy (pc->current_path,
+ pc->fish_path->fish_path.conversion_list);
}
destroy_path_instrumentation (&fpi);
@@ -187,10 +192,12 @@ get_conversion_path (Babl *current_format,
else
{
/*
- * Bummer, we have to search deeper... */
+ * Bummer, we have to search deeper...
+ */
BablList *list;
int i;
+
list = current_format->format.from_list;
if (list)
{
@@ -205,16 +212,16 @@ get_conversion_path (Babl *current_format,
if (!next_format->format.visited)
{
/* next_format is not in the current path, we can pay a visit */
- babl_list_insert_last (current_path, next_conversion);
- get_conversion_path (next_format, current_length + 1, max_length);
- babl_list_remove_last (current_path);
+ babl_list_insert_last (pc->current_path, next_conversion);
+ get_conversion_path (pc, next_format, current_length + 1, max_length);
+ babl_list_remove_last (pc->current_path);
}
}
/* Remove the current format from current path */
current_format->format.visited = 0;
}
- }
+ }
}
static char *
@@ -263,13 +270,23 @@ babl_fish_path (const Babl *source,
babl->fish_path.loss = BABL_MAX_COST_VALUE;
babl->fish_path.conversion_list = babl_list_init_with_size (BABL_HARD_MAX_PATH_LENGTH);
- current_path = babl_list_init_with_size (BABL_HARD_MAX_PATH_LENGTH);
- fish_path = babl;
- to_format = (Babl *) destination;
-
- get_conversion_path ((Babl *) source, 0, max_path_length ());
-
- babl_list_destroy (current_path);
+ {
+ PathContext pc;
+ pc.current_path = babl_list_init_with_size (BABL_HARD_MAX_PATH_LENGTH);
+ pc.fish_path = babl;
+ pc.to_format = (Babl *) destination;
+
+ babl_mutex_lock (babl_format_mutex);
+ /* we hold a global lock whilerunning get_conversion_path since
+ * it depends on keeping the various format.visited members in
+ * a consistent state, this code path is not performance critical
+ * since created fishes are cached.
+ */
+
+ get_conversion_path (&pc, (Babl *) source, 0, max_path_length ());
+ babl_mutex_unlock (babl_format_mutex);
+ babl_list_destroy (pc.current_path);
+ }
if (babl_list_size (babl->fish_path.conversion_list) == 0)
{
@@ -506,6 +523,7 @@ get_path_instrumentation (FishPathInstrumentation *fpi,
fpi->ref_destination_rgba_double,
NUM_TEST_PIXELS * 4);
+#if 0
fpi->fish_rgba_to_source->fish.processings--;
fpi->fish_reference->fish.processings--;
fpi->fish_destination_to_rgba->fish.processings -= 2;
@@ -513,6 +531,7 @@ get_path_instrumentation (FishPathInstrumentation *fpi,
fpi->fish_rgba_to_source->fish.pixels -= NUM_TEST_PIXELS;
fpi->fish_reference->fish.pixels -= NUM_TEST_PIXELS;
fpi->fish_destination_to_rgba->fish.pixels -= 2 * NUM_TEST_PIXELS;
+#endif
*ref_cost = fpi->reference_cost;
}
diff --git a/babl/babl-internal.c b/babl/babl-internal.c
index f8689ce..7155bcf 100644
--- a/babl/babl-internal.c
+++ b/babl/babl-internal.c
@@ -121,6 +121,7 @@ babl_process (Babl *babl,
return -1;
}
+BablMutex *babl_format_mutex;
#if BABL_DEBUG_MEM
BablMutex *babl_debug_mutex;
#endif
@@ -130,6 +131,7 @@ babl_internal_init (void)
{
babl_set_malloc (malloc);
babl_set_free (free);
+ babl_format_mutex = babl_mutex_new ();
#if BABL_DEBUG_MEM
babl_debug_mutex = babl_mutex_new ();
#endif
@@ -138,6 +140,7 @@ babl_internal_init (void)
void
babl_internal_destroy (void)
{
+ babl_mutex_destroy (babl_format_mutex);
#if BABL_DEBUG_MEM
babl_mutex_destroy (babl_debug_mutex);
#endif
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index 7606cac..451c5f8 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -239,6 +239,7 @@ babl_fatal (const char *format, ...)
)
extern int babl_hmpf_on_name_lookups;
+extern BablMutex *babl_format_mutex;
#define BABL_DEBUG_MEM 1
#if BABL_DEBUG_MEM
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]