[GRASS-SVN] r34486 - in grass/trunk: include lib/gis raster/r.mapcalc

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Nov 25 16:15:33 EST 2008


Author: glynn
Date: 2008-11-25 16:15:33 -0500 (Tue, 25 Nov 2008)
New Revision: 34486

Added:
   grass/trunk/lib/gis/worker.c
Modified:
   grass/trunk/include/gisdefs.h
   grass/trunk/lib/gis/Makefile
   grass/trunk/lib/gis/counter.c
   grass/trunk/lib/gis/datum.c
   grass/trunk/lib/gis/debug.c
   grass/trunk/lib/gis/env.c
   grass/trunk/lib/gis/error.c
   grass/trunk/lib/gis/gdal.c
   grass/trunk/lib/gis/get_ellipse.c
   grass/trunk/lib/gis/get_window.c
   grass/trunk/lib/gis/gisinit.c
   grass/trunk/lib/gis/home.c
   grass/trunk/lib/gis/locale.c
   grass/trunk/lib/gis/mach_name.c
   grass/trunk/lib/gis/mapset_nme.c
   grass/trunk/lib/gis/opencell.c
   grass/trunk/lib/gis/tempfile.c
   grass/trunk/lib/gis/verbose.c
   grass/trunk/lib/gis/whoami.c
   grass/trunk/lib/gis/window_map.c
   grass/trunk/raster/r.mapcalc/evaluate.c
Log:
Add, use G_is_initialized(), G_initialize_done() for one-shot initialisation
Optionally use mutexes for incrementing counters
Generalise r.mapcalc worker-threads code, move into lib/gis
Remove G_get_fp_type(), G_get_compression_type; initialise in gisinit()



Modified: grass/trunk/include/gisdefs.h
===================================================================
--- grass/trunk/include/gisdefs.h	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/include/gisdefs.h	2008-11-25 21:15:33 UTC (rev 34486)
@@ -388,6 +388,8 @@
 int G_copy_file(const char *, const char *);
 
 /* counter.c */
+int G_is_initialized(int *);
+void G_initialize_done(int *);
 void G_init_counter(struct Counter *, int);
 int G_counter_next(struct Counter *);
 
@@ -848,8 +850,6 @@
 void G_want_histogram(int);
 void G_set_cell_format(int);
 int G_cellvalue_format(CELL);
-int G_get_fp_type(void);
-int G_get_compression_type(void);
 int G_open_fp_cell_new(const char *);
 int G_open_fp_cell_new_uncompressed(const char *);
 int G_set_fp_type(RASTER_MAP_TYPE);
@@ -1201,6 +1201,12 @@
 void G__init_window(void);
 int G_row_repeat_nomask(int, int);
 
+/* worker.c */
+void G_begin_execute(void (*func)(void *), void *, void **, int);
+void G_end_execute(void **);
+void G_init_workers(void);
+void G_finish_workers(void);
+
 /* wr_cellhd.c */
 void G__write_Cell_head(FILE *, const struct Cell_head *, int);
 void G__write_Cell_head3(FILE *, const struct Cell_head *, int);

Modified: grass/trunk/lib/gis/Makefile
===================================================================
--- grass/trunk/lib/gis/Makefile	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/Makefile	2008-11-25 21:15:33 UTC (rev 34486)
@@ -37,6 +37,12 @@
 
 endif
 
+ifneq ($(USE_PTHREAD),)
+PTHREADLIB = -lpthread
+EXTRA_CFLAGS += -DUSE_PTHREAD
+EXTRA_LIBS += $(PTHREADLIB)
+endif
+
 default: lib $(FMODE_OBJ) $(DATAFILES) $(COLORFILES) $(ETC)/colors.desc $(ETC)/element_list
 
 $(FMODE_OBJ): fmode.dat

Modified: grass/trunk/lib/gis/counter.c
===================================================================
--- grass/trunk/lib/gis/counter.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/counter.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -1,12 +1,75 @@
 #include <grass/gis.h>
 
+#ifdef USE_PTHREADS
+#include <pthread.h>
+static pthread_mutex_t mutex;
+#endif
+
 void G_init_counter(struct Counter *c, int v)
 {
+#ifdef USE_PTHREADS
+    make_mutex();
+#endif
     c->value = v;
 }
 
 int G_counter_next(struct Counter *c)
 {
-    return c->value++;
+    int v;
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&mutex);
+#endif
+    v = c->value++;
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&mutex);
+#endif
+    return v;
 }
 
