]> git.saurik.com Git - wxWidgets.git/commitdiff
wxThread::GetCPUCount() and SetConcurrency() added and documented
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 6 Dec 1999 12:31:04 +0000 (12:31 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 6 Dec 1999 12:31:04 +0000 (12:31 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4837 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/thread.tex
include/wx/thread.h
samples/console/console.cpp
src/common/textfile.cpp
src/msw/thread.cpp
src/unix/threadpsx.cpp

index 861a746147eb1a52cd59a5588c2a306c1e9a3b80..ee12fcb7d0fbda57edb6838cdfe5fc0c871cf860 100644 (file)
@@ -6,7 +6,9 @@ next release (2.1.12 or 2.2?)
 
 wxBase:
 
-- wxThread class modified to support both detached and joinable threads
+- wxThread class modified to support both detached and joinable threads, also
+  added new GetCPUCount() and SetConcurrency() functions (useful under Solaris
+  only so far)
 - wxLog functions are now (more) MT-safe
 - wxStopWatch class, timer functions have more chances to return correct
   results for your platform (use ANSI function where available)
index cfdbc208797951acf8672860157d549bbb1d89e6..f7c4a1997e7352f7a8f53a4b509c50e293d5fcc3 100644 (file)
@@ -127,6 +127,16 @@ joinable threads and is the value returned by \helpref{Wait}{wxthreadwait}.
 This function is called by wxWindows itself and should never be called
 directly.
 
+\membersection{wxThread::GetCPUCount}\label{wxthreadgetcpucount}
+
+\func{static int}{GetCPUCount}{\void}
+
+Returns the number of system CPUs or -1 if the value is unknown.
+
+\wxheading{See also}
+
+\helpref{SetConcurrency}{wxthreadsetconcurrency}
+
 \membersection{wxThread::GetId}\label{wxthreadgetid}
 
 \constfunc{unsigned long}{GetId}{\void}
@@ -253,6 +263,17 @@ Resumes a thread suspended by the call to \helpref{Pause}{wxthreadpause}.
 
 This function can only be called from another thread context.
 
+\membersection{wxThread::SetConcurrency}\label{wxthreadsetconcurrency}
+
+\func{static bool}{SetConcurrency}{\param{size\_t }{level}}
+
+Sets the thread concurrency level for this process. This is, roughly, the
+number of threads that the system tries to schedule to run in parallel.
+The value of $0$ for {\it level} may be used to set the default one.
+
+Returns TRUE on success or FALSE otherwise (for example, if this function is
+not implemented for this platform (currently everything except Solaris)).
+
 \membersection{wxThread::TestDestroy}\label{wxthreadtestdestroy}
 
 \func{bool}{TestDestroy}{\void}
index 7c9df994de28333a0f30fb353584502b2bc2796f..a4c4b465df675a18b85ff13a48f20618f7e07589 100644 (file)
@@ -280,6 +280,21 @@ public:
         // NB: at least under MSW worker threads can not call ::wxSleep()!
     static void Sleep(unsigned long milliseconds);
 
+        // get the number of system CPUs - useful with SetConcurrency()
+        // (the "best" value for it is usually number of CPUs + 1)
+        //
+        // Returns -1 if unknown, number of CPUs otherwise
+    static int GetCPUCount();
+
+        // sets the concurrency level: this is, roughly, the number of threads
+        // the system tries to schedule to run in parallel. 0 means the
+        // default value (usually acceptable, but may not yield the best
+        // performance for this process)
+        //
+        // Returns TRUE on success, FALSE otherwise (if not implemented, for
+        // example)
+    static bool SetConcurrency(size_t level);
+
     // constructor only creates the C++ thread object and doesn't create (or
     // start) the real thread
     wxThread(wxThreadKind kind = wxTHREAD_DETACHED);
index 981a302ac35072e23ed5020941eaba82e6ee7e2c..0a08f86c1484b7ef8e41ed4d4a440c955eba10bf 100644 (file)
@@ -32,8 +32,8 @@
 //#define TEST_ARRAYS
 //#define TEST_LOG
 //#define TEST_STRINGS
-//#define TEST_THREADS
-#define TEST_TIME
+#define TEST_THREADS
+//#define TEST_TIME
 //#define TEST_LONGLONG
 
 // ============================================================================
@@ -647,6 +647,8 @@ int main(int argc, char **argv)
 #endif // TEST_LOG
 
 #ifdef TEST_THREADS
+    printf("This system has %d CPUs\n", wxThread::GetCPUCount());
+
     if ( argc > 1 && argv[1][0] == 't' )
         wxLog::AddTraceMask("thread");
 
index 9b35dfd8deadd655cfef999f3d2b35a61f0696eb..5c74b3ab570b576304866d071a7b696ff4f96ae7 100644 (file)
@@ -145,6 +145,11 @@ wxTextFile::~wxTextFile()
 // file operations
 // ----------------------------------------------------------------------------
 
+bool wxTextFile::Exists() const
+{
+    return wxFile::Exists(m_strFile);
+}
+
 bool wxTextFile::Open(const wxString& strFile)
 {
   m_strFile = strFile;
index 3ae5d7b979e867d983f9620a520cbbc8751e77e5..35838d9a2985eaec4ceee4640744c12db39975d2 100644 (file)
@@ -527,6 +527,17 @@ void wxThread::Sleep(unsigned long milliseconds)
     ::Sleep(milliseconds);
 }
 
+int wxThread::GetCPUCount()
+{
+    return -1;
+}
+
+bool wxThread::SetConcurrency(size_t level)
+{
+    // ok only for the default one
+    return level == 0;
+}
+
 // ctor and dtor
 // -------------
 
index fad73a2df9fb83bd6f923e0707dd7adf4e12d270..34f3cd81b4224fe665a134d950b76a57c69ba748 100644 (file)
     #include <sched.h>
 #endif
 
+#ifdef HAVE_THR_SETCONCURRENCY
+    #include <thread.h>
+#endif
+
+// we use wxFFile under Linux in GetCPUCount()
+#ifdef __LINUX__
+    #include "wx/ffile.h"
+#endif
+
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
@@ -834,6 +843,63 @@ void wxThread::Sleep(unsigned long milliseconds)
     wxUsleep(milliseconds);
 }
 
+int wxThread::GetCPUCount()
+{
+#if defined(__LINUX__)
+    // read from proc (can't use wxTextFile here because it's a special file:
+    // it has 0 size but still can be read from)
+    wxLogNull nolog;
+
+    wxFFile file(_T("/proc/cpuinfo"));
+    if ( file.IsOpened() )
+    {
+        // slurp the whole file
+        wxString s;
+        if ( file.ReadAll(&s) )
+        {
+            // (ab)use Replace() to find the number of "processor" strings
+            size_t count = s.Replace(_T("processor"), _T(""));
+            if ( count > 0 )
+            {
+                return count;
+            }
+
+            wxLogDebug(_T("failed to parse /proc/cpuinfo"));
+        }
+        else
+        {
+            wxLogDebug(_T("failed to read /proc/cpuinfo"));
+        }
+    }
+#elif defined(_SC_NPROCESSORS_ONLN)
+    // this works for Solaris
+    int rc = sysconf(_SC_NPROCESSORS_ONLN);
+    if ( rc != -1 )
+    {
+        return rc;
+    }
+#endif // different ways to get number of CPUs
+
+    // unknown
+    return -1;
+}
+
+bool wxThread::SetConcurrency(size_t level)
+{
+#ifdef HAVE_THR_SETCONCURRENCY
+    int rc = thr_setconcurrency(level);
+    if ( rc != 0 )
+    {
+        wxLogSysError(rc, _T("thr_setconcurrency() failed"));
+    }
+
+    return rc == 0;
+#else // !HAVE_THR_SETCONCURRENCY
+    // ok only for the default value
+    return level == 0;
+#endif // HAVE_THR_SETCONCURRENCY/!HAVE_THR_SETCONCURRENCY
+}
+
 // -----------------------------------------------------------------------------
 // creating thread
 // -----------------------------------------------------------------------------