// Destroy the semaphore. inline ~semaphore_t () { int rc = pthread_mutex_unlock (&mutex); posix_assert (rc); rc = pthread_mutex_destroy (&mutex); posix_assert (rc); }
void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_) { #if defined _POSIX_THREAD_PRIORITY_SCHEDULING && _POSIX_THREAD_PRIORITY_SCHEDULING >= 0 int policy = 0; struct sched_param param; #if _POSIX_THREAD_PRIORITY_SCHEDULING == 0 && defined _SC_THREAD_PRIORITY_SCHEDULING if (sysconf(_SC_THREAD_PRIORITY_SCHEDULING) < 0) { return; } #endif int rc = pthread_getschedparam(descriptor, &policy, ¶m); posix_assert (rc); if(priority_ != -1) { param.sched_priority = priority_; } if(schedulingPolicy_ != -1) { policy = schedulingPolicy_; } #ifdef __NetBSD__ if(policy == SCHED_OTHER) param.sched_priority = -1; #endif rc = pthread_setschedparam(descriptor, policy, ¶m); posix_assert (rc); #endif }
// Initialise the semaphore. inline semaphore_t () { int rc = pthread_mutex_init (&mutex, NULL); posix_assert (rc); rc = pthread_mutex_lock (&mutex); posix_assert (rc); }
inline ~mutex_t () { int rc = pthread_mutex_destroy (&mutex); posix_assert (rc); rc = pthread_mutexattr_destroy (&attr); posix_assert (rc); }
inline mutex_t () { int rc = pthread_mutexattr_init(&attr); posix_assert (rc); rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); posix_assert (rc); rc = pthread_mutex_init (&mutex, &attr); posix_assert (rc); }
void xs::thread_start (xs::thread_t *self_, thread_fn *tfn_, void *arg_) { self_->tfn = tfn_; self_->arg =arg_; int rc = pthread_create (&self_->handle, NULL, thread_routine, self_); posix_assert (rc); }
inline int wait (mutex_t* mutex_, int timeout_) { int rc; if (timeout_ != -1) { struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); timeout.tv_sec += timeout_ / 1000; timeout.tv_nsec += (timeout_ % 1000) * 1000000; if (timeout.tv_nsec > 1E9) { timeout.tv_sec++; timeout.tv_nsec -= 1E9; } rc = pthread_cond_timedwait (&cond, mutex_->get_mutex (), &timeout); } else rc = pthread_cond_wait(&cond, mutex_->get_mutex()); if (rc == 0) return 0; if (rc == ETIMEDOUT){ errno= EAGAIN; return -1; } posix_assert (rc); return -1; }
void zmq::thread_t::start (thread_fn *tfn_, void *arg_) { tfn = tfn_; arg = arg_; int rc = pthread_create (&descriptor, NULL, thread_routine, this); posix_assert (rc); }
void zmq::thread_t::stop () { if (started) { int rc = pthread_join (descriptor, NULL); posix_assert (rc); } }
inline bool try_lock () { int rc = pthread_mutex_trylock (&mutex); if (rc == EBUSY) return false; posix_assert (rc); return true; }
void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_) { #if defined _POSIX_THREAD_PRIORITY_SCHEDULING && _POSIX_THREAD_PRIORITY_SCHEDULING >= 0 int policy = 0; struct sched_param param; #if _POSIX_THREAD_PRIORITY_SCHEDULING == 0 && defined _SC_THREAD_PRIORITY_SCHEDULING if (sysconf(_SC_THREAD_PRIORITY_SCHEDULING) < 0) { return; } #endif int rc = pthread_getschedparam(descriptor, &policy, ¶m); posix_assert (rc); if(priority_ != -1) { param.sched_priority = priority_; } if(schedulingPolicy_ != -1) { policy = schedulingPolicy_; } #ifdef __NetBSD__ if(policy == SCHED_OTHER) param.sched_priority = -1; #endif rc = pthread_setschedparam(descriptor, policy, ¶m); #if defined(__FreeBSD_kernel__) || defined (__FreeBSD__) // If this feature is unavailable at run-time, don't abort. if(rc == ENOSYS) return; #endif posix_assert (rc); #else LIBZMQ_UNUSED (priority_); LIBZMQ_UNUSED (schedulingPolicy_); #endif }
void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_) { #if !defined ZMQ_HAVE_ZOS int policy = 0; struct sched_param param; int rc = pthread_getschedparam(descriptor, &policy, ¶m); posix_assert (rc); if(priority_ != -1) { param.sched_priority = priority_; } if(schedulingPolicy_ != -1) { policy = schedulingPolicy_; } rc = pthread_setschedparam(descriptor, policy, ¶m); posix_assert (rc); #endif }
static void *thread_routine(void *arg_) { #if !defined ZMQ_HAVE_OPENVMS && !defined ZMQ_HAVE_ANDROID // Following code will guarantee more predictable latencies as it'll // disallow any signal handling in the I/O thread. sigset_t signal_set; int rc = sigfillset (&signal_set); errno_assert (rc == 0); rc = pthread_sigmask(SIG_BLOCK, &signal_set, NULL); posix_assert (rc); #endif zmq::thread_t *self = (zmq::thread_t *) arg_; self->tfn(self->arg); return NULL; }
inline int wait (mutex_t *mutex_, int timeout_) { int rc; if (timeout_ != -1) { struct timespec timeout; #if defined ZMQ_HAVE_OSX \ && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200 // less than macOS 10.12 alt_clock_gettime (SYSTEM_CLOCK, &timeout); #else clock_gettime (CLOCK_MONOTONIC, &timeout); #endif timeout.tv_sec += timeout_ / 1000; timeout.tv_nsec += (timeout_ % 1000) * 1000000; if (timeout.tv_nsec > 1000000000) { timeout.tv_sec++; timeout.tv_nsec -= 1000000000; } rc = pthread_cond_timedwait (&cond, mutex_->get_mutex (), &timeout); } else rc = pthread_cond_wait (&cond, mutex_->get_mutex ()); if (rc == 0) return 0; if (rc == ETIMEDOUT) { errno = EAGAIN; return -1; } posix_assert (rc); return -1; }
inline void unlock () { int rc = pthread_mutex_unlock (&mutex); if (rc) posix_assert (rc); }
inline ~mutex_t () { int rc = pthread_mutex_destroy (&mutex); if (rc) posix_assert (rc); }
inline mutex_t () { int rc = pthread_mutex_init (&mutex, NULL); if (rc) posix_assert (rc); }
void zmq::thread_t:: applySchedulingParameters () // to be called in secondary thread context { #if defined _POSIX_THREAD_PRIORITY_SCHEDULING \ && _POSIX_THREAD_PRIORITY_SCHEDULING >= 0 int policy = 0; struct sched_param param; #if _POSIX_THREAD_PRIORITY_SCHEDULING == 0 \ && defined _SC_THREAD_PRIORITY_SCHEDULING if (sysconf (_SC_THREAD_PRIORITY_SCHEDULING) < 0) { return; } #endif int rc = pthread_getschedparam (descriptor, &policy, ¶m); posix_assert (rc); if (thread_sched_policy != ZMQ_THREAD_SCHED_POLICY_DFLT) { policy = thread_sched_policy; } /* Quoting docs: "Linux allows the static priority range 1 to 99 for the SCHED_FIFO and SCHED_RR policies, and the priority 0 for the remaining policies." Other policies may use the "nice value" in place of the priority: */ bool use_nice_instead_priority = (policy != SCHED_FIFO) && (policy != SCHED_RR); if (thread_priority != ZMQ_THREAD_PRIORITY_DFLT) { if (use_nice_instead_priority) param.sched_priority = 0; // this is the only supported priority for most scheduling policies else param.sched_priority = thread_priority; // user should provide a value between 1 and 99 } #ifdef __NetBSD__ if (policy == SCHED_OTHER) param.sched_priority = -1; #endif rc = pthread_setschedparam (descriptor, policy, ¶m); #if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) // If this feature is unavailable at run-time, don't abort. if (rc == ENOSYS) return; #endif posix_assert (rc); #if !defined ZMQ_HAVE_VXWORKS if (use_nice_instead_priority && thread_priority != ZMQ_THREAD_PRIORITY_DFLT) { // assume the user wants to decrease the thread's nice value // i.e., increase the chance of this thread being scheduled: try setting that to // maximum priority. rc = nice (-20); errno_assert (rc != -1); // IMPORTANT: EPERM is typically returned for unprivileged processes: that's because // CAP_SYS_NICE capability is required or RLIMIT_NICE resource limit should be changed to avoid EPERM! } #endif #ifdef ZMQ_HAVE_PTHREAD_SET_AFFINITY if (!thread_affinity_cpus.empty ()) { cpu_set_t cpuset; CPU_ZERO (&cpuset); for (std::set<int>::const_iterator it = thread_affinity_cpus.begin (); it != thread_affinity_cpus.end (); it++) { CPU_SET ((int) (*it), &cpuset); } rc = pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset); posix_assert (rc); } #endif #endif }
inline void lock () { int rc = pthread_mutex_lock (&mutex); posix_assert (rc); }
void xs::thread_stop (xs::thread_t *self_) { int rc = pthread_join (self_->handle, NULL); posix_assert (rc); }
inline void broadcast () { int rc = pthread_cond_broadcast (&cond); posix_assert (rc); }
inline ~condition_variable_t () { int rc = pthread_cond_destroy (&cond); posix_assert (rc); }
inline condition_variable_t () { int rc = pthread_cond_init (&cond, NULL); posix_assert (rc); }
// Post the semaphore. inline void post () { int rc = pthread_mutex_unlock (&mutex); posix_assert (rc); }