Add g_get_num_processors()

Based on a patch from John Cupitt <jcupitt@gmail.com>

Useful for thread pools which should scale to number of processors.

See https://bugzilla.gnome.org/show_bug.cgi?id=687223

https://bugzilla.gnome.org/show_bug.cgi?id=614930
This commit is contained in:
Colin Walters 2012-12-17 10:47:53 -05:00
parent ed5accf16c
commit 2149b29468
5 changed files with 69 additions and 4 deletions

View File

@ -650,6 +650,9 @@ g_pointer_bit_lock
g_pointer_bit_trylock
g_pointer_bit_unlock
<SUBSECTION>
g_get_num_processors
<SUBSECTION Private>
G_LOCK_NAME
atexit

View File

@ -179,6 +179,7 @@ g_completion_new
g_completion_remove_items
g_completion_set_compare
g_get_filename_charsets
g_get_num_processors
g_convert
g_convert_error_quark
g_convert_with_fallback

View File

@ -1007,5 +1007,61 @@ g_thread_self (void)
return (GThread*) thread;
}
/**
* g_get_num_processors:
*
* Determine the approximate number of threads that the system will
* schedule simultaneously for this process. This is intended to be
* used as a parameter to g_thread_pool_new() for CPU bound tasks and
* similar cases.
*
* Returns: Number of schedulable threads, always greater than 0
*
* Since: 2.36
*/
guint
g_get_num_processors (void)
{
#ifdef G_OS_WIN32
DWORD_PTR process_cpus;
DWORD_PTR system_cpus;
if (GetProcessAffinityMask (GetCurrentProcess (),
&process_cpus, &system_cpus))
{
unsigned int count;
for (count = 0; process_cpus != 0; process_cpus >>= 1)
if (process_cpus & 1)
count++;
if (count > 0)
return count;
}
#elif defined(HAVE_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
{
int count;
count = sysconf (_SC_NPROCESSORS_ONLN);
if (count > 0)
return count;
}
#elif defined HW_NCPU
{
int mib[2], count = 0;
size_t len;
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
len = sizeof(count);
if (sysctl (mib, 2, &count, &len, NULL, 0) == 0 && count > 0)
return count;
}
#endif
return 1; /* Fallback */
}
/* Epilogue {{{1 */
/* vim: set foldmethod=marker: */

View File

@ -249,6 +249,9 @@ void g_once_init_leave (volatile void *location,
(g_once_init_leave((location), (gsize) (result)))
#endif
GLIB_AVAILABLE_IN_2_36
guint g_get_num_processors (void);
G_END_DECLS
#endif /* __G_THREAD_H__ */

View File

@ -26,8 +26,6 @@
#include <glib.h>
#include <string.h>
#define N_THREADS (20)
static char *echo_prog_path;
static void
@ -35,8 +33,12 @@ multithreaded_test_run (GThreadFunc function)
{
int i;
GPtrArray *threads = g_ptr_array_new ();
guint n_threads;
for (i = 0; i < N_THREADS; i++)
/* Limit to 64, otherwise we may hit file descriptor limits and such */
n_threads = MIN (g_get_num_processors () * 2, 64);
for (i = 0; i < n_threads; i++)
{
GThread *thread;
@ -44,7 +46,7 @@ multithreaded_test_run (GThreadFunc function)
g_ptr_array_add (threads, thread);
}
for (i = 0; i < N_THREADS; i++)
for (i = 0; i < n_threads; i++)
{
gpointer ret;
ret = g_thread_join (g_ptr_array_index (threads, i));