"Fossies" - the Fresh Open Source Software Archive

Member "heaplayers-351/allocators/ptmalloc2/thread-m.h" (6 Oct 2003, 8891 Bytes) of package /linux/misc/old/heaplayers_3_5_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "thread-m.h" see the Fossies "Dox" file reference documentation.

    1 /* Basic platform-independent macro definitions for mutexes and
    2    thread-specific data.
    3    Copyright (C) 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
    4    This file is part of the GNU C Library.
    5    Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
    6 
    7    The GNU C Library is free software; you can redistribute it and/or
    8    modify it under the terms of the GNU Lesser General Public
    9    License as published by the Free Software Foundation; either
   10    version 2.1 of the License, or (at your option) any later version.
   11 
   12    The GNU C Library is distributed in the hope that it will be useful,
   13    but WITHOUT ANY WARRANTY; without even the implied warranty of
   14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15    Lesser General Public License for more details.
   16 
   17    You should have received a copy of the GNU Lesser General Public
   18    License along with the GNU C Library; if not, write to the Free
   19    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   20    02111-1307 USA.  */
   21 
   22 /* $Id: thread-m.h,v 1.1 2003/10/06 20:42:48 emery Exp $
   23    One out of _LIBC, USE_PTHREADS, USE_THR or USE_SPROC should be
   24    defined, otherwise the token NO_THREADS and dummy implementations
   25    of the macros will be defined.  */
   26 
   27 #ifndef _THREAD_M_H
   28 #define _THREAD_M_H
   29 
   30 #undef thread_atfork_static
   31 
   32 #if defined(_LIBC) /* The GNU C library, a special case of Posix threads */
   33 
   34 #include <bits/libc-lock.h>
   35 
   36 #ifdef PTHREAD_MUTEX_INITIALIZER
   37 
   38 typedef pthread_t thread_id;
   39 
   40 /* mutex */
   41 typedef pthread_mutex_t mutex_t;
   42 
   43 #define MUTEX_INITIALIZER   PTHREAD_MUTEX_INITIALIZER
   44 
   45 /* Even if not linking with libpthread, ensure usability of mutex as
   46    an `in use' flag, see also the NO_THREADS case below.  Assume
   47    pthread_mutex_t is at least one int wide.  */
   48 
   49 #define mutex_init(m)       \
   50    (__pthread_mutex_init != NULL \
   51     ? __pthread_mutex_init (m, NULL) : (*(int *)(m) = 0))
   52 #define mutex_lock(m)       \
   53    (__pthread_mutex_lock != NULL \
   54     ? __pthread_mutex_lock (m) : ((*(int *)(m) = 1), 0))
   55 #define mutex_trylock(m)    \
   56    (__pthread_mutex_trylock != NULL \
   57     ? __pthread_mutex_trylock (m) : (*(int *)(m) ? 1 : ((*(int *)(m) = 1), 0)))
   58 #define mutex_unlock(m)     \
   59    (__pthread_mutex_unlock != NULL \
   60     ? __pthread_mutex_unlock (m) : (*(int*)(m) = 0))
   61 
   62 #define thread_atfork(prepare, parent, child) \
   63    (__pthread_atfork != NULL ? __pthread_atfork(prepare, parent, child) : 0)
   64 
   65 #elif defined(MUTEX_INITIALIZER)
   66 /* Assume hurd, with cthreads */
   67 
   68 /* Cthreads `mutex_t' is a pointer to a mutex, and malloc wants just the
   69    mutex itself.  */
   70 #undef mutex_t
   71 #define mutex_t struct mutex
   72 
   73 #undef mutex_init
   74 #define mutex_init(m) (__mutex_init(m), 0)
   75 
   76 #undef mutex_lock
   77 #define mutex_lock(m) (__mutex_lock(m), 0)
   78 
   79 #undef mutex_unlock
   80 #define mutex_unlock(m) (__mutex_unlock(m), 0)
   81 
   82 #define mutex_trylock(m) (!__mutex_trylock(m))
   83 
   84 #define thread_atfork(prepare, parent, child) do {} while(0)
   85 #define thread_atfork_static(prepare, parent, child) \
   86  text_set_element(_hurd_fork_prepare_hook, prepare); \
   87  text_set_element(_hurd_fork_parent_hook, parent); \
   88  text_set_element(_hurd_fork_child_hook, child);
   89 
   90 /* No we're *not* using pthreads.  */
   91 #define __pthread_initialize ((void (*)(void))0)
   92 
   93 #else
   94 
   95 #define NO_THREADS
   96 
   97 #endif /* MUTEX_INITIALIZER && PTHREAD_MUTEX_INITIALIZER */
   98 
   99 #ifndef NO_THREADS
  100 
  101 /* thread specific data for glibc */
  102 
  103 #include <bits/libc-tsd.h>
  104 
  105 typedef int tsd_key_t[1];   /* no key data structure, libc magic does it */
  106 __libc_tsd_define (, MALLOC)    /* declaration/common definition */
  107 #define tsd_key_create(key, destr)  ((void) (key))
  108 #define tsd_setspecific(key, data)  __libc_tsd_set (MALLOC, (data))
  109 #define tsd_getspecific(key, vptr)  ((vptr) = __libc_tsd_get (MALLOC))
  110 
  111 #endif
  112 
  113 #elif defined(USE_PTHREADS) /* Posix threads */
  114 
  115 #include <pthread.h>
  116 
  117 typedef pthread_t thread_id;
  118 
  119 /* mutex */
  120 #if (defined __i386__ || defined __x86_64__) && defined __GNUC__ && \
  121     !defined USE_NO_SPINLOCKS
  122 
  123 #include <time.h>
  124 
  125 /* Use fast inline spinlocks.  */
  126 typedef struct {
  127   volatile unsigned int lock;
  128   int pad0_;
  129 } mutex_t;
  130 
  131 #define MUTEX_INITIALIZER          { 0 }
  132 #define mutex_init(m)              ((m)->lock = 0)
  133 static inline int mutex_lock(mutex_t *m) {
  134   int cnt = 0, r;
  135   struct timespec tm;
  136 
  137   for(;;) {
  138     __asm__ __volatile__
  139       ("xchgl %0, %1"
  140        : "=r"(r), "=m"(m->lock)
  141        : "0"(1), "m"(m->lock)
  142        : "memory");
  143     if(!r)
  144       return 0;
  145     if(cnt < 50) {
  146       sched_yield();
  147       cnt++;
  148     } else {
  149       tm.tv_sec = 0;
  150       tm.tv_nsec = 2000001;
  151       nanosleep(&tm, NULL);
  152       cnt = 0;
  153     }
  154   }
  155 }
  156 static inline int mutex_trylock(mutex_t *m) {
  157   int r;
  158 
  159   __asm__ __volatile__
  160     ("xchgl %0, %1"
  161      : "=r"(r), "=m"(m->lock)
  162      : "0"(1), "m"(m->lock)
  163      : "memory");
  164   return r;
  165 }
  166 static inline int mutex_unlock(mutex_t *m) {
  167   m->lock = 0;
  168   __asm __volatile ("" : "=m" (m->lock) : "0" (m->lock));
  169   return 0;
  170 }
  171 
  172 #else
  173 
  174 /* Normal pthread mutex.  */
  175 typedef pthread_mutex_t mutex_t;
  176 
  177 #define MUTEX_INITIALIZER          PTHREAD_MUTEX_INITIALIZER
  178 #define mutex_init(m)              pthread_mutex_init(m, NULL)
  179 #define mutex_lock(m)              pthread_mutex_lock(m)
  180 #define mutex_trylock(m)           pthread_mutex_trylock(m)
  181 #define mutex_unlock(m)            pthread_mutex_unlock(m)
  182 
  183 #endif /* (__i386__ || __x86_64__) && __GNUC__ && !USE_NO_SPINLOCKS */
  184 
  185 /* thread specific data */
  186 #if defined(__sgi) || defined(USE_TSD_DATA_HACK)
  187 
  188 /* Hack for thread-specific data, e.g. on Irix 6.x.  We can't use
  189    pthread_setspecific because that function calls malloc() itself.
  190    The hack only works when pthread_t can be converted to an integral
  191    type. */
  192 
  193 typedef void *tsd_key_t[256];
  194 #define tsd_key_create(key, destr) do { \
  195   int i; \
  196   for(i=0; i<256; i++) (*key)[i] = 0; \
  197 } while(0)
  198 #define tsd_setspecific(key, data) \
  199  (key[(unsigned)pthread_self() % 256] = (data))
  200 #define tsd_getspecific(key, vptr) \
  201  (vptr = key[(unsigned)pthread_self() % 256])
  202 
  203 #else
  204 
  205 typedef pthread_key_t tsd_key_t;
  206 
  207 #define tsd_key_create(key, destr) pthread_key_create(key, destr)
  208 #define tsd_setspecific(key, data) pthread_setspecific(key, data)
  209 #define tsd_getspecific(key, vptr) (vptr = pthread_getspecific(key))
  210 
  211 #endif
  212 
  213 /* at fork */
  214 #define thread_atfork(prepare, parent, child) \
  215                                    pthread_atfork(prepare, parent, child)
  216 
  217 #elif USE_THR /* Solaris threads */
  218 
  219 #include <thread.h>
  220 
  221 typedef thread_t thread_id;
  222 
  223 #define MUTEX_INITIALIZER          { 0 }
  224 #define mutex_init(m)              mutex_init(m, USYNC_THREAD, NULL)
  225 
  226 /*
  227  * Hack for thread-specific data on Solaris.  We can't use thr_setspecific
  228  * because that function calls malloc() itself.
  229  */
  230 typedef void *tsd_key_t[256];
  231 #define tsd_key_create(key, destr) do { \
  232   int i; \
  233   for(i=0; i<256; i++) (*key)[i] = 0; \
  234 } while(0)
  235 #define tsd_setspecific(key, data) (key[(unsigned)thr_self() % 256] = (data))
  236 #define tsd_getspecific(key, vptr) (vptr = key[(unsigned)thr_self() % 256])
  237 
  238 #define thread_atfork(prepare, parent, child) do {} while(0)
  239 
  240 #elif USE_SPROC /* SGI sproc() threads */
  241 
  242 #include <sys/wait.h>
  243 #include <sys/types.h>
  244 #include <sys/prctl.h>
  245 #include <abi_mutex.h>
  246 
  247 typedef int thread_id;
  248 
  249 typedef abilock_t mutex_t;
  250 
  251 #define MUTEX_INITIALIZER          { 0 }
  252 #define mutex_init(m)              init_lock(m)
  253 #define mutex_lock(m)              (spin_lock(m), 0)
  254 #define mutex_trylock(m)           acquire_lock(m)
  255 #define mutex_unlock(m)            release_lock(m)
  256 
  257 typedef int tsd_key_t;
  258 int tsd_key_next;
  259 #define tsd_key_create(key, destr) ((*key) = tsd_key_next++)
  260 #define tsd_setspecific(key, data) (((void **)(&PRDA->usr_prda))[key] = data)
  261 #define tsd_getspecific(key, vptr) (vptr = ((void **)(&PRDA->usr_prda))[key])
  262 
  263 #define thread_atfork(prepare, parent, child) do {} while(0)
  264 
  265 #else /* no _LIBC or USE_... are defined */
  266 
  267 #define NO_THREADS
  268 
  269 #endif /* defined(_LIBC) */
  270 
  271 #ifdef NO_THREADS /* No threads, provide dummy macros */
  272 
  273 typedef int thread_id;
  274 
  275 /* The mutex functions used to do absolutely nothing, i.e. lock,
  276    trylock and unlock would always just return 0.  However, even
  277    without any concurrently active threads, a mutex can be used
  278    legitimately as an `in use' flag.  To make the code that is
  279    protected by a mutex async-signal safe, these macros would have to
  280    be based on atomic test-and-set operations, for example. */
  281 typedef int mutex_t;
  282 
  283 #define MUTEX_INITIALIZER          0
  284 #define mutex_init(m)              (*(m) = 0)
  285 #define mutex_lock(m)              ((*(m) = 1), 0)
  286 #define mutex_trylock(m)           (*(m) ? 1 : ((*(m) = 1), 0))
  287 #define mutex_unlock(m)            (*(m) = 0)
  288 
  289 typedef void *tsd_key_t;
  290 #define tsd_key_create(key, destr) do {} while(0)
  291 #define tsd_setspecific(key, data) ((key) = (data))
  292 #define tsd_getspecific(key, vptr) (vptr = (key))
  293 
  294 #define thread_atfork(prepare, parent, child) do {} while(0)
  295 
  296 #endif /* defined(NO_THREADS) */
  297 
  298 #endif /* !defined(_THREAD_M_H) */