@q $Id: sthread.cweb 2269 2008-11-23 14:33:22Z michel $ @> @q Copyright 2004, Ondra Kamenik @> @ Start of {\tt sthreads.h} file. We set the default values for |max_parallel_threads| for both |posix| and |empty| implementation and both joinable and detach group. For |posix| this defaults to uniprocessor machine with hyper-threading, this is 2. @c #include #include "sthread.h" #ifdef HAVE_PTHREAD namespace sthread { template<> int thread_group::max_parallel_threads = 2; template<> int detach_thread_group::max_parallel_threads = 2; @; } #else namespace sthread { template<> int thread_group::max_parallel_threads = 1; template<> int detach_thread_group::max_parallel_threads = 1; @; } #endif @ @= @<|thread_traits| method codes@>; @<|mutex_traits| method codes@>; @<|cond_traits| method codes@>; @<|PosixSynchro| constructor@>; @<|posix_thread_function| code@>; @<|posix_detach_thread_function| code@>; @ @<|thread_traits| method codes@>= void* posix_thread_function(void* c); template <> void thread_traits::run(_Ctype* c) { pthread_create(&(c->getThreadIden()), NULL, posix_thread_function, (void*) c); } @# void* posix_detach_thread_function(void* c); template <> void thread_traits::detach_run(_Dtype* c) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&(c->getThreadIden()), &attr, posix_detach_thread_function, (void*) c); pthread_attr_destroy(&attr); } @# template <> void thread_traits::exit() { pthread_exit(NULL); } @# template <> void thread_traits::join(_Ctype* c) { pthread_join(c->getThreadIden(), NULL); } @ @<|mutex_traits| method codes@>= template <> void mutex_traits::init(pthread_mutex_t& m) { pthread_mutex_init(&m, NULL); } @# template <> void mutex_traits::lock(pthread_mutex_t& m) { pthread_mutex_lock(&m); } @# template <> void mutex_traits::unlock(pthread_mutex_t& m) { pthread_mutex_unlock(&m); } @ @<|cond_traits| method codes@>= template <> void cond_traits::init(_Tcond& cond) { pthread_cond_init(&cond, NULL); } @# template <> void cond_traits::broadcast(_Tcond& cond) { pthread_cond_broadcast(&cond); } @# template <> void cond_traits::wait(_Tcond& cond, _Tmutex& mutex) { pthread_cond_wait(&cond, &mutex); } @# template <> void cond_traits::destroy(_Tcond& cond) { pthread_cond_destroy(&cond); } @ Here we instantiate the static map, and construct |PosixSynchro| using that map. @<|PosixSynchro| constructor@>= static posix_synchro::mutex_map_t posix_mm; PosixSynchro::PosixSynchro(const void* c, const char* id) : posix_synchro(c, id, posix_mm) {} @ This function is of the type |void* function(void*)| as required by POSIX, but it typecasts its argument and runs |operator()()|. @<|posix_thread_function| code@>= void* posix_thread_function(void* c) { thread_traits::_Ctype* ct = (thread_traits::_Ctype*)c; try { ct->operator()(); } catch (...) { ct->exit(); } return NULL; } @ @<|posix_detach_thread_function| code@>= void* posix_detach_thread_function(void* c) { thread_traits::_Dtype* ct = (thread_traits::_Dtype*)c; condition_counter* counter = ct->counter; try { ct->operator()(); } catch (...) { ct->exit(); } if (counter) counter->decrease(); return NULL; } @ The only trait methods we need to work are |thread_traits::run| and |thread_traits::detach_run|, which directly call |operator()()|. Anything other is empty. @= template <> void thread_traits::run(_Ctype* c) { c->operator()(); } template <> void thread_traits::detach_run(_Dtype* c) { c->operator()(); } @# template <> void thread_traits::exit() { } @# template <> void thread_traits::join(_Ctype* c) { } @# template <> void mutex_traits::init(Empty& m) { } @# template <> void mutex_traits::lock(Empty& m) { } @# template <> void mutex_traits::unlock(Empty& m) { } @# template <> void cond_traits::init(_Tcond& cond) { } @# template <> void cond_traits::broadcast(_Tcond& cond) { } @# template <> void cond_traits::wait(_Tcond& cond, _Tmutex& mutex) { } @# template <> void cond_traits::destroy(_Tcond& cond) { } @ End of {\tt sthreads.h} file.