+#ifdef USE_PTHREADS
+static void make_mutex(void)
+{
+    static pthread_mutex_t t_mutex = PTHREAD_MUTEX_INITIALIZER;
+    static int initialized;
+    pthread_mutexattr_t attr;
+
+    if (initialized)
+	return;
+
+    pthread_mutex_lock(&t_mutex);
+
+    if (initialized) {
+	pthread_mutex_unlock(&t_mutex);
+	return;
+    }
+
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&r_mutex, &attr);
+    initialized = 1;
+
+    pthread_mutex_unlock(&t_mutex);
+}
+#endif
+
+int G_is_initialized(int *p)
+{
+    if (*p)
+	return 1;
+
+#ifdef USE_PTHREADS
+    make_mutex();
+    pthread_mutex_lock(&mutex);
+#endif
+    return 0;
+}
+
+void G_initialize_done(int *p)
+{
+    *p = 1;
+
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&mutex);
+#endif
+}
+

Modified: grass/trunk/lib/gis/datum.c
===================================================================
--- grass/trunk/lib/gis/datum.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/datum.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -37,6 +37,7 @@
     } *datums;
     int size;
     int count;
+    int initialized;
 } table;
 
 static int compare_table_names(const void *, const void *);
@@ -149,7 +150,7 @@
     char buf[1024];
     int line;
 
-    if (table.count > 0)
+    if (G_is_initialized(&table.initialized))
 	return;
 
     sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);
@@ -157,6 +158,7 @@
     fd = fopen(file, "r");
     if (!fd) {
 	G_warning(_("unable to open datum table file: %s"), file);
+	G_initialize_done(&table.initialized);
 	return;
     }
 
@@ -189,6 +191,8 @@
     }
 
     qsort(table.datums, table.count, sizeof(struct datum), compare_table_names);
+
+    G_initialize_done(&table.initialized);
 }
 
 static int compare_table_names(const void *aa, const void *bb)

Modified: grass/trunk/lib/gis/debug.c
===================================================================
--- grass/trunk/lib/gis/debug.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/debug.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -23,9 +23,9 @@
 #include "G.h"
 
 
-static int grass_debug_level = -1;
+static int initialized;
+static int grass_debug_level;
 
-
 /**
  * \brief Print debugging message.
  *
@@ -47,7 +47,7 @@
 {
     const char *lstr;
 
-    if (grass_debug_level >= 0)
+    if (G_is_initialized(&initialized))
 	return;
 
     lstr = G__getenv("DEBUG");
@@ -56,6 +56,8 @@
 	grass_debug_level = atoi(lstr);
     else
 	grass_debug_level = 0;
+
+    G_initialize_done(&initialized);
 }
 
 int G_debug(int level, const char *msg, ...)

Modified: grass/trunk/lib/gis/env.c
===================================================================
--- grass/trunk/lib/gis/env.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/env.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -95,11 +95,9 @@
     if (loc == G_VAR_GISRC && st->varmode == G_GISRC_MODE_MEMORY)
 	return 0;		/* don't use file for GISRC */
 
-    if (st->init[loc])
+    if (G_is_initialized(&st->init[loc]))
 	return 1;
 
-    st->init[loc] = 1;
-
     if ((fd = open_env("r", loc))) {
 	while (G_getl2(buf, sizeof buf, fd)) {
 	    for (name = value = buf; *value; value++)
@@ -118,6 +116,7 @@
 	fclose(fd);
     }
 
+    G_initialize_done(&st->init[loc]);
     return 0;
 }
 

Modified: grass/trunk/lib/gis/error.c
===================================================================
--- grass/trunk/lib/gis/error.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/error.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -308,7 +308,7 @@
     static int initialized;
     char *fstr;
 
-    if (initialized)
+    if (G_is_initialized(&initialized))
 	return;
 
     G_init_counter(&message_id, 1);
@@ -335,7 +335,7 @@
     else
 	grass_info_format = G_INFO_FORMAT_STANDARD;
 
-    initialized = 1;
+    G_initialize_done(&initialized);
 }
 
 /* Write a message to the log file */

Modified: grass/trunk/lib/gis/gdal.c
===================================================================
--- grass/trunk/lib/gis/gdal.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/gdal.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -125,12 +125,12 @@
 #ifdef GDAL_LINK
     static int initialized;
 
