[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