2015-04-07 03:13:12 -07:00
|
|
|
/*
|
|
|
|
This file is a part of the JThread package, which contains some object-
|
|
|
|
oriented thread wrappers for different thread implementations.
|
|
|
|
|
|
|
|
Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com)
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
copy of this software and associated documentation files (the "Software"),
|
|
|
|
to deal in the Software without restriction, including without limitation
|
|
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "threading/thread.h"
|
|
|
|
#include "threading/mutex_auto_lock.h"
|
|
|
|
#include "log.h"
|
2015-10-16 20:43:29 -07:00
|
|
|
#include "porting.h"
|
2015-04-07 03:13:12 -07:00
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
#define UNUSED(expr) do { (void)(expr); } while (0)
|
|
|
|
|
|
|
|
#if USE_CPP11_THREADS
|
2015-04-07 03:13:12 -07:00
|
|
|
#include <chrono>
|
2015-10-16 20:43:29 -07:00
|
|
|
#include <system_error>
|
|
|
|
#elif USE_WIN_THREADS
|
|
|
|
#ifndef _WIN32_WCE
|
|
|
|
#include <process.h>
|
|
|
|
#endif
|
|
|
|
#elif USE_POSIX_THREADS
|
|
|
|
#include <time.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
2015-04-07 03:13:12 -07:00
|
|
|
#include <sys/time.h>
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
#if defined(__FreeBSD__) || defined(__APPLE__)
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#elif defined(_GNU_SOURCE)
|
|
|
|
#include <sys/sysinfo.h>
|
|
|
|
#endif
|
2015-04-07 03:13:12 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
// for setName
|
2016-07-04 12:00:57 -07:00
|
|
|
#if defined(__linux__)
|
2015-04-07 03:13:12 -07:00
|
|
|
#include <sys/prctl.h>
|
|
|
|
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
|
|
|
|
#include <pthread_np.h>
|
|
|
|
#elif defined(_MSC_VER)
|
|
|
|
struct THREADNAME_INFO {
|
2015-10-16 20:43:29 -07:00
|
|
|
DWORD dwType; // Must be 0x1000
|
|
|
|
LPCSTR szName; // Pointer to name (in user addr space)
|
2015-04-07 03:13:12 -07:00
|
|
|
DWORD dwThreadID; // Thread ID (-1=caller thread)
|
2015-10-16 20:43:29 -07:00
|
|
|
DWORD dwFlags; // Reserved for future use, must be zero
|
2015-04-07 03:13:12 -07:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
// for bindToProcessor
|
2015-04-07 03:13:12 -07:00
|
|
|
#if __FreeBSD_version >= 702106
|
|
|
|
typedef cpuset_t cpu_set_t;
|
2016-07-04 12:00:57 -07:00
|
|
|
#elif defined(__linux__)
|
2015-04-07 03:13:12 -07:00
|
|
|
#include <sched.h>
|
|
|
|
#elif defined(__sun) || defined(sun)
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/processor.h>
|
|
|
|
#include <sys/procset.h>
|
|
|
|
#elif defined(_AIX)
|
|
|
|
#include <sys/processor.h>
|
2015-10-16 20:43:29 -07:00
|
|
|
#include <sys/thread.h>
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(__APPLE__)
|
|
|
|
#include <mach/mach_init.h>
|
2015-08-27 11:51:07 -07:00
|
|
|
#include <mach/thread_act.h>
|
2015-04-07 03:13:12 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
Thread::Thread(const std::string &name) :
|
2015-10-16 20:43:29 -07:00
|
|
|
m_name(name),
|
|
|
|
m_retval(NULL),
|
2015-10-17 19:42:48 -07:00
|
|
|
m_joinable(false),
|
2015-10-16 20:43:29 -07:00
|
|
|
m_request_stop(false),
|
|
|
|
m_running(false)
|
|
|
|
{
|
|
|
|
#ifdef _AIX
|
|
|
|
m_kernel_thread_id = -1;
|
2015-04-07 03:13:12 -07:00
|
|
|
#endif
|
2015-10-16 20:43:29 -07:00
|
|
|
}
|
2015-04-07 03:13:12 -07:00
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
Thread::~Thread()
|
2015-04-07 03:13:12 -07:00
|
|
|
{
|
2015-10-16 20:43:29 -07:00
|
|
|
kill();
|
2015-04-07 03:13:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Thread::start()
|
|
|
|
{
|
2015-10-17 19:42:48 -07:00
|
|
|
MutexAutoLock lock(m_mutex);
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
if (m_running)
|
2015-04-07 03:13:12 -07:00
|
|
|
return false;
|
|
|
|
|
2015-10-17 19:42:48 -07:00
|
|
|
m_request_stop = false;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
#if USE_CPP11_THREADS
|
|
|
|
|
|
|
|
try {
|
2016-03-07 13:55:32 -08:00
|
|
|
m_thread_obj = new std::thread(threadProc, this);
|
2015-10-30 23:38:23 -07:00
|
|
|
} catch (const std::system_error &e) {
|
2015-04-07 03:13:12 -07:00
|
|
|
return false;
|
2015-10-16 20:43:29 -07:00
|
|
|
}
|
2015-04-07 03:13:12 -07:00
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
#elif USE_WIN_THREADS
|
2015-04-07 03:13:12 -07:00
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
m_thread_handle = CreateThread(NULL, 0, threadProc, this, 0, &m_thread_id);
|
|
|
|
if (!m_thread_handle)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
#elif USE_POSIX_THREADS
|
2015-04-07 03:13:12 -07:00
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
int status = pthread_create(&m_thread_handle, NULL, threadProc, this);
|
2015-04-07 03:13:12 -07:00
|
|
|
if (status)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
#endif
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
while (!m_running)
|
|
|
|
sleep_ms(1);
|
|
|
|
|
2015-10-17 19:42:48 -07:00
|
|
|
m_joinable = true;
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Thread::stop()
|
|
|
|
{
|
|
|
|
m_request_stop = true;
|
2015-04-07 03:13:12 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-17 19:42:48 -07:00
|
|
|
bool Thread::wait()
|
2015-10-16 20:43:29 -07:00
|
|
|
{
|
2015-10-17 19:42:48 -07:00
|
|
|
MutexAutoLock lock(m_mutex);
|
|
|
|
|
|
|
|
if (!m_joinable)
|
|
|
|
return false;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
#if USE_CPP11_THREADS
|
|
|
|
|
|
|
|
m_thread_obj->join();
|
|
|
|
|
2015-10-17 19:42:48 -07:00
|
|
|
delete m_thread_obj;
|
|
|
|
m_thread_obj = NULL;
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
#elif USE_WIN_THREADS
|
|
|
|
|
2015-10-17 03:23:07 -07:00
|
|
|
int ret = WaitForSingleObject(m_thread_handle, INFINITE);
|
2015-10-16 20:43:29 -07:00
|
|
|
assert(ret == WAIT_OBJECT_0);
|
|
|
|
UNUSED(ret);
|
|
|
|
|
2015-10-17 19:42:48 -07:00
|
|
|
CloseHandle(m_thread_handle);
|
|
|
|
m_thread_handle = NULL;
|
|
|
|
m_thread_id = -1;
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
#elif USE_POSIX_THREADS
|
|
|
|
|
|
|
|
int ret = pthread_join(m_thread_handle, NULL);
|
|
|
|
assert(ret == 0);
|
|
|
|
UNUSED(ret);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
assert(m_running == false);
|
2015-10-17 19:42:48 -07:00
|
|
|
m_joinable = false;
|
|
|
|
return true;
|
2015-10-16 20:43:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
bool Thread::kill()
|
|
|
|
{
|
2015-10-16 20:43:29 -07:00
|
|
|
if (!m_running) {
|
2015-04-07 03:13:12 -07:00
|
|
|
wait();
|
|
|
|
return false;
|
|
|
|
}
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-10-17 19:42:48 -07:00
|
|
|
m_running = false;
|
|
|
|
|
2016-10-06 12:13:04 -07:00
|
|
|
#if USE_WIN_THREADS
|
2015-10-16 20:43:29 -07:00
|
|
|
TerminateThread(m_thread_handle, 0);
|
2015-10-17 19:42:48 -07:00
|
|
|
CloseHandle(m_thread_handle);
|
2015-10-16 20:43:29 -07:00
|
|
|
#else
|
|
|
|
// We need to pthread_kill instead on Android since NDKv5's pthread
|
|
|
|
// implementation is incomplete.
|
2015-04-07 03:13:12 -07:00
|
|
|
# ifdef __ANDROID__
|
2016-04-30 06:44:28 -07:00
|
|
|
pthread_kill(getThreadHandle(), SIGKILL);
|
2015-04-07 03:13:12 -07:00
|
|
|
# else
|
2016-04-30 06:44:28 -07:00
|
|
|
pthread_cancel(getThreadHandle());
|
2015-04-07 03:13:12 -07:00
|
|
|
# endif
|
|
|
|
wait();
|
|
|
|
#endif
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
m_retval = NULL;
|
2015-10-17 19:42:48 -07:00
|
|
|
m_joinable = false;
|
2015-10-16 20:43:29 -07:00
|
|
|
m_request_stop = false;
|
2015-10-17 19:42:48 -07:00
|
|
|
|
|
|
|
return true;
|
2015-04-07 03:13:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
bool Thread::getReturnValue(void **ret)
|
|
|
|
{
|
|
|
|
if (m_running)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
*ret = m_retval;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if USE_CPP11_THREADS || USE_POSIX_THREADS
|
2015-10-17 19:42:48 -07:00
|
|
|
void *Thread::threadProc(void *param)
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(_WIN32_WCE)
|
2015-10-17 19:42:48 -07:00
|
|
|
DWORD Thread::threadProc(LPVOID param)
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(_WIN32)
|
2015-10-17 19:42:48 -07:00
|
|
|
DWORD WINAPI Thread::threadProc(LPVOID param)
|
2015-04-07 03:13:12 -07:00
|
|
|
#endif
|
|
|
|
{
|
2015-10-16 20:43:29 -07:00
|
|
|
Thread *thr = (Thread *)param;
|
|
|
|
|
|
|
|
#ifdef _AIX
|
|
|
|
m_kernel_thread_id = thread_self();
|
2015-04-07 03:13:12 -07:00
|
|
|
#endif
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
thr->setName(thr->m_name);
|
|
|
|
|
|
|
|
g_logger.registerThread(thr->m_name);
|
|
|
|
thr->m_running = true;
|
2015-04-07 03:13:12 -07:00
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
thr->m_retval = thr->run();
|
2015-04-07 03:13:12 -07:00
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
thr->m_running = false;
|
2015-10-13 00:57:44 -07:00
|
|
|
g_logger.deregisterThread();
|
2015-04-07 03:13:12 -07:00
|
|
|
|
2015-11-08 13:19:34 -08:00
|
|
|
// 0 is returned here to avoid an unnecessary ifdef clause
|
|
|
|
return 0;
|
2015-04-07 03:13:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Thread::setName(const std::string &name)
|
|
|
|
{
|
2016-07-04 12:00:57 -07:00
|
|
|
#if defined(__linux__)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
// It would be cleaner to do this with pthread_setname_np,
|
|
|
|
// which was added to glibc in version 2.12, but some major
|
|
|
|
// distributions are still runing 2.11 and previous versions.
|
2015-04-07 03:13:12 -07:00
|
|
|
prctl(PR_SET_NAME, name.c_str());
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
pthread_set_name_np(pthread_self(), name.c_str());
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(__NetBSD__)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
pthread_setname_np(pthread_self(), name.c_str());
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(__APPLE__)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
pthread_setname_np(name.c_str());
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(_MSC_VER)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
// Windows itself doesn't support thread names,
|
|
|
|
// but the MSVC debugger does...
|
|
|
|
THREADNAME_INFO info;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
info.dwType = 0x1000;
|
|
|
|
info.szName = name.c_str();
|
|
|
|
info.dwThreadID = -1;
|
|
|
|
info.dwFlags = 0;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
__try {
|
2015-10-16 20:43:29 -07:00
|
|
|
RaiseException(0x406D1388, 0,
|
|
|
|
sizeof(info) / sizeof(DWORD), (ULONG_PTR *)&info);
|
2015-04-07 03:13:12 -07:00
|
|
|
} __except (EXCEPTION_CONTINUE_EXECUTION) {
|
|
|
|
}
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(_WIN32) || defined(__GNU__)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
// These platforms are known to not support thread names.
|
|
|
|
// Silently ignore the request.
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#else
|
|
|
|
#warning "Unrecognized platform, thread names will not be available."
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int Thread::getNumberOfProcessors()
|
|
|
|
{
|
2016-10-06 12:13:04 -07:00
|
|
|
#if USE_CPP11_THREADS
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
return std::thread::hardware_concurrency();
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2016-10-06 12:13:04 -07:00
|
|
|
#elif USE_WIN_THREADS
|
|
|
|
|
|
|
|
SYSTEM_INFO sysinfo;
|
|
|
|
GetSystemInfo(&sysinfo);
|
|
|
|
return sysinfo.dwNumberOfProcessors;
|
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(_SC_NPROCESSORS_ONLN)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
return sysconf(_SC_NPROCESSORS_ONLN);
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
#elif defined(__FreeBSD__) || defined(__NetBSD__) || \
|
|
|
|
defined(__DragonFly__) || defined(__APPLE__)
|
|
|
|
|
|
|
|
unsigned int num_cpus = 1;
|
|
|
|
size_t len = sizeof(num_cpus);
|
|
|
|
|
|
|
|
int mib[2];
|
|
|
|
mib[0] = CTL_HW;
|
|
|
|
mib[1] = HW_NCPU;
|
|
|
|
|
|
|
|
sysctl(mib, 2, &num_cpus, &len, NULL, 0);
|
|
|
|
return num_cpus;
|
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(_GNU_SOURCE)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
return get_nprocs();
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(PTW32_VERSION) || defined(__hpux)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
return pthread_num_processors_np();
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#else
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
return 1;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-16 20:43:29 -07:00
|
|
|
bool Thread::bindToProcessor(unsigned int proc_number)
|
2015-04-07 03:13:12 -07:00
|
|
|
{
|
|
|
|
#if defined(__ANDROID__)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
return false;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2016-10-06 12:13:04 -07:00
|
|
|
#elif USE_WIN_THREADS
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2016-04-30 06:44:28 -07:00
|
|
|
return SetThreadAffinityMask(getThreadHandle(), 1 << proc_number);
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2016-07-04 12:00:57 -07:00
|
|
|
#elif __FreeBSD_version >= 702106 || defined(__linux__)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
cpu_set_t cpuset;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
CPU_ZERO(&cpuset);
|
2015-10-16 20:43:29 -07:00
|
|
|
CPU_SET(proc_number, &cpuset);
|
|
|
|
|
2016-04-30 06:44:28 -07:00
|
|
|
return pthread_setaffinity_np(getThreadHandle(), sizeof(cpuset), &cpuset) == 0;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(__sun) || defined(sun)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
return processor_bind(P_LWPID, P_MYID, proc_number, NULL) == 0
|
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(_AIX)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
|
|
|
return bindprocessor(BINDTHREAD, m_kernel_thread_id, proc_number) == 0;
|
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(__hpux) || defined(hpux)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
pthread_spu_t answer;
|
|
|
|
|
|
|
|
return pthread_processor_bind_np(PTHREAD_BIND_ADVISORY_NP,
|
2016-04-30 06:44:28 -07:00
|
|
|
&answer, proc_number, getThreadHandle()) == 0;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#elif defined(__APPLE__)
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
struct thread_affinity_policy tapol;
|
|
|
|
|
2016-04-30 06:44:28 -07:00
|
|
|
thread_port_t threadport = pthread_mach_thread_np(getThreadHandle());
|
2015-10-16 20:43:29 -07:00
|
|
|
tapol.affinity_tag = proc_number + 1;
|
2015-04-07 03:13:12 -07:00
|
|
|
return thread_policy_set(threadport, THREAD_AFFINITY_POLICY,
|
|
|
|
(thread_policy_t)&tapol,
|
|
|
|
THREAD_AFFINITY_POLICY_COUNT) == KERN_SUCCESS;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#else
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
return false;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Thread::setPriority(int prio)
|
|
|
|
{
|
2016-10-06 12:13:04 -07:00
|
|
|
#if USE_WIN_THREADS
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2016-04-30 06:44:28 -07:00
|
|
|
return SetThreadPriority(getThreadHandle(), prio);
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#else
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
struct sched_param sparam;
|
|
|
|
int policy;
|
|
|
|
|
2016-04-30 06:44:28 -07:00
|
|
|
if (pthread_getschedparam(getThreadHandle(), &policy, &sparam) != 0)
|
2015-04-07 03:13:12 -07:00
|
|
|
return false;
|
|
|
|
|
|
|
|
int min = sched_get_priority_min(policy);
|
|
|
|
int max = sched_get_priority_max(policy);
|
|
|
|
|
|
|
|
sparam.sched_priority = min + prio * (max - min) / THREAD_PRIORITY_HIGHEST;
|
2016-04-30 06:44:28 -07:00
|
|
|
return pthread_setschedparam(getThreadHandle(), policy, &sparam) == 0;
|
2015-10-16 20:43:29 -07:00
|
|
|
|
2015-04-07 03:13:12 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|