-    if (initialized)
+    if (G_is_initialized(&initialized))
 	return;
 
     init_gdal();
     (*pGDALAllRegister)();
-    initialized = 1;
+    G_initialize_done(&initialized);
 #endif
 }
 

Modified: grass/trunk/lib/gis/get_ellipse.c
===================================================================
--- grass/trunk/lib/gis/get_ellipse.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/get_ellipse.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -41,6 +41,7 @@
     } *ellipses;
     int count;
     int size;
+    int initialized;
 } table;
 
 /* static int get_a_e2 (char *, char *, double *,double *); */
@@ -261,7 +262,7 @@
     int line;
     int err;
 
-    if (table.count > 0)
+    if (G_is_initialized(&table.initialized))
 	return 1;
 
     sprintf(file, "%s/etc/ellipse.table", G_gisbase());
@@ -269,6 +270,7 @@
 
     if (fd == NULL) {
 	(fatal ? G_fatal_error : G_warning)(_("Unable to open ellipsoid table file <%s>"), file);
+	G_initialize_done(&table.initialized);
 	return 0;
     }
 
@@ -319,6 +321,7 @@
     if (!err) {
 	/* over correct typed version */
 	qsort(table.ellipses, table.count, sizeof(struct ellipse), compare_ellipse_names);
+	G_initialize_done(&table.initialized);
 	return 1;
     }
 
@@ -328,6 +331,8 @@
 	: _("Line%s of ellipsoid table file <%s> is invalid"),
 	badlines, file);
 
+    G_initialize_done(&table.initialized);
+
     return 0;
 }
 

Modified: grass/trunk/lib/gis/get_window.c
===================================================================
--- grass/trunk/lib/gis/get_window.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/get_window.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -54,7 +54,7 @@
 {
     const char *regvar, *err;
 
-    if (st->initialized) {
+    if (G_is_initialized(&st->initialized)) {
 	*window = st->dbwindow;
 	return;
     }
@@ -78,13 +78,14 @@
     if (err)
 	G_fatal_error(_("region for current mapset %s\nrun \"g.region\""), err);
 
-    st->initialized = 1;
     *window = st->dbwindow;
 
     if (!G__.window_set) {
 	G__.window_set = 1;
 	G__.window = st->dbwindow;
     }
+
+    G_initialize_done(&st->initialized);
 }
 
 

Modified: grass/trunk/lib/gis/gisinit.c
===================================================================
--- grass/trunk/lib/gis/gisinit.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/gisinit.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -115,13 +115,13 @@
     G__.want_histogram = 0;
 
     /* set the write type for floating maps */
-    G__.fp_type = -1;
+    G__.fp_type = getenv("GRASS_FP_DOUBLE") ? DCELL_TYPE : FCELL_TYPE;
 
     /* Set masking flag unknown */
     G__.auto_mask = -1;
 
     G__.nbytes = sizeof(CELL);
-    G__.compression_type = 0;
+    G__.compression_type = getenv("GRASS_INT_ZLIB") ? 2 : 1;
 
     initialized = 1;
 
@@ -136,8 +136,6 @@
     G_init_env();
     G_init_logging();
     G__init_window();
-    G_get_fp_type();
-    G_get_compression_type();
     G__check_for_auto_masking();
     G_init_locale();
     G_init_debug();

Modified: grass/trunk/lib/gis/home.c
===================================================================
--- grass/trunk/lib/gis/home.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/home.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -42,9 +42,10 @@
 
 char *G__home(void)
 {
+    static int initialized;
     static char *home = 0;
 
-    if (home)
+    if (G_is_initialized(&initialized))
 	return home;
 
 #ifdef __MINGW32__
@@ -68,5 +69,6 @@
     home = getenv("HOME");
 #endif
     G_debug(2, "G__home home = %s", home);
+    G_initialize_done(&initialized);
     return home;
 }

Modified: grass/trunk/lib/gis/locale.c
===================================================================
--- grass/trunk/lib/gis/locale.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/locale.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -25,25 +25,26 @@
 void G_init_locale(void)
 {
     static int initialized;
-    char localedir[GPATH_MAX];
     const char *gisbase;
 
-    if (initialized)
+    if (G_is_initialized(&initialized))
 	return;
-    initialized = 1;
 
     setlocale(LC_CTYPE, "");
     setlocale(LC_MESSAGES, "");
 
     gisbase = getenv("GISBASE");
-    if (!gisbase || !*gisbase)
-	return;
+    if (gisbase && *gisbase) {
+	char localedir[GPATH_MAX];
 
-    strcpy(localedir, gisbase);
-    strcat(localedir, "/locale");
+	strcpy(localedir, gisbase);
+	strcat(localedir, "/locale");
 
-    bindtextdomain("grasslibs", localedir);
-    bindtextdomain("grassmods", localedir);
+	bindtextdomain("grasslibs", localedir);
+	bindtextdomain("grassmods", localedir);
+    }
+
+    G_initialize_done(&initialized);
 }
 #endif
 

Modified: grass/trunk/lib/gis/mach_name.c
===================================================================
--- grass/trunk/lib/gis/mach_name.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/mach_name.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -16,9 +16,10 @@
 
 char *G__machine_name(void)
 {
+    static int initialized;
     static char name[128];
 
-    if (*name)
+    if (G_is_initialized(&initialized))
 	return name;
 
 #if defined(HAVE_GETHOSTNAME)
@@ -34,5 +35,6 @@
     strcpy(name, "unknown");
 #endif
 
+    G_initialize_done(&initialized);
     return name;
 }

Modified: grass/trunk/lib/gis/mapset_nme.c
===================================================================
--- grass/trunk/lib/gis/mapset_nme.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/mapset_nme.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -22,6 +22,7 @@
 	int count;
 	int size;
     } path, path2;
