diff options
Diffstat (limited to 'src/base/ThreadHelper.cpp')
-rw-r--r-- | src/base/ThreadHelper.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/base/ThreadHelper.cpp b/src/base/ThreadHelper.cpp new file mode 100644 index 0000000..105e116 --- /dev/null +++ b/src/base/ThreadHelper.cpp @@ -0,0 +1,94 @@ +// +// libavg - Media Playback Engine. +// Copyright (C) 2003-2014 Ulrich von Zadow +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Current versions can be found at www.libavg.de +// + +#include "ThreadHelper.h" +#include "OSHelper.h" + +#ifdef _WIN32 +#include <Windows.h> +#endif + +namespace avg { + +void setAffinityMask(bool bIsMainThread) +{ + // The main thread gets the first processor to itself. All other threads share the + // rest of the processors available, unless, of course, there is only one processor + // in the machine. +#ifdef linux + static cpu_set_t allProcessors; + static bool bInitialized = false; + if (!bInitialized) { + int rc = sched_getaffinity(0, sizeof(allProcessors), &allProcessors); + AVG_ASSERT(rc == 0); +// cerr << "All processors: "; +// printAffinityMask(allProcessors); + bInitialized = true; + } + cpu_set_t mask; + if (bIsMainThread) { + CPU_ZERO(&mask); + CPU_SET(0, &mask); +// cerr << "Main Thread: "; + } else { + mask = allProcessors; + if (CPU_COUNT(&mask) > 1) { + CPU_CLR(0, &mask); + } +// cerr << "Aux Thread: "; + } +// printAffinityMask(mask); + int rc = sched_setaffinity(0, sizeof(mask), &mask); + AVG_ASSERT(rc == 0); +#elif defined _WIN32 + DWORD processAffinityMask; + DWORD systemAffinityMask; + BOOL rc = GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, + &systemAffinityMask); + AVG_ASSERT(rc == TRUE); + DWORD mainThreadMask = 1 << getLowestBitSet(processAffinityMask); + DWORD mask; + if (bIsMainThread) { + mask = mainThreadMask; + } else { + mask = processAffinityMask & ~mainThreadMask; + if (mask == 0) { + mask = processAffinityMask; + } + } + DWORD_PTR pPrevMask = SetThreadAffinityMask(GetCurrentThread(), mask); + AVG_ASSERT_MSG(pPrevMask != 0, getWinErrMsg(GetLastError()).c_str()); +#endif +} + +unsigned getLowestBitSet(unsigned val) +{ + AVG_ASSERT(val != 0); // Doh + + unsigned pos = 0; + while (!(val & 1)) { + val >>= 1; + ++pos; + } + return pos; +} + +} |