488 |
|
#if defined(HAVE_PTHREADS) |
489 |
|
|
490 |
|
// POSIX threads available, start 60Hz thread |
491 |
< |
pthread_attr_init(&tick_thread_attr); |
492 |
< |
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) |
493 |
< |
if (geteuid() == 0) { |
494 |
< |
pthread_attr_setinheritsched(&tick_thread_attr, PTHREAD_EXPLICIT_SCHED); |
495 |
< |
pthread_attr_setschedpolicy(&tick_thread_attr, SCHED_FIFO); |
496 |
< |
struct sched_param fifo_param; |
497 |
< |
fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2; |
498 |
< |
pthread_attr_setschedparam(&tick_thread_attr, &fifo_param); |
499 |
< |
} |
500 |
< |
#endif |
491 |
> |
Set_pthread_attr(&tick_thread_attr, 0); |
492 |
|
tick_thread_active = (pthread_create(&tick_thread, &tick_thread_attr, tick_func, NULL) == 0); |
493 |
|
if (!tick_thread_active) { |
494 |
|
sprintf(str, GetString(STR_TICK_THREAD_ERR), strerror(errno)); |
683 |
|
#endif |
684 |
|
|
685 |
|
|
686 |
+ |
#ifdef HAVE_PTHREADS |
687 |
+ |
/* |
688 |
+ |
* Pthread configuration |
689 |
+ |
*/ |
690 |
+ |
void |
691 |
+ |
Set_pthread_attr(pthread_attr_t *attr, int priority) |
692 |
+ |
{ |
693 |
+ |
pthread_attr_init(attr); |
694 |
+ |
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) |
695 |
+ |
// Some of these only work for superuser |
696 |
+ |
if (geteuid() == 0) { |
697 |
+ |
pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); |
698 |
+ |
pthread_attr_setschedpolicy(attr, SCHED_FIFO); |
699 |
+ |
struct sched_param fifo_param; |
700 |
+ |
fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) + |
701 |
+ |
sched_get_priority_max(SCHED_FIFO)) / 2 + |
702 |
+ |
priority); |
703 |
+ |
pthread_attr_setschedparam(attr, &fifo_param); |
704 |
+ |
} |
705 |
+ |
if (pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM) != 0) { |
706 |
+ |
#ifdef PTHREAD_SCOPE_BOUND_NP |
707 |
+ |
// If system scope is not available (eg. we're not running |
708 |
+ |
// with CAP_SCHED_MGT capability on an SGI box), try bound |
709 |
+ |
// scope. It exposes pthread scheduling to the kernel, |
710 |
+ |
// without setting realtime priority. |
711 |
+ |
pthread_attr_setscope(attr, PTHREAD_SCOPE_BOUND_NP); |
712 |
+ |
#endif |
713 |
+ |
} |
714 |
+ |
#endif |
715 |
+ |
} |
716 |
+ |
#endif // HAVE_PTHREADS |
717 |
+ |
|
718 |
+ |
|
719 |
|
/* |
720 |
|
* Mutexes |
721 |
|
*/ |
723 |
|
#ifdef HAVE_PTHREADS |
724 |
|
|
725 |
|
struct B2_mutex { |
726 |
< |
B2_mutex() { pthread_mutex_init(&m, NULL); } |
726 |
> |
B2_mutex() { |
727 |
> |
pthread_mutexattr_t attr; |
728 |
> |
pthread_mutexattr_init(&attr); |
729 |
> |
// Initialize the mutex for priority inheritance -- |
730 |
> |
// required for accurate timing. |
731 |
> |
#ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL |
732 |
> |
pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); |
733 |
> |
#endif |
734 |
> |
#if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL) |
735 |
> |
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); |
736 |
> |
#endif |
737 |
> |
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); |
738 |
> |
pthread_mutex_init(&m, &attr); |
739 |
> |
pthread_mutexattr_destroy(&attr); |
740 |
> |
} |
741 |
|
~B2_mutex() { pthread_mutex_unlock(&m); pthread_mutex_destroy(&m); } |
742 |
|
pthread_mutex_t m; |
743 |
|
}; |