+    int initialized;
 } state;
 
 static struct state *st = &state;
@@ -40,8 +41,7 @@
  */
 char *G__mapset_name(int n)
 {
-    if (st->path.count == 0)
-	G_get_list_of_mapsets();
+    G_get_list_of_mapsets();
 
     if (n < 0 || n >= st->path.count)
 	return NULL;
@@ -53,6 +53,9 @@
 {
     FILE *fp;
 
+    if (G_is_initialized(&st->initialized))
+	return;
+
     fp = G_fopen_old("", "SEARCH_PATH", G_mapset());
     if (fp) {
 	char name[GNAME_MAX];
@@ -70,6 +73,8 @@
 	if (strcmp(perm, cur) != 0 && G__mapset_permissions(perm) >= 0)
 	    new_mapset(perm);
     }
+
+    G_initialize_done(&st->initialized);
 }
 
 static void new_mapset(const char *name)

Modified: grass/trunk/lib/gis/opencell.c
===================================================================
--- grass/trunk/lib/gis/opencell.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/opencell.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -450,24 +450,6 @@
     return sizeof(CELL) - 1;
 }
 
-int G_get_fp_type(void)
-{
-    if (G__.fp_type <= 0)
-	G__.fp_type = getenv("GRASS_FP_DOUBLE")
-	    ? DCELL_TYPE
-	    : FCELL_TYPE;
-
-    return G__.fp_type;
-}
-
-int G_get_compression_type(void)
-{
-    if (!G__.compression_type)
-	G__.compression_type = getenv("GRASS_INT_ZLIB") ? 2 : 1;
-    return G__.compression_type;
-}
-
-
 /*!
   \brief Opens new fcell file in a database
 
@@ -487,7 +469,7 @@
 */
 int G_open_fp_cell_new(const char *name)
 {
-    return G__open_raster_new(name, OPEN_NEW_COMPRESSED, G_get_fp_type());
+    return G__open_raster_new(name, OPEN_NEW_COMPRESSED, G__.fp_type);
 }
 
 /*!
@@ -502,7 +484,7 @@
 */
 int G_open_fp_cell_new_uncompressed(const char *name)
 {
-    return G__open_raster_new(name, OPEN_NEW_UNCOMPRESSED, G_get_fp_type());
+    return G__open_raster_new(name, OPEN_NEW_UNCOMPRESSED, G__.fp_type);
 }
 
 static int G__open_raster_new(const char *name, int open_mode,
@@ -589,7 +571,7 @@
 	fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
 	G_zero(fcb->row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
 	G__write_row_ptrs(fd);
-	fcb->cellhd.compressed = G_get_compression_type();
+	fcb->cellhd.compressed = G__.compression_type;
 
 	fcb->nbytes = 1;	/* to the minimum */
     }
@@ -599,7 +581,7 @@
 	    fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
 	    G_zero(fcb->row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
 	    G__write_row_ptrs(fd);
-	    fcb->cellhd.compressed = G_get_compression_type();
+	    fcb->cellhd.compressed = G__.compression_type;
 	}
 	else
 	    fcb->cellhd.compressed = 0;

Modified: grass/trunk/lib/gis/tempfile.c
===================================================================
--- grass/trunk/lib/gis/tempfile.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/tempfile.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -24,12 +24,12 @@
 
 void G_init_tempfile(void)
 {
-    if (initialized)
+    if (G_is_initialized(&initialized))
 	return;
 
     G_init_counter(&unique, 0);
 
-    initialized = 1;
+    G_initialize_done(&initialized);
 }
 
 /**

Modified: grass/trunk/lib/gis/verbose.c
===================================================================
--- grass/trunk/lib/gis/verbose.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/verbose.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -21,15 +21,16 @@
 
 #include <stdlib.h>
 #include <grass/config.h>
+#include <grass/gis.h>
 
 #define MAXLEVEL 3
 #define STDLEVEL 2
 #define MINLEVEL 0
 
+static int initialized;
+static int verbose;	/* current verbosity level */
 
-static int verbose = -1;	/* current verbosity level */
 
-
 /**
  * \brief Get current verbosity level.
  *
@@ -44,17 +45,17 @@
 
 int G_verbose(void)
 {
-    char *verstr;		/* string for GRASS_VERBOSE content */
+    const char *verstr;		/* string for GRASS_VERBOSE content */
 
+    if (G_is_initialized(&initialized))
+	return verbose;
+
     /* verbose not defined -> get it from env. */
-    if (verbose < 0) {
+    verstr = getenv("GRASS_VERBOSE");
+    verbose = verstr ? atoi(verstr) : STDLEVEL;
 
-	if ((verstr = getenv("GRASS_VERBOSE"))) {
-	    if ((verbose = atoi(verstr))) ;
-	}
-	else
-	    verbose = STDLEVEL;
-    }
+    G_initialize_done(&initialized);
+
     return verbose;
 }
 

