~async_message_loop() { if(thread.get_id() != std::thread::id()){ DWORD id = ::GetThreadId(thread.native_handle()); ::PostThreadMessageW(id, WM_QUIT, 0, 0); thread.join(); } }
explicit TimerObjectReactor(DataObjectReactor& dor) : _epfd(-1), _evtfd(-1), _dor(dor) { #ifdef __linux__ if ((_evtfd = ::eventfd(0, EFD_CLOEXEC)) < 0) { Logger::pLOG->error("Eventfd file handle could not be created in TOR: {}", std::strerror(errno)); return; } if ((_epfd = ::epoll_create1(EPOLL_CLOEXEC)) < 0) { Logger::pLOG->error("Epoll file handle could not be created in TOR: {}", std::strerror(errno)); close(_evtfd); return; } // Add it first to stop epoll_wait in case of destruction epoll_event evt {}; evt.events = EPOLLIN; evt.data.fd = _evtfd; if (::epoll_ctl(_epfd, EPOLL_CTL_ADD, _evtfd, &evt) < 0) { Logger::pLOG->error("Epoll control error at ADD stop event in TOR: {}", std::strerror(errno)); close(_epfd); close(_evtfd); return; } _thrd = std::thread([this](){ TimerObjectReactor::run(); }); //The thread name is a meaningful C language string, whose length is //restricted to 16 characters, including the terminating null byte ('\0') std::string s = "TOR-THRD-0"; Logger::pLOG->info("Created {}", s); if (pthread_setname_np(_thrd.native_handle(), s.data())) Logger::pLOG->warn("Could not set name for {}", s); struct sched_param param {}; param.sched_priority = RT_PRIO; if (pthread_setschedparam(_thrd.native_handle(), SCHED_FIFO, ¶m)) Logger::pLOG->warn("Could not set realtime parameter for {}", s); #endif }
int stop() { Logger logdev = Logger::getInstance(LOGDEVICE); if (running) { running = false; // Native pthread_cancel due blocking read that consume less cpu then timed select pthread_cancel(key_thread.native_handle()); key_thread.join(); close(fd); fd = -1; } LOG4CPLUS_DEBUG(logdev, "key reader stopped"); return (0); }
static inline void set_affinity(std::thread &t, int n) { if(t.get_id() == std::thread::id()) throw std::runtime_error("thread not running"); cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(n, &cpuset); auto pth = t.native_handle(); if ( ::pthread_setaffinity_np(pth, sizeof(cpuset), &cpuset) != 0) throw std::runtime_error("pthread_setaffinity_np"); }
void RequestQueueImplWorker::StopThread( std::thread& t, common::SharedState<ThreadState>& s, common::Semaphore& sem) { assert(s() == RUNNING); s.set_to(TERMINATING); sem.signal(); #if THRILL_MSVC >= 1700 // In the Visual C++ Runtime 2012 and 2013, there is a deadlock bug, which // occurs when threads are joined after main() exits. Apparently, Microsoft // thinks this is not a big issue. It has not been fixed in VC++RT 2013. // https://connect.microsoft.com/VisualStudio/feedback/details/747145 // // All threads are created by singletons, which are global variables that // are deleted after main() exits. The fix applied here it to use // std::thread::native_handle() and access the WINAPI to terminate the // thread directly (after it finished handling its i/o requests). WaitForSingleObject(t->native_handle(), INFINITE); CloseHandle(t->native_handle()); #else t.join(); #endif assert(s() == TERMINATED); s.set_to(NOT_RUNNING); }
void SetCpuAffinity(std::thread& thread, size_t cpu_id) { #if __linux__ && !THRILL_ON_TRAVIS cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(cpu_id % std::thread::hardware_concurrency(), &cpuset); int rc = pthread_setaffinity_np( thread.native_handle(), sizeof(cpu_set_t), &cpuset); if (rc != 0) { LOG1 << "Error calling pthread_setaffinity_np(): " << rc << ": " << strerror(errno); } #else tlx::unused(thread); tlx::unused(cpu_id); #endif }
bool Core::bind(std::thread& thread) { auto cpuset = hwloc_bitmap_dup(core_->cpuset); hwloc_bitmap_singlify(cpuset); if (hwloc_set_thread_cpubind(topology_, thread.native_handle(), cpuset, 0)) { auto error = errno; LOG(thread_logger, warning) << "Error setting thread affinity: " << strerror(error); hwloc_bitmap_free(cpuset); return false; } hwloc_bitmap_free(cpuset); return true; }
void setThreadBackground(std::thread& t, Background background) { int m = background ? THREAD_MODE_BACKGROUND_BEGIN : THREAD_MODE_BACKGROUND_END; std::thread::native_handle_type h = t.native_handle(); SetThreadPriority(h, m); }
void setPriority(std::thread& t, ThreadPriorityClass priorityClass, ThreadPriorityLevel priorityLevel) { #ifdef WIN32 std::thread::native_handle_type h = t.native_handle(); SetPriorityClass(h, convertThreadPriorityClass(priorityClass)); SetThreadPriority(h, convertThreadPriorityLevel(priorityClass, priorityLevel)); #else int policy; struct sched_param param; int res = pthread_getschedparam(t.native_handle(), &policy, ¶m); if (res != 0) { throw ghoul::RuntimeError( "Error accessing scheduling parameters with error " + std::to_string(res), "Thread" ); } param.sched_priority = convertThreadPriorityLevel(priorityClass, priorityLevel); res = pthread_setschedparam( t.native_handle(), policy, ¶m ); if (res != 0) { throw ghoul::RuntimeError( "Error setting scheduling parameters with error " + std::to_string(res), "Thread" ); } #endif }