wxThread::GetCPUCount() and SetConcurrency() added and documented

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4837 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-12-06 12:31:04 +00:00
parent c92d798f9d
commit ef8d96c29c
7 changed files with 125 additions and 3 deletions

View File

@@ -6,7 +6,9 @@ next release (2.1.12 or 2.2?)
wxBase: 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 - wxLog functions are now (more) MT-safe
- wxStopWatch class, timer functions have more chances to return correct - wxStopWatch class, timer functions have more chances to return correct
results for your platform (use ANSI function where available) results for your platform (use ANSI function where available)

View 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 This function is called by wxWindows itself and should never be called
directly. 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} \membersection{wxThread::GetId}\label{wxthreadgetid}
\constfunc{unsigned long}{GetId}{\void} \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. 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} \membersection{wxThread::TestDestroy}\label{wxthreadtestdestroy}
\func{bool}{TestDestroy}{\void} \func{bool}{TestDestroy}{\void}

View File

@@ -280,6 +280,21 @@ public:
// NB: at least under MSW worker threads can not call ::wxSleep()! // NB: at least under MSW worker threads can not call ::wxSleep()!
static void Sleep(unsigned long milliseconds); 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 // constructor only creates the C++ thread object and doesn't create (or
// start) the real thread // start) the real thread
wxThread(wxThreadKind kind = wxTHREAD_DETACHED); wxThread(wxThreadKind kind = wxTHREAD_DETACHED);

View File

@@ -32,8 +32,8 @@
//#define TEST_ARRAYS //#define TEST_ARRAYS
//#define TEST_LOG //#define TEST_LOG
//#define TEST_STRINGS //#define TEST_STRINGS
//#define TEST_THREADS #define TEST_THREADS
#define TEST_TIME //#define TEST_TIME
//#define TEST_LONGLONG //#define TEST_LONGLONG
// ============================================================================ // ============================================================================
@@ -647,6 +647,8 @@ int main(int argc, char **argv)
#endif // TEST_LOG #endif // TEST_LOG
#ifdef TEST_THREADS #ifdef TEST_THREADS
printf("This system has %d CPUs\n", wxThread::GetCPUCount());
if ( argc > 1 && argv[1][0] == 't' ) if ( argc > 1 && argv[1][0] == 't' )
wxLog::AddTraceMask("thread"); wxLog::AddTraceMask("thread");

View File

@@ -145,6 +145,11 @@ wxTextFile::~wxTextFile()
// file operations // file operations
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool wxTextFile::Exists() const
{
return wxFile::Exists(m_strFile);
}
bool wxTextFile::Open(const wxString& strFile) bool wxTextFile::Open(const wxString& strFile)
{ {
m_strFile = strFile; m_strFile = strFile;

View File

@@ -527,6 +527,17 @@ void wxThread::Sleep(unsigned long milliseconds)
::Sleep(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 // ctor and dtor
// ------------- // -------------

View File

@@ -45,6 +45,15 @@
#include <sched.h> #include <sched.h>
#endif #endif
#ifdef HAVE_THR_SETCONCURRENCY
#include <thread.h>
#endif
// we use wxFFile under Linux in GetCPUCount()
#ifdef __LINUX__
#include "wx/ffile.h"
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// constants // constants
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -834,6 +843,63 @@ void wxThread::Sleep(unsigned long milliseconds)
wxUsleep(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 // creating thread
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------