Modified: grass/trunk/lib/gis/whoami.c
===================================================================
--- grass/trunk/lib/gis/whoami.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/whoami.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -39,9 +39,10 @@
 
 char *G_whoami(void)
 {
+    static int initialized;
     static char *name;
 
-    if (name)
+    if (G_is_initialized(&initialized))
 	return name;
 
 #ifdef __MINGW32__
@@ -64,5 +65,7 @@
     if (!name || !*name)
 	name = "anonymous";
 
+    G_initialize_done(&initialized);
+
     return name;
 }

Modified: grass/trunk/lib/gis/window_map.c
===================================================================
--- grass/trunk/lib/gis/window_map.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/lib/gis/window_map.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -317,10 +317,12 @@
 
 void G__init_window(void)
 {
-    if (!G__.window_set) {
-	G__.window_set = 1;
-	G_get_window(&G__.window);
-    }
+    if (G_is_initialized(&G__.window_set))
+	return;
+
+    G_get_window(&G__.window);
+
+    G_initialize_done(&G__.window_set);
 }
 
 

Added: grass/trunk/lib/gis/worker.c
===================================================================
--- grass/trunk/lib/gis/worker.c	                        (rev 0)
+++ grass/trunk/lib/gis/worker.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -0,0 +1,174 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#ifdef USE_PTHREAD
+
+/****************************************************************************/
+
+#include <pthread.h>
+
+#define DEFAULT_WORKERS 8
+
+struct worker {
+    void (*func)(void *);
+    void *closure;
+    void **ref;
+    pthread_t thread;
+    pthread_cond_t cond;
+    pthread_mutex_t mutex;
+    int cancel;
+};
+
+static int num_workers;
+static struct worker *workers;
+static pthread_cond_t worker_cond;
+static pthread_mutex_t worker_mutex;
+
+/****************************************************************************/
+
+static void *worker(void *arg)
+{
+    struct worker *w = arg;
+
+    while (!w->cancel) {
+	pthread_mutex_lock(&w->mutex);
+	while (!w->func)
+	    pthread_cond_wait(&w->cond, &w->mutex);
+
+	(*w->func)(w->closure);
+
+	w->func = NULL;
+	w->closure = NULL;
+	*w->ref = NULL;
+	pthread_mutex_unlock(&w->mutex);
+	pthread_cond_signal(&w->cond);
+	pthread_cond_signal(&worker_cond);
+    }
+
+    return NULL;
+}
+
+static struct worker *get_worker(void)
+{
+    int i;
+
+    for (i = 0; i < num_workers; i++) {
+	struct worker *w = &workers[i];
+	if (!w->func)
+	    return w;
+    }
+
+    return NULL;
+}
+
+void G_begin_execute(void (*func)(void *), void *closure, void **ref, int force)
+{
+    struct worker *w;
+ 
+    if (*ref)
+	G_fatal_error(_("Task already has a worker"));
+
+    pthread_mutex_lock(&worker_mutex);
+
+    while (w = get_worker(), force && !w)
+	pthread_cond_wait(&worker_cond, &worker_mutex);
+    *ref = w;
+
+    if (!w) {
+	pthread_mutex_unlock(&worker_mutex);
+	(*func)(closure);
+	return;
+    }
+
+    pthread_mutex_lock(&w->mutex);
+    w->func = func;
+    w->closure = closure;
+    w->ref = ref;
+    pthread_cond_signal(&w->cond);
+    pthread_mutex_unlock(&w->mutex);
+
+    pthread_mutex_unlock(&worker_mutex);
+}
+
+void G_end_execute(void **ref)
+{
+    struct worker *w = *ref;
+
+    if (!w)
+	return;
+
+    pthread_mutex_lock(&w->mutex);
+    while (*ref)
+	pthread_cond_wait(&w->cond, &w->mutex);
+    pthread_mutex_unlock(&w->mutex);
+}
+
+void G_init_workers(void)
+{
+    const char *p = getenv("WORKERS");
+    int i;
+
+    pthread_mutex_init(&worker_mutex, NULL);
+    pthread_cond_init(&worker_cond, NULL);
+
+    num_workers = p ? atoi(p) : DEFAULT_WORKERS;
+    workers = G_calloc(num_workers, sizeof(struct worker));
+
+    for (i = 0; i < num_workers; i++) {
+	struct worker *w = &workers[i];
+	pthread_mutex_init(&w->mutex, NULL);
+	pthread_cond_init(&w->cond, NULL);
+	pthread_create(&w->thread, NULL, worker, w);
+    }
+}
+
+void G_finish_workers(void)
+{
+    int i;
+
+    for (i = 0; i < num_workers; i++) {
+	struct worker *w = &workers[i];
+	w->cancel = 1;
+    }
+
+    for (i = 0; i < num_workers; i++) {
+	struct worker *w = &workers[i];
+	pthread_join(w->thread, NULL);
+	pthread_mutex_destroy(&w->mutex);
+	pthread_cond_destroy(&w->cond);
+    }
+
+    pthread_mutex_destroy(&worker_mutex);
+    pthread_cond_destroy(&worker_cond);
+}
+
+/****************************************************************************/
+
+#else
+
+/****************************************************************************/
+
+void G_begin_execute(void (*func)(void *), void *closure, void **ref, int force)
+{
+    (*func)(closure);
+}
+
+void G_end_execute(void **ref)
+{
+}
+
+void G_init_workers(void)
+{
+}
+
+void G_finish_workers(void)
+{
+}
+
+/****************************************************************************/
+
+#endif
+

