You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2007/06/27 02:15:38 UTC

svn commit: r550994 - in /incubator/stdcxx/trunk/tests: include/rw_thread.h src/thread.cpp

Author: sebor
Date: Tue Jun 26 17:15:37 2007
New Revision: 550994

URL: http://svn.apache.org/viewvc?view=rev&rev=550994
Log:
2007-06-26  Martin Sebor  <se...@roguewave.com>

	* rw_thread.h (rw_get_cpus): New function to determine the number
	of processors on the system.
	* thread.cpp (rw_get_cpus): Defined it.
	(rw_thread_pool): Called rw_get_cpus() to set nthreads when the
	argument is equal to SIZE_MAX.

Modified:
    incubator/stdcxx/trunk/tests/include/rw_thread.h
    incubator/stdcxx/trunk/tests/src/thread.cpp

Modified: incubator/stdcxx/trunk/tests/include/rw_thread.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/include/rw_thread.h?view=diff&rev=550994&r1=550993&r2=550994
==============================================================================
--- incubator/stdcxx/trunk/tests/include/rw_thread.h (original)
+++ incubator/stdcxx/trunk/tests/include/rw_thread.h Tue Jun 26 17:15:37 2007
@@ -59,9 +59,11 @@
 
 // create a pool of nthreads, passing each a successive element
 // of argarray as argument (if non-null) and filling the tidarray
-// array with their id's; if tidarray is null, waits for all
+// array with their id's; if (tidarray == 0), waits for all
 // threads to join and fills the aragarray with the result
 // returned from each thread
+// if (nthreads == SIZE_MAX), sets nthreads to the positive result
+// of rw_get_processors() plus 1, or to 2 otherwise
 // returns 0 on success, or a non-zero value indicating the thread
 // number that failed to create on error
 _TEST_EXPORT int
@@ -70,6 +72,12 @@
                 rw_thread_attr_t* /* attr */,
                 void* (*)(void*)  /* thr_proc */,
                 void**            /* argarray */);
+
+// returns the number of logical processors/cores on the system,
+// or -1 on error
+_TEST_EXPORT int
+rw_get_cpus ();
+
 
 }   // extern "C"
 

Modified: incubator/stdcxx/trunk/tests/src/thread.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/src/thread.cpp?view=diff&rev=550994&r1=550993&r2=550994
==============================================================================
--- incubator/stdcxx/trunk/tests/src/thread.cpp (original)
+++ incubator/stdcxx/trunk/tests/src/thread.cpp Tue Jun 26 17:15:37 2007
@@ -31,8 +31,13 @@
 
 #include <rw_thread.h>
 #include <stddef.h>     // for size_t
+#include <stdio.h>      // for FILE, fscanf(), popen()
 #include <string.h>     // for memset()
 
+#ifdef _WIN32
+#  define popen(name, mode)   _popen(name, mode)
+#endif   // _WIN32
+
 /**************************************************************************/
 
 static long maxthreads;
@@ -369,22 +374,108 @@
 
 #endif   // threads environment
 
+/**************************************************************************/
+
+// retrieves the number of processors/cores on the system
+_TEST_EXPORT int
+rw_get_cpus ()
+{
+    const char* const cmd = {
+        // shell command(s) to obtain the number of processors
+
+#ifdef _RWSTD_OS_AIX
+        // AIX: /etc/lsdev -Cc processor | wc -l
+        "/etc/lsdev -Cc processor | /usr/bin/wc -l"
+#elif defined (_RWSTD_OS_LINUX)
+        // Linux: cat /proc/cpuinfo | grep processor | wc -l
+        "/usr/bin/cat /proc/cpuinfo "
+        "  | /usr/bin/grep processor "
+        "  | /usr/bin/wc -l"
+#elif defined (_RWSTD_OS_FREEBSD)
+        // FreeBSD: /sbin/sysctl -n hw.ncpu
+        "/sbin/sysctl -n hw.ncpu"
+#elif defined (_RWSTD_OS_HP_UX)
+        // HP-UX: /etc/ioscan -k -C processor | grep processor | wc -l
+        "/etc/ioscan -k -C processor "
+        "  | /usr/bin/grep processor "
+        "  | /usr/bin/wc -l"
+#elif defined (_RWSTD_OS_IRIX64)
+        // IRIX: hinv | /usr/bin/grep "^[1-9][0-9]* .* Processor"
+        "/sbin/hinv "
+        "  | /usr/bin/grep \"^[1-9][0-9]* .* Processor\""
+#elif defined (_RWSTD_OS_OSF1)
+        // Tru64 UNIX: /usr/sbin/psrinfo | grep online | wc -l
+        "/usr/sbin/psrinfo "
+        "  | /usr/bin/grep on[-]*line "
+        "  | /usr/bin wc -l"
+#elif defined (_RWSTD_OS_SUNOS)
+        // Solaris: /usr/bin/mpstat | wc -l
+        "/usr/bin/mpstat "
+        "  | /usr/bin/grep -v \"^CPU\" "
+        "  | /usr/bin/wc -l"
+#elif defined (_RWSTD_OS_WINDOWS)
+        // Windows: ???
+        0
+#else
+        0
+#endif
+
+    };
+
+    int ncpus = -1;
+
+    if (cmd) {
+        // open and read the output of the command from a pipe
+        FILE* const fp = popen (cmd, "r");
+
+        if (fp) {
+            int tmp = 0;
+        
+            int n = fscanf (fp, "%d", &tmp);
+
+            if (1 == n)
+                ncpus = tmp;
+
+            fclose (fp);
+        }
+    }
+
+    return ncpus;
+}
+
+/**************************************************************************/
 
 extern "C" {
 
 
 _TEST_EXPORT int
-rw_thread_pool (rw_thread_t *thr_id, size_t nthrs,
+rw_thread_pool (rw_thread_t        *thr_id,
+                size_t              nthrs,
                 rw_thread_attr_t*,
-                void* (*thr_proc)(void*),
-                void **thr_arg)
+                void*             (*thr_proc)(void*),
+                void*              *thr_arg)
 {
     // small buffer for thread ids when invoked with (thr_id == 0)
     rw_thread_t id_buf [16];
 
     const bool join = 0 == thr_id;
 
-#ifndef _RWSTD_REENTRANT
+#ifdef _RWSTD_REENTRANT
+
+    if (_RWSTD_SIZE_MAX == nthrs) {
+        // when the number of threads is -1 use the number
+        // of processors plus 1 (in case it's 1 to begin
+        // with)
+
+        const int ncpus = rw_get_cpus ();
+
+        if (0 < ncpus)
+            nthrs = size_t (ncpus) + 1;
+        else
+            nthrs = 2;
+    }
+
+#else
 
     // when not reentrant/thread safe emulate the creation
     // of a single thread and then waiting for it to finish
@@ -408,7 +499,6 @@
 
         return 0;
     }
-
 #endif   // !_RWSTD_REENTRANT
 
     bool delete_ids = false;