diff -c -r glib-2.22.5/glib/glib.symbols glib-2.22.5-john/glib/glib.symbols
*** glib-2.22.5/glib/glib.symbols	2010-03-16 02:38:47.000000000 +0000
--- glib-2.22.5-john/glib/glib.symbols	2010-04-05 23:08:34.605962182 +0100
***************
*** 1309,1314 ****
--- 1309,1315 ----
  g_static_rw_lock_writer_unlock
  g_thread_foreach
  g_thread_get_initialized
+ g_get_num_processors
  #endif
  #endif
  
diff -c -r glib-2.22.5/glib/gthread.c glib-2.22.5-john/glib/gthread.c
*** glib-2.22.5/glib/gthread.c	2010-03-16 02:38:47.000000000 +0000
--- glib-2.22.5-john/glib/gthread.c	2010-04-05 23:38:36.253397888 +0100
***************
*** 115,121 ****
    NULL,                                        /* thread_exit */
    NULL,                                        /* thread_set_priority */
    NULL,                                        /* thread_self */
!   NULL                                         /* thread_equal */
  };
  
  /* Local data */
--- 115,122 ----
    NULL,                                        /* thread_exit */
    NULL,                                        /* thread_set_priority */
    NULL,                                        /* thread_self */
!   NULL,                                        /* thread_equal */
!   NULL                                         /* num_processors */
  };
  
  /* Local data */
***************
*** 989,993 ****
--- 990,1010 ----
    return g_thread_supported ();
  }
  
+ /**
+  * g_get_num_processors
+  *
+  * Returns the maximum number of simultaneous threads of execution available
+  * to this process.
+  *
+  * Returns: the maximum number of simultaneous threads of execution
+  *
+  * Since: 2.24
+  */
+ int
+ g_get_num_processors (void)
+ {
+   return G_THREAD_UF (num_processors, ());
+ }
+ 
  #define __G_THREAD_C__
  #include "galiasdef.c"
diff -c -r glib-2.22.5/glib/gthread.h glib-2.22.5-john/glib/gthread.h
*** glib-2.22.5/glib/gthread.h	2010-03-16 02:38:47.000000000 +0000
--- glib-2.22.5-john/glib/gthread.h	2010-04-05 23:29:02.225944610 +0100
***************
*** 111,116 ****
--- 111,117 ----
    void      (*thread_self)        (gpointer              thread);
    gboolean  (*thread_equal)       (gpointer              thread1,
  				   gpointer              thread2);
+   int	    (*num_processors)	  (void);
  };
  
  GLIB_VAR GThreadFunctions       g_thread_functions_for_glib_use;
***************
*** 232,237 ****
--- 233,240 ----
  void     g_thread_set_priority (GThread               *thread,
                                  GThreadPriority        priority);
  
