1 // SGThread - Simple pthread class wrappers.
3 // Written by Bernie Bright, started April 2001.
5 // Copyright (C) 2001 Bernard Bright - bbright@bigpond.net.au
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #ifndef SGTHREAD_HXX_INCLUDED
24 #define SGTHREAD_HXX_INCLUDED 1
26 #include <simgear/compiler.h>
29 #if defined ( SG_HAVE_STD_INCLUDES )
34 # include <sys/errno.h>
40 void* start_handler( void* );
44 * Encapsulate generic threading methods.
45 * Users derive a class from SGThread and implement the run() member function.
51 * SGThread cancelation modes.
62 * Create a new thread object.
63 * When a SGThread object is created it does not begin execution
64 * immediately. It is started by calling the start() member function.
69 * Start the underlying thread of execution.
70 * @param cpu An optional parameter to specify on which CPU to run this
71 * thread (only supported on IRIX at this time).
72 * @return Pthread error code if execution fails, otherwise returns 0.
74 int start( unsigned cpu = 0 );
77 * Sends a cancellation request to the underlying thread. The target
78 * thread will either ignore the request, honor it immediately or defer
79 * it until it reaches a cancellation point.
84 * Suspends the exection of the calling thread until this thread
91 * Destroy a thread object.
92 * This is protected so that its illegal to simply delete a thread
93 * - it must return from its run() function.
98 * Set the threads cancellation mode.
99 * @param mode The required cancellation mode.
101 void set_cancel( cancel_t mode );
104 * All threads execute by deriving the run() method of SGThread.
105 * If this function terminates then the thread also terminates.
107 virtual void run() = 0;
112 * Pthread thread identifier.
116 friend void* start_handler( void* );
120 SGThread( const SGThread& );
121 SGThread& operator=( const SGThread& );
130 SGThread::~SGThread()
135 SGThread::start( unsigned cpu )
138 pthread_attr_init(&attr);
139 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
141 int status = pthread_create( &tid, &attr, start_handler, this );
142 assert( status == 0 );
143 pthread_attr_destroy(&attr);
145 if ( !status && !cpu )
146 pthread_setrunon_np( cpu );
154 int status = pthread_join( tid, 0 );
155 assert( status == 0 );
161 int status = pthread_cancel( tid );
162 assert( status == 0 );
166 * A mutex is used to protect a section of code such that at any time
167 * only a single thread can execute the code.
171 friend class SGPthreadCond;
176 * Create a new mutex.
177 * Under Linux this is a 'fast' mutex.
182 * Destroy a mutex object.
183 * Note: it is the responsibility of the caller to ensure the mutex is
184 * unlocked before destruction occurs.
190 * If the mutex is currently unlocked, it becomes locked and owned by
191 * the calling thread. If the mutex is already locked by another thread,
192 * the calling thread is suspended until the mutex is unlocked. If the
193 * mutex is already locked and owned by the calling thread, the calling
194 * thread is suspended until the mutex is unlocked, effectively causing
195 * the calling thread to deadlock.
197 * @see SGMutex::trylock
202 * Try to lock the mutex for the current thread. Behaves like lock except
203 * that it doesn't block the calling thread.
204 * @return true if mutex was successfully locked, otherwise false.
211 * It is assumed that the mutex is locked and owned by the calling thread.
220 pthread_mutex_t mutex;
223 inline SGMutex::SGMutex()
226 // Note: This will only work if the mutex is in shared memory,
227 // something we don't support enyhow. -EMH-
228 pthread_mutexattr_t mutex_attr = 0;
229 pthread_mutexattr_init(&mutex_attr);
230 pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
231 int status = pthread_mutex_init( &mutex, &mutex_attr );
232 assert( status == 0 );
233 pthread_mutexattr_destroy(&mutex_attr);
235 int status = pthread_mutex_init( &mutex, 0 );
236 assert( status == 0 );
240 inline SGMutex::~SGMutex()
242 int status = pthread_mutex_destroy( &mutex );
243 assert( status == 0 );
246 inline void SGMutex::lock()
248 int status = pthread_mutex_lock( &mutex );
249 assert( status == 0 );
252 inline void SGMutex::unlock()
254 int status = pthread_mutex_unlock( &mutex );
255 assert( status == 0 );
259 * A condition variable is a synchronization device that allows threads to
260 * suspend execution until some predicate on shared data is satisfied.
261 * A condition variable is always associated with a mutex to avoid race
268 * Create a new condition variable.
273 * Destroy the condition object.
278 * Wait for this condition variable to be signaled.
280 * @param SGMutex& reference to a locked mutex.
282 void wait( SGMutex& );
285 * Wait for this condition variable to be signaled for at most
288 * @param mutex reference to a locked mutex.
289 * @param ms milliseconds to wait for a signal.
293 bool wait( SGMutex& mutex, unsigned long ms );
296 * Wake one thread waiting on this condition variable.
297 * Nothing happens if no threads are waiting.
298 * If several threads are waiting exactly one thread is restarted. It
299 * is not specified which.
304 * Wake all threads waiting on this condition variable.
305 * Nothing happens if no threads are waiting.
311 SGPthreadCond(const SGPthreadCond& );
312 SGPthreadCond& operator=(const SGPthreadCond& );
317 * The Pthread conditon variable.
322 inline SGPthreadCond::SGPthreadCond()
324 int status = pthread_cond_init( &cond, 0 );
325 assert( status == 0 );
328 inline SGPthreadCond::~SGPthreadCond()
330 int status = pthread_cond_destroy( &cond );
331 assert( status == 0 );
334 inline void SGPthreadCond::signal()
336 int status = pthread_cond_signal( &cond );
337 assert( status == 0 );
340 inline void SGPthreadCond::broadcast()
342 int status = pthread_cond_broadcast( &cond );
343 assert( status == 0 );
346 inline void SGPthreadCond::wait( SGMutex& mutex )
348 int status = pthread_cond_wait( &cond, &mutex.mutex );
349 assert( status == 0 );
352 #endif /* SGTHREAD_HXX_INCLUDED */