#ifndef BOOST_THREAD_DETAIL_PTHREAD_HPP #define BOOST_THREAD_DETAIL_PTHREAD_HPP #include #include #include #include //for is_same #include #include #include #include #include /* the way to have thread object 1) contention scope: (static) system_scope process_scope 2) detach_state: (dynamic) detached joinable 3) scheduling policy: (dynamic) time_sharing fifo round_robin inherited */ namespace boost { typedef pthread_t thread_type; //contention scope struct system_scope { enum {type=0}; }; //THR_BOUND for solaris thread struct process_scope { enum {type=0}; }; struct nonportable_scope { enum {type=0}; }; //detach state struct detached { enum {type=1}; }; struct joinable { enum {type=1}; }; //scheduling policies struct time_sharing { enum {type=2}; }; template //Priority is [0-100], relative, struct fifo { enum {priority=Priority, type=2}; }; template struct round_robin { enum {priority=Priority, type=2}; }; struct inherited { enum {type=2}; }; namespace detail { template struct thread_attr_init { template void operator()(T&) const {} }; struct thread_attr_init { template void operator()(T& attr) const { pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); } }; struct thread_attr_init { template void operator()(T& attr) const { //if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS) == ENOTSUP) pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); } }; struct thread_attr_init { template void operator()(T& attr) const { pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); } }; struct thread_attr_init { template void operator()(T& attr) const { pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); } }; struct thread_attr_init { template void operator()(T& attr) const { pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); } }; struct thread_attr_init { template void operator()(T& attr) const { pthread_attr_setschedpolicy(&attr, SCHED_OTHER); } }; template struct thread_attr_init > { template void operator()(T& attr) const { int ret; BOOST_STATIC_ASSERT(Priority>=0); BOOST_STATIC_ASSERT(Priority<=100); ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); if ( ret ) perror("pthread_attr_setchedpolicy"); assert(!ret); int p_max = sched_get_priority_max(SCHED_FIFO); int p_min = sched_get_priority_min(SCHED_FIFO); assert(p_max != -1 && p_min != -1); sched_param my_thread_param; my_thread_param.sched_priority = int(Priority/100.0*(p_max-p_min)) + p_min; ret = pthread_attr_setschedparam(&attr, &my_thread_param); if ( ret ) perror("pthread_attr_setchedparam"); assert(!ret); } }; template struct thread_attr_init > { template void operator()(T& attr) const { int ret; BOOST_STATIC_ASSERT(Priority>=0); BOOST_STATIC_ASSERT(Priority<=100); ret = pthread_attr_setschedpolicy(&attr, SCHED_RR); if ( ret ) perror("pthread_attr_setchedpolicy"); assert(!ret); int p_max = sched_get_priority_max(SCHED_RR); int p_min = sched_get_priority_min(SCHED_RR); assert(p_max != -1 && p_min != -1); sched_param my_thread_param; my_thread_param.sched_priority = int(Priority/100.0*(p_max-p_min)) + p_min; ret = pthread_attr_setschedparam(&attr, &my_thread_param); if ( ret ) perror("pthread_attr_setchedparam"); assert(!ret); } }; template struct thread_attributes { thread_attributes() { pthread_attr_init(&attr); detail::thread_attr_init()(attr); detail::thread_attr_init()(attr); detail::thread_attr_init()(attr); } pthread_attr_t& attribute() { return attr; } ~thread_attributes() { pthread_attr_destroy(&attr); } pthread_attr_t attr; }; } //namespace detail struct default_template_arg { enum {type=10000}; }; template struct dispatch_features { typedef typename ct_if < (F1::type==0), F1, typename ct_if < (F2::type==0), F2, typename ct_if < (F3::type==0), F3, default_template_arg >::type >::type >::type first; typedef typename ct_if < (F1::type==1), F1, typename ct_if < (F2::type==1), F2, typename ct_if < (F3::type==1), F3, default_template_arg >::type >::type >::type second; typedef typename ct_if < (F1::type==2), F1, typename ct_if < (F2::type==2), F2, typename ct_if < (F3::type==2), F3, default_template_arg >::type >::type >::type third; }; template void* thread_fun(void* o) { Obj* O = static_cast(o); (*O)(); return 0; } template class thread { //template typedef typename dispatch_features::first first_arg; //set default_template_arg if needed typedef typename ct_if::value, system_scope, first_arg>::type ContentionScope; typedef typename dispatch_features::second second_arg; //set default_template_arg if needed typedef typename ct_if::value, joinable, second_arg>::type DetachState; typedef typename dispatch_features::third third_arg; //set default_template_arg if needed typedef typename ct_if::value, time_sharing, third_arg>::type SchedPolicy; //disable illegal combination BOOST_STATIC_ASSERT( ContentionScope::type == 0 ); BOOST_STATIC_ASSERT( DetachState::type == 1 ); BOOST_STATIC_ASSERT( SchedPolicy::type == 2 ); public: thread() : is_detached(true), o(NULL) { } thread(Obj* o_) : is_detached(true), o(o_) { } void run() { set_is_detached(DetachState()); detail::thread_attributes a; typedef void* (*F)(void *); int ret = pthread_create(&tid, &a.attribute(), F(thread_fun), (void*)o); //(void*)(const_cast( o.get() ) ) ); if ( ret ) perror("pthread_create"); assert(!ret); } void join() { if ( !is_detached ) pthread_join(tid, NULL); is_detached = false; } void detach() { if ( !is_detached ) pthread_detach(tid); is_detached = true; } ~thread() { join(); } protected: void set_is_detached(detached) { is_detached=true; } void set_is_detached(joinable) { is_detached=false; } bool is_detached; pthread_t tid; //shared_ptr o; Obj* o; }; } //namespace boost #endif //BOOST_THREAD_DETAIL_PTHREAD_HPP