Modified: grass/trunk/raster/r.mapcalc/evaluate.c
===================================================================
--- grass/trunk/raster/r.mapcalc/evaluate.c	2008-11-25 17:14:57 UTC (rev 34485)
+++ grass/trunk/raster/r.mapcalc/evaluate.c	2008-11-25 21:15:33 UTC (rev 34486)
@@ -1,9 +1,6 @@
 
 #include <stdlib.h>
 #include <unistd.h>
-#ifdef USE_PTHREAD
-#include <pthread.h>
-#endif
 
 #include <grass/gis.h>
 #include <grass/glocale.h>
@@ -19,8 +16,8 @@
 
 /****************************************************************************/
 
-static void initialize(expression * e);
-static void evaluate(expression * e);
+static void initialize(expression *e);
+static void evaluate(expression *e);
 
 /****************************************************************************/
 
@@ -99,125 +96,21 @@
 
 /****************************************************************************/
 
-#ifdef USE_PTHREAD
-
-struct worker {
-    struct expression *exp;
-    pthread_t thread;
-    pthread_cond_t cond;
-    pthread_mutex_t mutex;
-};
-
-static int num_workers;
-static struct worker *workers;
-
-static pthread_mutex_t worker_mutex;
-
-static void *worker(void *arg)
+static void do_evaluate(void *p)
 {
-    struct worker *w = arg;
-
-    for (;;) {
-	pthread_mutex_lock(&w->mutex);
-	while (!w->exp)
-	    pthread_cond_wait(&w->cond, &w->mutex);
-	evaluate(w->exp);
-	w->exp->worker = NULL;
-	w->exp = NULL;
-	pthread_mutex_unlock(&w->mutex);
-	pthread_cond_signal(&w->cond);
-    }
-
-    return NULL;
+    evaluate((struct expression *) p);
 }
 
