[glib] Add g_get_num_processors()



commit 2149b29468bb99af3c29d5de61f75aad735082dc
Author: Colin Walters <walters verbum org>
Date:   Mon Dec 17 10:47:53 2012 -0500

    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

 docs/reference/glib/glib-sections.txt |    3 ++
 glib/glib.symbols                     |    1 +
 glib/gthread.c                        |   56 +++++++++++++++++++++++++++++++++
 glib/gthread.h                        |    3 ++
 glib/tests/spawn-multithreaded.c      |   10 +++--
 5 files changed, 69 insertions(+), 4 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index e4e9df4..c3f694a 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -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
diff --git a/glib/glib.symbols b/glib/glib.symbols
index 2ae79d9..d48b39d 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -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
diff --git a/glib/gthread.c b/glib/gthread.c
index d3a924a..c27bca6 100644
--- a/glib/gthread.c
+++ b/glib/gthread.c
@@ -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: */
diff --git a/glib/gthread.h b/glib/gthread.h
index 710b64d..b9c3025 100644
--- a/glib/gthread.h
+++ b/glib/gthread.h
@@ -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__ */
diff --git a/glib/tests/spawn-multithreaded.c b/glib/tests/spawn-multithreaded.c
index 239bbf6..baccf36 100644
--- a/glib/tests/spawn-multithreaded.c
+++ b/glib/tests/spawn-multithreaded.c
@@ -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;
+
+  /* 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++)
+  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));



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]