+ int	 g_get_num_processors  (void);
+ 
  /* GStaticMutexes can be statically initialized with the value
   * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
   * much easier, than having to explicitly allocate the mutex before
diff -c -r glib-2.22.5/gthread/gthread-impl.c glib-2.22.5-john/gthread/gthread-impl.c
*** glib-2.22.5/gthread/gthread-impl.c	2010-03-16 02:38:47.000000000 +0000
--- glib-2.22.5-john/gthread/gthread-impl.c	2010-04-05 22:40:54.584373626 +0100
***************
*** 334,340 ****
  	       init->thread_join &&
  	       init->thread_exit &&
  	       init->thread_set_priority &&
! 	       init->thread_self);
  
    /* if somebody is calling g_thread_init (), it means that he wants to
     * have thread support, so check this
--- 334,341 ----
  	       init->thread_join &&
  	       init->thread_exit &&
  	       init->thread_set_priority &&
! 	       init->thread_self &&
! 	       init->num_processors);
  
    /* if somebody is calling g_thread_init (), it means that he wants to
     * have thread support, so check this
diff -c -r glib-2.22.5/gthread/gthread-posix.c glib-2.22.5-john/gthread/gthread-posix.c
*** glib-2.22.5/gthread/gthread-posix.c	2009-04-01 00:04:20.000000000 +0100
--- glib-2.22.5-john/gthread/gthread-posix.c	2010-04-05 22:29:24.823425338 +0100
***************
*** 441,448 ****
  static guint64 (*g_thread_gettime_impl)(void) = 0;
  #endif
  
! static GThreadFunctions g_thread_functions_for_glib_use_default =
  {
    g_mutex_new_posix_impl,
    (void (*)(GMutex *)) pthread_mutex_lock,
    g_mutex_trylock_posix_impl,
--- 441,485 ----
  static guint64 (*g_thread_gettime_impl)(void) = 0;
  #endif
  
! static int
! g_num_processors_posix_impl (void)
  {
+   int nproc;
+ 
+   nproc = 1;
+ 
+ #if defined(HAVE_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
+   {
+     /* POSIX style.
+      */
+     int x;
+ 
+     x = sysconf (_SC_NPROCESSORS_ONLN);
+     if (x > 0)
+       nproc = x;
+   }
+ #elif defined HW_NCPU
+   {
+     /* BSD style.
+      */
+     int x;
+     size_t len = sizeof (x);
+ 
+     sysctl ((int[2]) {CTL_HW, HW_NCPU}, 2, &x, &len, NULL, 0);
+     if (x > 0)
+       nproc = x;
+   }
+ #endif
+ 
+   /* libgomp has some very complex code on Linux to count the number of
+    * processors available to the current process taking pthread affinity
+    * into account, but we don't attempt that here. Perhaps we should?
+    */
+ 
+   return nproc;
+ }
+ 
+ static GThreadFunctions g_thread_functions_for_glib_use_default = {
    g_mutex_new_posix_impl,
    (void (*)(GMutex *)) pthread_mutex_lock,
    g_mutex_trylock_posix_impl,
***************
*** 463,467 ****
    g_thread_exit_posix_impl,
    g_thread_set_priority_posix_impl,
    g_thread_self_posix_impl,
!   g_thread_equal_posix_impl
  };
--- 500,505 ----
    g_thread_exit_posix_impl,
    g_thread_set_priority_posix_impl,
    g_thread_self_posix_impl,
!   g_thread_equal_posix_impl,
!   g_num_processors_posix_impl
  };
diff -c -r glib-2.22.5/gthread/gthread-win32.c glib-2.22.5-john/gthread/gthread-win32.c
*** glib-2.22.5/gthread/gthread-win32.c	2009-04-01 00:04:20.000000000 +0100
--- glib-2.22.5-john/gthread/gthread-win32.c	2010-04-05 22:03:15.373423470 +0100
***************
*** 561,566 ****
--- 561,593 ----
    return v;
  }
  
+ static int
+ g_num_processors_win32_impl (void)
+ {
+   /* Count the CPUs currently available to this process.  
+    */
+   int nproc;
+   DWORD_PTR process_cpus;
+   DWORD_PTR system_cpus;
+ 
+   nproc = 1;
+ 
+   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)
+ 	nproc = count;
+     }
+ 
+   return nproc;
+ }
+ 
  static GThreadFunctions g_thread_functions_for_glib_use_default =
  {
    g_mutex_new_win32_impl,           /* mutex */
***************
*** 583,589 ****
    g_thread_exit_win32_impl,
    g_thread_set_priority_win32_impl,
    g_thread_self_win32_impl,
!   NULL                             /* no equal function necessary */
  };
  
  #define HAVE_G_THREAD_IMPL_INIT
--- 610,617 ----
    g_thread_exit_win32_impl,
    g_thread_set_priority_win32_impl,
    g_thread_self_win32_impl,
!   NULL,                             /* no equal function necessary */
!   g_num_processors_win32_impl
  };
  
  #define HAVE_G_THREAD_IMPL_INIT
diff -c -r glib-2.22.5/tests/thread-test.c glib-2.22.5-john/tests/thread-test.c
*** glib-2.22.5/tests/thread-test.c	2009-04-01 00:04:21.000000000 +0100
--- glib-2.22.5-john/tests/thread-test.c	2010-04-05 23:41:48.463402757 +0100
***************
*** 369,374 ****
--- 369,384 ----
      }
  }
  
+ static void
+ test_g_get_num_processors (void)
+ {
+   int nprocs;
+ 
+   nprocs = g_get_num_processors ();
+ 
+   g_assert (nprocs >= 1 && nprocs < 10000);
+ }
+ 
  /* run all the tests */
  void
  run_all_tests()
***************
*** 378,383 ****
--- 388,394 ----
    test_g_static_private ();
    test_g_static_rw_lock ();
    test_g_thread_once ();
+   test_g_get_num_processors ();
  }
  
  int 
