One pool is for remote (i.e. downloading) requests.
One pool is for local CPU tasks.
Thus for best performance the number of CPU bound tasks should not be more than the number of CPUs available.
Whereas for network requests, the number of active tasks can be higher.
<listitem>
<para>background_max_threads=10</para>
</listitem>
+ <listitem>
+ <para>background_max_threads_local=<emphasis>Number of CPUs</emphasis></para>
+ </listitem>
<listitem>
<para>window_menubar=true</para>
</listitem>
* viking -- GPS Data and Topo Analyzer, Explorer, and Manager
*
* Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
+ * Copyright (c) 2015, Rob Norris <rw_norris@hotmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "background.h"
#include "settings.h"
+#include "util.h"
-static GThreadPool *thread_pool = NULL;
+static GThreadPool *thread_pool_remote = NULL;
+static GThreadPool *thread_pool_local = NULL;
static gboolean stop_all_threads = FALSE;
static GtkWidget *bgwindow = NULL;
/**
* a_background_thread:
+ * @bp: Which pool this thread should run in
* @parent:
* @message:
* @func: worker function
*
* Function to enlist new background function.
*/
-void a_background_thread ( GtkWindow *parent, const gchar *message, vik_thr_func func, gpointer userdata, vik_thr_free_func userdata_free_func, vik_thr_free_func userdata_cancel_cleanup_func, gint number_items )
+void a_background_thread ( Background_Pool_Type bp, GtkWindow *parent, const gchar *message, vik_thr_func func, gpointer userdata, vik_thr_free_func userdata_free_func, vik_thr_free_func userdata_cancel_cleanup_func, gint number_items )
{
GtkTreeIter *piter = g_malloc ( sizeof ( GtkTreeIter ) );
gpointer *args = g_malloc ( sizeof(gpointer) * VIK_BG_NUM_ARGS );
-1 );
/* run the thread in the background */
- g_thread_pool_push( thread_pool, args, NULL );
+ if ( bp == BACKGROUND_POOL_REMOTE )
+ g_thread_pool_push( thread_pool_remote, args, NULL );
+ else
+ g_thread_pool_push( thread_pool_local, args, NULL );
}
/**
}
#define VIK_SETTINGS_BACKGROUND_MAX_THREADS "background_max_threads"
+#define VIK_SETTINGS_BACKGROUND_MAX_THREADS_LOCAL "background_max_threads_local"
/**
* a_background_init:
*/
void a_background_init()
{
- /* initialize thread pool */
+ // initialize thread pools
gint max_threads = 10; /* limit maximum number of threads running at one time */
gint maxt;
if ( a_settings_get_integer ( VIK_SETTINGS_BACKGROUND_MAX_THREADS, &maxt ) )
max_threads = maxt;
- thread_pool = g_thread_pool_new ( (GFunc) thread_helper, NULL, max_threads, FALSE, NULL );
+ thread_pool_remote = g_thread_pool_new ( (GFunc) thread_helper, NULL, max_threads, FALSE, NULL );
+
+ if ( a_settings_get_integer ( VIK_SETTINGS_BACKGROUND_MAX_THREADS_LOCAL, &maxt ) )
+ max_threads = maxt;
+ else {
+ guint cpus = util_get_number_of_cpus ();
+ max_threads = cpus > 1 ? cpus-1 : 1; // Don't use all available CPUs!
+ }
+
+ thread_pool_local = g_thread_pool_new ( (GFunc) thread_helper, NULL, max_threads, FALSE, NULL );
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
*/
void a_background_uninit()
{
- /* wait until all running threads stop */
stop_all_threads = TRUE;
- g_thread_pool_free ( thread_pool, TRUE, TRUE );
+ // wait until these threads stop
+ g_thread_pool_free ( thread_pool_remote, TRUE, TRUE );
+ // Don't wait for these
+ g_thread_pool_free ( thread_pool_local, TRUE, FALSE );
gtk_list_store_clear ( bgstore );
g_object_unref ( bgstore );
typedef void(*vik_thr_free_func)(gpointer);
typedef void(*vik_thr_func)(gpointer,gpointer);
-/* the new way */
-void a_background_thread ( GtkWindow *parent, const gchar *message, vik_thr_func func, gpointer userdata, vik_thr_free_func userdata_free_func, vik_thr_free_func userdata_cancel_cleanup_func, gint number_items );
+typedef enum {
+ BACKGROUND_POOL_REMOTE, // i.e. Network requests - can have an arbitary large pool
+ BACKGROUND_POOL_LOCAL, // i.e. CPU bound tasks - pool should be no larger than available CPUs for best performance
+} Background_Pool_Type;
+
+void a_background_thread ( Background_Pool_Type bp, GtkWindow *parent, const gchar *message, vik_thr_func func, gpointer userdata, vik_thr_free_func userdata_free_func, vik_thr_free_func userdata_cancel_cleanup_func, gint number_items );
int a_background_thread_progress ( gpointer callbackdata, gdouble fraction );
int a_background_testcancel ( gpointer callbackdata );
void a_background_show_window ();
static void
_async_load_attributions ( BingMapSource *self )
{
- a_background_thread ( /*VIK_GTK_WINDOW_FROM_WIDGET(vp)*/NULL,
- _("Bing attribution Loading"),
- (vik_thr_func) _load_attributions_thread,
- self,
- NULL,
- NULL,
- 1 );
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ /*VIK_GTK_WINDOW_FROM_WIDGET(vp)*/NULL,
+ _("Bing attribution Loading"),
+ (vik_thr_func) _load_attributions_thread,
+ self,
+ NULL,
+ NULL,
+ 1 );
}
title = g_strdup_printf(_("Uploading %s to OSM"), info->name);
- /* launch the thread */
- a_background_thread(VIK_GTK_WINDOW_FROM_LAYER(vtl), /* parent window */
- title, /* description string */
- (vik_thr_func) osm_traces_upload_thread, /* function to call within thread */
- info, /* pass along data */
- (vik_thr_free_func) oti_free, /* function to free pass along data */
- (vik_thr_free_func) NULL,
- 1 );
+ // launch the thread
+ a_background_thread( BACKGROUND_POOL_REMOTE,
+ VIK_GTK_WINDOW_FROM_LAYER(vtl), /* parent window */
+ title, /* description string */
+ (vik_thr_func) osm_traces_upload_thread, /* function to call within thread */
+ info, /* pass along data */
+ (vik_thr_free_func) oti_free, /* function to free pass along data */
+ (vik_thr_free_func) NULL,
+ 1 );
g_free ( title ); title = NULL;
}
gtk_widget_destroy ( dia );
dltd->vdl = vdl;
dltd->vdl->files = data.sl;
- a_background_thread ( VIK_GTK_WINDOW_FROM_WIDGET(vp),
+ a_background_thread ( BACKGROUND_POOL_LOCAL,
+ VIK_GTK_WINDOW_FROM_WIDGET(vp),
_("DEM Loading"),
(vik_thr_func) dem_layer_load_list_thread,
dltd,
p->source = vdl->source;
g_object_weak_ref(G_OBJECT(p->vdl), weak_ref_cb, p );
- a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vdl), tmp,
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ VIK_GTK_WINDOW_FROM_LAYER(vdl), tmp,
(vik_thr_func) dem_download_thread, p,
(vik_thr_free_func) free_dem_download_params, NULL, 1 );
g_object_weak_ref(G_OBJECT(mdi->vml), weak_ref_cb, mdi);
/* launch the thread */
- a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vml), /* parent window */
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ VIK_GTK_WINDOW_FROM_LAYER(vml), /* parent window */
tmp, /* description string */
(vik_thr_func) map_download_thread, /* function to call within thread */
mdi, /* pass along data */
tmp = g_strdup_printf ( fmt, mdi->mapstoget, MAPS_LAYER_NTH_LABEL(vml->maptype) );
g_object_weak_ref(G_OBJECT(mdi->vml), weak_ref_cb, mdi);
- /* launch the thread */
- a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vml), /* parent window */
- tmp, /* description string */
- (vik_thr_func) map_download_thread, /* function to call within thread */
- mdi, /* pass along data */
- (vik_thr_free_func) mdi_free, /* function to free pass along data */
- (vik_thr_free_func) mdi_cancel_cleanup,
- mdi->mapstoget );
+
+ // launch the thread
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ VIK_GTK_WINDOW_FROM_LAYER(vml), /* parent window */
+ tmp, /* description string */
+ (vik_thr_func) map_download_thread, /* function to call within thread */
+ mdi, /* pass along data */
+ (vik_thr_free_func) mdi_free, /* function to free pass along data */
+ (vik_thr_free_func) mdi_cancel_cleanup,
+ mdi->mapstoget );
g_free ( tmp );
}
else
thumbnail_create_thread_data *tctd = g_malloc ( sizeof(thumbnail_create_thread_data) );
tctd->vtl = vtl;
tctd->pics = pics;
- a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
+ a_background_thread ( BACKGROUND_POOL_LOCAL,
+ VIK_GTK_WINDOW_FROM_LAYER(vtl),
tmp,
(vik_thr_func) create_thumbnails_thread,
tctd,
gchar *tmp = g_strdup_printf ( _("Geotagging %d Images..."), len );
// Processing lots of files can take time - so run a background effort
- a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(options->vtl),
- tmp,
- (vik_thr_func) trw_layer_geotag_thread,
- options,
- (vik_thr_free_func) trw_layer_geotag_thread_free,
- NULL,
- len );
+ a_background_thread ( BACKGROUND_POOL_LOCAL,
+ VIK_GTK_WINDOW_FROM_LAYER(options->vtl),
+ tmp,
+ (vik_thr_func) trw_layer_geotag_thread,
+ options,
+ (vik_thr_free_func) trw_layer_geotag_thread_free,
+ NULL,
+ len );
g_free ( tmp );
vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, _("Trying to determine location...") );
- a_background_thread ( GTK_WINDOW(vw),
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ GTK_WINDOW(vw),
_("Determining location"),
(vik_thr_func) determine_location_thread,
vw,