source: trunk/drmaa_utils/drmaa_utils/thread.c @ 1

Revision 1, 8.0 KB checked in by mmamonski, 13 years ago (diff)

Torque/PBS DRMAA initial commit

Line 
1/* $Id: thread.c 2 2009-10-12 09:51:22Z mamonski $ */
2/*
3 *  FedStage DRMAA utilities library
4 *  Copyright (C) 2006-2008  FedStage Systems
5 *
6 *  This program is free software: you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation, either version 3 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * @file thread.c
22 * Implementation of recursive mutexes for systems without native support
23 * for it.
24 */
25
26
27#ifdef HAVE_CONFIG_H
28#       include <config.h>
29#endif
30
31#include <drmaa_utils/thread.h>
32#include <drmaa_utils/common.h>
33#include <errno.h>
34#include <unistd.h>
35
36#ifdef HAVE_GETTID
37#include <sys/types.h>
38#include <sys/syscall.h>
39pid_t gettid(void)
40{
41        return (pid_t)syscall( __NR_gettid );
42}
43#endif
44
45#ifndef lint
46static char rcsid[]
47#       ifdef __GNUC__
48                __attribute__ ((unused))
49#       endif
50        = "$Id: thread.c 2 2009-10-12 09:51:22Z mamonski $";
51#endif
52
53
54void
55fsd_thread_create( fsd_thread_t *thread, void* (*func)(void*), void *arg )
56{
57        int errno_ = 0;
58        errno_ = pthread_create( thread, NULL, func, arg );
59        if( errno_ )
60                fsd_exc_raise_sys( errno_ );
61}
62
63void
64fsd_thread_join( fsd_thread_t th, void **thread_return )
65{
66        int errno_ = 0;
67        errno_ = pthread_join( th, thread_return );
68        if( errno_ )
69                fsd_exc_raise_sys( errno_ );
70}
71
72void
73fsd_thread_detach( fsd_thread_t th )
74{
75        int errno_ = 0;
76        errno_ = pthread_detach( th );
77        if( errno_ )
78                fsd_exc_raise_sys( errno_ );
79}
80
81
82#if HAVE_RECURSIVE_MUTEXES
83
84void
85fsd_mutex_init( fsd_mutex_t *mutex )
86{
87        int errno_ = 0;
88        pthread_mutexattr_t attr;
89        do {
90                errno_ = pthread_mutexattr_init( &attr );
91                if( errno_ )  break;
92                errno_ = pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE_NP );
93                if( errno_ )  break;
94                errno_ = pthread_mutex_init( mutex, &attr );
95                if( errno_ )  break;
96                errno_ = pthread_mutexattr_destroy( &attr );
97        } while( false );
98        if( errno_ )
99                fsd_exc_raise_sys( errno_ );
100}
101
102void
103fsd_mutex_destroy( fsd_mutex_t *mutex )
104{
105        int errno_ = 0;
106        errno_ = pthread_mutex_destroy( mutex );
107        if( errno_ )
108                fsd_exc_raise_sys( errno_ );
109}
110
111bool
112fsd_mutex_lock( fsd_mutex_t *mutex )
113{
114        int errno_ = 0;
115        errno_ = pthread_mutex_lock( mutex );
116        if( errno_ )
117                fsd_exc_raise_sys( errno_ );
118        return true;
119}
120
121bool
122fsd_mutex_unlock( fsd_mutex_t *mutex )
123{
124        int errno_ = 0;
125        errno_ = pthread_mutex_unlock( mutex );
126        if( errno_ )
127                fsd_exc_raise_sys( errno_ );
128        return false;
129}
130
131bool
132fsd_mutex_trylock( fsd_mutex_t *mutex )
133{
134        int errno_ = 0;
135        errno_ = pthread_mutex_trylock( mutex );
136        switch( errno_ )
137         {
138                case 0:
139                        return true;
140                case EBUSY:
141                        return false;
142                default:
143                        fsd_exc_raise_sys( errno_ );
144         }
145}
146
147int
148fsd_mutex_unlock_times( fsd_mutex_t *mutex )
149{
150        int count = 0;
151        int errno_ = 0;
152        while( errno_ == 0 )
153         {
154                errno_ = pthread_mutex_unlock( mutex );
155                if( !errno_ )
156                        count++;
157         }
158        if( errno_ != EPERM  ||  count == 0 )
159                fsd_exc_raise_sys( errno_ );
160        return count;
161}
162
163void
164fsd_cond_init( fsd_cond_t *cond )
165{
166        int errno_ = 0;
167        errno_ = pthread_cond_init( cond, NULL );
168        if( errno_ )
169                fsd_exc_raise_sys( errno_ );
170}
171
172void
173fsd_cond_destroy( fsd_cond_t *cond )
174{
175        int errno_ = 0;
176        errno_ = pthread_cond_destroy( cond );
177        if( errno_ )
178                fsd_exc_raise_sys( errno_ );
179}
180
181void
182fsd_cond_signal( fsd_cond_t *cond )
183{
184        int errno_ = 0;
185        errno_ = pthread_cond_signal( cond );
186        if( errno_ )
187                fsd_exc_raise_sys( errno_ );
188}
189
190void
191fsd_cond_broadcast( fsd_cond_t *cond )
192{
193        int errno_ = 0;
194        errno_ = pthread_cond_broadcast( cond );
195        if( errno_ )
196                fsd_exc_raise_sys( errno_ );
197}
198
199void
200fsd_cond_wait( fsd_cond_t *cond, fsd_mutex_t *mutex )
201{
202        int errno_ = 0;
203        errno_ = pthread_cond_wait( cond, mutex );
204        if( errno_ )
205                fsd_exc_raise_sys( errno_ );
206}
207
208bool
209fsd_cond_timedwait( fsd_cond_t *cond, fsd_mutex_t *mutex,
210                const struct timespec *abstime )
211{
212        int errno_ = 0;
213        errno_ = pthread_cond_timedwait( cond, mutex, abstime );
214        switch( errno_ )
215         {
216                case 0:
217                        return true;
218                case ETIMEDOUT:
219                        return false;
220                default:
221                        fsd_exc_raise_sys( errno_ );
222         }
223}
224
225#else /* ! HAVE_RECURSIVE_MUTEXES */
226
227void
228fsd_mutex_init( fsd_mutex_t *mutex )
229{
230        int errno_ = 0;
231        mutex->owner = (pthread_t)-1;
232        mutex->acquired = 0;
233        errno_ = pthread_mutex_init( &mutex->mutex, NULL );
234        if( errno_ )
235                fsd_exc_raise_sys( errno_ );
236}
237
238void
239fsd_mutex_destroy( fsd_mutex_t *mutex )
240{
241        int errno_ = 0;
242        errno_ = pthread_mutex_destroy( &mutex->mutex );
243        if( errno_ )
244                fsd_exc_raise_sys( errno_ );
245}
246
247bool
248fsd_mutex_lock( fsd_mutex_t *mutex )
249{
250        /* Note: The order of checks is significant. */
251        if( mutex->acquired  &&  pthread_equal( mutex->owner, pthread_self() ) )
252                mutex->acquired ++;
253        else
254         {
255                int errno_ = 0;
256                errno_ = pthread_mutex_lock( &mutex->mutex );
257                if( errno_ == 0 )
258                 {
259                        mutex->owner    = pthread_self();
260                        mutex->acquired = 1;
261                 }
262                else
263                        fsd_exc_raise_sys( errno_ );
264         }
265        return true;
266}
267
268bool
269fsd_mutex_unlock( fsd_mutex_t *mutex )
270{
271        fsd_assert( mutex->acquired
272                        &&  pthread_equal( mutex->owner, pthread_self() ) );
273        if( -- (mutex->acquired) == 0 )
274         {
275                int errno_ = 0;
276                errno_ = pthread_mutex_unlock( &mutex->mutex );
277                if( errno_ )
278                        fsd_exc_raise_sys( errno_ );
279         }
280        return false;
281}
282
283bool
284fsd_mutex_trylock( fsd_mutex_t *mutex )
285{
286        if( mutex->acquired  &&  pthread_equal( mutex->owner, pthread_self() ) )
287         {
288                mutex->acquired ++;
289                return true;
290         }
291        else
292         {
293                int errno_ = 0;
294                errno_ = pthread_mutex_trylock( &mutex->mutex );
295                switch( errno_ )
296                 {
297                        case 0:
298                                mutex->owner    = pthread_self();
299                                mutex->acquired = 1;
300                                return true;
301                        case ETIMEDOUT:
302                                return false;
303                        default:
304                                fsd_exc_raise_sys( errno_ );
305                 }
306         }
307}
308
309int
310fsd_mutex_unlock_times( fsd_mutex_t *mutex )
311{
312        int errno_ = 0;
313        int count = 0;
314        fsd_assert( mutex->acquired
315                        &&  pthread_equal( mutex->owner, pthread_self() ) );
316        count = mutex->acquired;
317        mutex->acquired = 0;
318        errno_ = pthread_mutex_unlock( &mutex->mutex );
319        if( errno_ )
320                fsd_exc_raise_sys( errno_ );
321        return count;
322}
323
324void
325fsd_cond_init( fsd_cond_t *cond )
326{
327        int errno_ = 0;
328        errno_ = pthread_cond_init( cond, NULL );
329        if( errno_ )
330                fsd_exc_raise_sys( errno_ );
331}
332
333void
334fsd_cond_destroy( fsd_cond_t *cond )
335{
336        int errno_ = 0;
337        errno_ = pthread_cond_destroy( cond );
338        if( errno_ )
339                fsd_exc_raise_sys( errno_ );
340}
341
342void
343fsd_cond_signal( fsd_cond_t *cond )
344{
345        int errno_ = 0;
346        errno_ = pthread_cond_signal( cond );
347        if( errno_ )
348                fsd_exc_raise_sys( errno_ );
349}
350
351void
352fsd_cond_broadcast( fsd_cond_t *cond )
353{
354        int errno_ = 0;
355        errno_ = pthread_cond_broadcast( cond );
356        if( errno_ )
357                fsd_exc_raise_sys( errno_ );
358}
359
360void
361fsd_cond_wait( fsd_cond_t *cond, fsd_mutex_t *mutex )
362{
363        int errno_ = 0;
364        int acquired_save = mutex->acquired;
365        fsd_assert( mutex->acquired
366                        &&  pthread_equal( mutex->owner, pthread_self() ) );
367        errno_ = pthread_cond_wait( cond, &mutex->mutex );
368        if( errno_ == 0 )
369         {
370                mutex->owner = pthread_self();
371                mutex->acquired = acquired_save;
372         }
373        else
374                fsd_exc_raise_sys( errno_ );
375}
376
377bool
378fsd_cond_timedwait( fsd_cond_t *cond, fsd_mutex_t *mutex,
379                const struct timespec *abstime )
380{
381        int errno_ = 0;
382        int acquired_save = mutex->acquired;
383        fsd_assert( mutex->acquired
384                        &&  pthread_equal( mutex->owner, pthread_self() ) );
385        errno_ = pthread_cond_timedwait( cond, &mutex->mutex, abstime );
386        switch( errno_ )
387         {
388                case 0:
389                        mutex->owner = pthread_self();
390                        mutex->acquired = acquired_save;
391                        return true;
392                case ETIMEDOUT:
393                        mutex->owner = pthread_self();
394                        mutex->acquired = acquired_save;
395                        return false;
396                default:
397                        fsd_exc_raise_sys( errno_ );
398         }
399}
400
401#endif /* ! HAVE_RECURSIVE_MUTEXES */
402
403
404
405int
406fsd_thread_id(void)
407{
408#if HAVE_GETTID
409        /*
410         * On Linux 2.6 (with NPTL) getpid() returns
411         * same value for all threads in single process.
412         */
413        return (int)gettid();
414#else
415        return (int)getpid();
416#endif
417}
418
Note: See TracBrowser for help on using the repository browser.