-static struct worker *get_worker(void)
-{
-    int i;
-
-    for (i = 0; i < num_workers; i++) {
-	struct worker *w = &workers[i];
-	if (!w->exp)
-	    return w;
-    }
-
-    return NULL;
-}
-
 static void begin_evaluate(struct expression *e)
 {
-    struct worker *w;
- 
-    if (e->worker)
-	G_fatal_error("Expression <%s> already has a worker", format_expression(e));
-
-    pthread_mutex_lock(&worker_mutex);
-    w = get_worker();
-    e->worker = w;
-
-    if (!w) {
-	pthread_mutex_unlock(&worker_mutex);
-	evaluate(e);
-	return;
-    }
-
-    pthread_mutex_lock(&w->mutex);
-    w->exp = e;
-    pthread_cond_signal(&w->cond);
-    pthread_mutex_unlock(&w->mutex);
-
-    pthread_mutex_unlock(&worker_mutex);
+    G_begin_execute(do_evaluate, e, &e->worker, 1);
 }
 
 static void end_evaluate(struct expression *e)
 {
-    struct worker *w = e->worker;
-
-    if (!w)
-	return;
-
-    pthread_mutex_lock(&w->mutex);
-    while (e->worker)
-	pthread_cond_wait(&w->cond, &w->mutex);
-    pthread_mutex_unlock(&w->mutex);
+    G_end_execute(&e->worker);
 }
 
-static void init_threads(void)
-{
-    const char *p = getenv("WORKERS");
-    int i;
-
-    pthread_mutex_init(&worker_mutex, NULL);
-
-    num_workers = p ? atoi(p) : 8;
-    workers = G_calloc(num_workers, sizeof(struct worker));
-
-    printf("num_workers = %d\n", num_workers);
-
-    for (i = 0; i < num_workers; i++) {
-	struct worker *w = &workers[i];
-	pthread_mutex_init(&w->mutex, NULL);
-	pthread_cond_init(&w->cond, NULL);
-	pthread_create(&w->thread, NULL, worker, w);
-    }
-}
-
-static void end_threads(void)
-{
-    int i;
-
-    pthread_mutex_destroy(&worker_mutex);
-
-    for (i = 0; i < num_workers; i++) {
-	struct worker *w = &workers[i];
-	pthread_cancel(w->thread);
-	pthread_mutex_destroy(&w->mutex);
-	pthread_cond_destroy(&w->cond);
-    }
-}
-
-#endif
-
 /****************************************************************************/
 
 static void evaluate_constant(expression * e)
@@ -266,7 +159,6 @@
     int i;
     int res;
 
-#ifdef USE_PTHREAD
     if (e->data.func.argc > 1 && e->data.func.func != f_eval) {
 	for (i = 1; i <= e->data.func.argc; i++)
 	    begin_evaluate(e->data.func.args[i]);
@@ -275,9 +167,8 @@
 	    end_evaluate(e->data.func.args[i]);
     }
     else
-#endif
-    for (i = 1; i <= e->data.func.argc; i++)
-	evaluate(e->data.func.args[i]);
+	for (i = 1; i <= e->data.func.argc; i++)
+	    evaluate(e->data.func.args[i]);
 
     res = (*e->data.func.func) (e->data.func.argc,
 				e->data.func.argt, e->data.func.argv);
@@ -439,9 +330,7 @@
     count = rows * depths;
     n = 0;
 
-#ifdef USE_PTHREAD
-    init_threads();
-#endif
+    G_init_workers();
 
     for (current_depth = 0; current_depth < depths; current_depth++)
 	for (current_row = 0; current_row < rows; current_row++) {
@@ -464,9 +353,7 @@
 	    n++;
 	}
 
-#ifdef USE_PTHREAD
-    end_threads();
-#endif
+    G_finish_workers();
 
     if (verbose)
 	G_percent(n, count, 2);



More information about the grass-commit mailing list