Home | History | Annotate | Download | only in Python
      1 
      2 /* Posix threads interface */
      3 
      4 #include <stdlib.h>
      5 #include <string.h>
      6 #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
      7 #define destructor xxdestructor
      8 #endif
      9 #include <pthread.h>
     10 #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
     11 #undef destructor
     12 #endif
     13 #include <signal.h>
     14 
     15 /* The POSIX spec requires that use of pthread_attr_setstacksize
     16    be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
     17 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
     18 #ifndef THREAD_STACK_SIZE
     19 #define THREAD_STACK_SIZE       0       /* use default stack size */
     20 #endif
     21 
     22 /* The default stack size for new threads on OSX and BSD is small enough that
     23  * we'll get hard crashes instead of 'maximum recursion depth exceeded'
     24  * exceptions.
     25  *
     26  * The default stack sizes below are the empirically determined minimal stack
     27  * sizes where a simple recursive function doesn't cause a hard crash.
     28  */
     29 #if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
     30 #undef  THREAD_STACK_SIZE
     31 #define THREAD_STACK_SIZE       0x500000
     32 #endif
     33 #if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
     34 #undef  THREAD_STACK_SIZE
     35 #define THREAD_STACK_SIZE       0x400000
     36 #endif
     37 /* for safety, ensure a viable minimum stacksize */
     38 #define THREAD_STACK_MIN        0x8000  /* 32kB */
     39 #else  /* !_POSIX_THREAD_ATTR_STACKSIZE */
     40 #ifdef THREAD_STACK_SIZE
     41 #error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
     42 #endif
     43 #endif
     44 
     45 /* The POSIX spec says that implementations supporting the sem_*
     46    family of functions must indicate this by defining
     47    _POSIX_SEMAPHORES. */
     48 #ifdef _POSIX_SEMAPHORES
     49 /* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
     50    we need to add 0 to make it work there as well. */
     51 #if (_POSIX_SEMAPHORES+0) == -1
     52 #define HAVE_BROKEN_POSIX_SEMAPHORES
     53 #else
     54 #include <semaphore.h>
     55 #include <errno.h>
     56 #endif
     57 #endif
     58 
     59 /* Before FreeBSD 5.4, system scope threads was very limited resource
     60    in default setting.  So the process scope is preferred to get
     61    enough number of threads to work. */
     62 #ifdef __FreeBSD__
     63 #include <osreldate.h>
     64 #if __FreeBSD_version >= 500000 && __FreeBSD_version < 504101
     65 #undef PTHREAD_SYSTEM_SCHED_SUPPORTED
     66 #endif
     67 #endif
     68 
     69 #if !defined(pthread_attr_default)
     70 #  define pthread_attr_default ((pthread_attr_t *)NULL)
     71 #endif
     72 #if !defined(pthread_mutexattr_default)
     73 #  define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
     74 #endif
     75 #if !defined(pthread_condattr_default)
     76 #  define pthread_condattr_default ((pthread_condattr_t *)NULL)
     77 #endif
     78 
     79 
     80 /* Whether or not to use semaphores directly rather than emulating them with
     81  * mutexes and condition variables:
     82  */
     83 #if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
     84      defined(HAVE_SEM_TIMEDWAIT))
     85 #  define USE_SEMAPHORES
     86 #else
     87 #  undef USE_SEMAPHORES
     88 #endif
     89 
     90 
     91 /* On platforms that don't use standard POSIX threads pthread_sigmask()
     92  * isn't present.  DEC threads uses sigprocmask() instead as do most
     93  * other UNIX International compliant systems that don't have the full
     94  * pthread implementation.
     95  */
     96 #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
     97 #  define SET_THREAD_SIGMASK pthread_sigmask
     98 #else
     99 #  define SET_THREAD_SIGMASK sigprocmask
    100 #endif
    101 
    102 
    103 /* We assume all modern POSIX systems have gettimeofday() */
    104 #ifdef GETTIMEOFDAY_NO_TZ
    105 #define GETTIMEOFDAY(ptv) gettimeofday(ptv)
    106 #else
    107 #define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
    108 #endif
    109 
    110 #define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
    111 do { \
    112     struct timeval tv; \
    113     GETTIMEOFDAY(&tv); \
    114     tv.tv_usec += microseconds % 1000000; \
    115     tv.tv_sec += microseconds / 1000000; \
    116     tv.tv_sec += tv.tv_usec / 1000000; \
    117     tv.tv_usec %= 1000000; \
    118     ts.tv_sec = tv.tv_sec; \
    119     ts.tv_nsec = tv.tv_usec * 1000; \
    120 } while(0)
    121 
    122 
    123 /* A pthread mutex isn't sufficient to model the Python lock type
    124  * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
    125  * following are undefined:
    126  *  -> a thread tries to lock a mutex it already has locked
    127  *  -> a thread tries to unlock a mutex locked by a different thread
    128  * pthread mutexes are designed for serializing threads over short pieces
    129  * of code anyway, so wouldn't be an appropriate implementation of
    130  * Python's locks regardless.
    131  *
    132  * The pthread_lock struct implements a Python lock as a "locked?" bit
    133  * and a <condition, mutex> pair.  In general, if the bit can be acquired
    134  * instantly, it is, else the pair is used to block the thread until the
    135  * bit is cleared.     9 May 1994 tim (at) ksr.com
    136  */
    137 
    138 typedef struct {
    139     char             locked; /* 0=unlocked, 1=locked */
    140     /* a <cond, mutex> pair to handle an acquire of a locked lock */
    141     pthread_cond_t   lock_released;
    142     pthread_mutex_t  mut;
    143 } pthread_lock;
    144 
    145 #define CHECK_STATUS(name)  if (status != 0) { perror(name); error = 1; }
    146 
    147 /*
    148  * Initialization.
    149  */
    150 
    151 #if defined(_HAVE_BSDI)
    152 static
    153 void _noop(void)
    154 {
    155 }
    156 
    157 static void
    158 PyThread__init_thread(void)
    159 {
    160     /* DO AN INIT BY STARTING THE THREAD */
    161     static int dummy = 0;
    162     pthread_t thread1;
    163     pthread_create(&thread1, NULL, (void *) _noop, &dummy);
    164     pthread_join(thread1, NULL);
    165 }
    166 
    167 #else /* !_HAVE_BSDI */
    168 
    169 static void
    170 PyThread__init_thread(void)
    171 {
    172 #if defined(_AIX) && defined(__GNUC__)
    173     extern void pthread_init(void);
    174     pthread_init();
    175 #endif
    176 }
    177 
    178 #endif /* !_HAVE_BSDI */
    179 
    180 /*
    181  * Thread support.
    182  */
    183 
    184 
    185 long
    186 PyThread_start_new_thread(void (*func)(void *), void *arg)
    187 {
    188     pthread_t th;
    189     int status;
    190 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    191     pthread_attr_t attrs;
    192 #endif
    193 #if defined(THREAD_STACK_SIZE)
    194     size_t      tss;
    195 #endif
    196 
    197     dprintf(("PyThread_start_new_thread called\n"));
    198     if (!initialized)
    199         PyThread_init_thread();
    200 
    201 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    202     if (pthread_attr_init(&attrs) != 0)
    203         return -1;
    204 #endif
    205 #if defined(THREAD_STACK_SIZE)
    206     tss = (_pythread_stacksize != 0) ? _pythread_stacksize
    207                                      : THREAD_STACK_SIZE;
    208     if (tss != 0) {
    209         if (pthread_attr_setstacksize(&attrs, tss) != 0) {
    210             pthread_attr_destroy(&attrs);
    211             return -1;
    212         }
    213     }
    214 #endif
    215 #if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    216     pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
    217 #endif
    218 
    219     status = pthread_create(&th,
    220 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    221                              &attrs,
    222 #else
    223                              (pthread_attr_t*)NULL,
    224 #endif
    225                              (void* (*)(void *))func,
    226                              (void *)arg
    227                              );
    228 
    229 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    230     pthread_attr_destroy(&attrs);
    231 #endif
    232     if (status != 0)
    233         return -1;
    234 
    235     pthread_detach(th);
    236 
    237 #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
    238     return (long) th;
    239 #else
    240     return (long) *(long *) &th;
    241 #endif
    242 }
    243 
    244 /* XXX This implementation is considered (to quote Tim Peters) "inherently
    245    hosed" because:
    246      - It does not guarantee the promise that a non-zero integer is returned.
    247      - The cast to long is inherently unsafe.
    248      - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
    249 */
    250 long
    251 PyThread_get_thread_ident(void)
    252 {
    253     volatile pthread_t threadid;
    254     if (!initialized)
    255         PyThread_init_thread();
    256     threadid = pthread_self();
    257     return (long) threadid;
    258 }
    259 
    260 void
    261 PyThread_exit_thread(void)
    262 {
    263     dprintf(("PyThread_exit_thread called\n"));
    264     if (!initialized)
    265         exit(0);
    266     pthread_exit(0);
    267 }
    268 
    269 #ifdef USE_SEMAPHORES
    270 
    271 /*
    272  * Lock support.
    273  */
    274 
    275 PyThread_type_lock
    276 PyThread_allocate_lock(void)
    277 {
    278     sem_t *lock;
    279     int status, error = 0;
    280 
    281     dprintf(("PyThread_allocate_lock called\n"));
    282     if (!initialized)
    283         PyThread_init_thread();
    284 
    285     lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
    286 
    287     if (lock) {
    288         status = sem_init(lock,0,1);
    289         CHECK_STATUS("sem_init");
    290 
    291         if (error) {
    292             PyMem_RawFree((void *)lock);
    293             lock = NULL;
    294         }
    295     }
    296 
    297     dprintf(("PyThread_allocate_lock() -> %p\n", lock));
    298     return (PyThread_type_lock)lock;
    299 }
    300 
    301 void
    302 PyThread_free_lock(PyThread_type_lock lock)
    303 {
    304     sem_t *thelock = (sem_t *)lock;
    305     int status, error = 0;
    306 
    307     (void) error; /* silence unused-but-set-variable warning */
    308     dprintf(("PyThread_free_lock(%p) called\n", lock));
    309 
    310     if (!thelock)
    311         return;
    312 
    313     status = sem_destroy(thelock);
    314     CHECK_STATUS("sem_destroy");
    315 
    316     PyMem_RawFree((void *)thelock);
    317 }
    318 
    319 /*
    320  * As of February 2002, Cygwin thread implementations mistakenly report error
    321  * codes in the return value of the sem_ calls (like the pthread_ functions).
    322  * Correct implementations return -1 and put the code in errno. This supports
    323  * either.
    324  */
    325 static int
    326 fix_status(int status)
    327 {
    328     return (status == -1) ? errno : status;
    329 }
    330 
    331 PyLockStatus
    332 PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
    333                             int intr_flag)
    334 {
    335     PyLockStatus success;
    336     sem_t *thelock = (sem_t *)lock;
    337     int status, error = 0;
    338     struct timespec ts;
    339 
    340     (void) error; /* silence unused-but-set-variable warning */
    341     dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
    342              lock, microseconds, intr_flag));
    343 
    344     if (microseconds > 0)
    345         MICROSECONDS_TO_TIMESPEC(microseconds, ts);
    346     do {
    347         if (microseconds > 0)
    348             status = fix_status(sem_timedwait(thelock, &ts));
    349         else if (microseconds == 0)
    350             status = fix_status(sem_trywait(thelock));
    351         else
    352             status = fix_status(sem_wait(thelock));
    353         /* Retry if interrupted by a signal, unless the caller wants to be
    354            notified.  */
    355     } while (!intr_flag && status == EINTR);
    356 
    357     /* Don't check the status if we're stopping because of an interrupt.  */
    358     if (!(intr_flag && status == EINTR)) {
    359         if (microseconds > 0) {
    360             if (status != ETIMEDOUT)
    361                 CHECK_STATUS("sem_timedwait");
    362         }
    363         else if (microseconds == 0) {
    364             if (status != EAGAIN)
    365                 CHECK_STATUS("sem_trywait");
    366         }
    367         else {
    368             CHECK_STATUS("sem_wait");
    369         }
    370     }
    371 
    372     if (status == 0) {
    373         success = PY_LOCK_ACQUIRED;
    374     } else if (intr_flag && status == EINTR) {
    375         success = PY_LOCK_INTR;
    376     } else {
    377         success = PY_LOCK_FAILURE;
    378     }
    379 
    380     dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
    381              lock, microseconds, intr_flag, success));
    382     return success;
    383 }
    384 
    385 void
    386 PyThread_release_lock(PyThread_type_lock lock)
    387 {
    388     sem_t *thelock = (sem_t *)lock;
    389     int status, error = 0;
    390 
    391     (void) error; /* silence unused-but-set-variable warning */
    392     dprintf(("PyThread_release_lock(%p) called\n", lock));
    393 
    394     status = sem_post(thelock);
    395     CHECK_STATUS("sem_post");
    396 }
    397 
    398 #else /* USE_SEMAPHORES */
    399 
    400 /*
    401  * Lock support.
    402  */
    403 PyThread_type_lock
    404 PyThread_allocate_lock(void)
    405 {
    406     pthread_lock *lock;
    407     int status, error = 0;
    408 
    409     dprintf(("PyThread_allocate_lock called\n"));
    410     if (!initialized)
    411         PyThread_init_thread();
    412 
    413     lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
    414     if (lock) {
    415         memset((void *)lock, '\0', sizeof(pthread_lock));
    416         lock->locked = 0;
    417 
    418         status = pthread_mutex_init(&lock->mut,
    419                                     pthread_mutexattr_default);
    420         CHECK_STATUS("pthread_mutex_init");
    421         /* Mark the pthread mutex underlying a Python mutex as
    422            pure happens-before.  We can't simply mark the
    423            Python-level mutex as a mutex because it can be
    424            acquired and released in different threads, which
    425            will cause errors. */
    426         _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
    427 
    428         status = pthread_cond_init(&lock->lock_released,
    429                                    pthread_condattr_default);
    430         CHECK_STATUS("pthread_cond_init");
    431 
    432         if (error) {
    433             PyMem_RawFree((void *)lock);
    434             lock = 0;
    435         }
    436     }
    437 
    438     dprintf(("PyThread_allocate_lock() -> %p\n", lock));
    439     return (PyThread_type_lock) lock;
    440 }
    441 
    442 void
    443 PyThread_free_lock(PyThread_type_lock lock)
    444 {
    445     pthread_lock *thelock = (pthread_lock *)lock;
    446     int status, error = 0;
    447 
    448     (void) error; /* silence unused-but-set-variable warning */
    449     dprintf(("PyThread_free_lock(%p) called\n", lock));
    450 
    451     /* some pthread-like implementations tie the mutex to the cond
    452      * and must have the cond destroyed first.
    453      */
    454     status = pthread_cond_destroy( &thelock->lock_released );
    455     CHECK_STATUS("pthread_cond_destroy");
    456 
    457     status = pthread_mutex_destroy( &thelock->mut );
    458     CHECK_STATUS("pthread_mutex_destroy");
    459 
    460     PyMem_RawFree((void *)thelock);
    461 }
    462 
    463 PyLockStatus
    464 PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
    465                             int intr_flag)
    466 {
    467     PyLockStatus success;
    468     pthread_lock *thelock = (pthread_lock *)lock;
    469     int status, error = 0;
    470 
    471     dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
    472              lock, microseconds, intr_flag));
    473 
    474     status = pthread_mutex_lock( &thelock->mut );
    475     CHECK_STATUS("pthread_mutex_lock[1]");
    476 
    477     if (thelock->locked == 0) {
    478         success = PY_LOCK_ACQUIRED;
    479     } else if (microseconds == 0) {
    480         success = PY_LOCK_FAILURE;
    481     } else {
    482         struct timespec ts;
    483         if (microseconds > 0)
    484             MICROSECONDS_TO_TIMESPEC(microseconds, ts);
    485         /* continue trying until we get the lock */
    486 
    487         /* mut must be locked by me -- part of the condition
    488          * protocol */
    489         success = PY_LOCK_FAILURE;
    490         while (success == PY_LOCK_FAILURE) {
    491             if (microseconds > 0) {
    492                 status = pthread_cond_timedwait(
    493                     &thelock->lock_released,
    494                     &thelock->mut, &ts);
    495                 if (status == ETIMEDOUT)
    496                     break;
    497                 CHECK_STATUS("pthread_cond_timed_wait");
    498             }
    499             else {
    500                 status = pthread_cond_wait(
    501                     &thelock->lock_released,
    502                     &thelock->mut);
    503                 CHECK_STATUS("pthread_cond_wait");
    504             }
    505 
    506             if (intr_flag && status == 0 && thelock->locked) {
    507                 /* We were woken up, but didn't get the lock.  We probably received
    508                  * a signal.  Return PY_LOCK_INTR to allow the caller to handle
    509                  * it and retry.  */
    510                 success = PY_LOCK_INTR;
    511                 break;
    512             } else if (status == 0 && !thelock->locked) {
    513                 success = PY_LOCK_ACQUIRED;
    514             } else {
    515                 success = PY_LOCK_FAILURE;
    516             }
    517         }
    518     }
    519     if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
    520     status = pthread_mutex_unlock( &thelock->mut );
    521     CHECK_STATUS("pthread_mutex_unlock[1]");
    522 
    523     if (error) success = PY_LOCK_FAILURE;
    524     dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
    525              lock, microseconds, intr_flag, success));
    526     return success;
    527 }
    528 
    529 void
    530 PyThread_release_lock(PyThread_type_lock lock)
    531 {
    532     pthread_lock *thelock = (pthread_lock *)lock;
    533     int status, error = 0;
    534 
    535     (void) error; /* silence unused-but-set-variable warning */
    536     dprintf(("PyThread_release_lock(%p) called\n", lock));
    537 
    538     status = pthread_mutex_lock( &thelock->mut );
    539     CHECK_STATUS("pthread_mutex_lock[3]");
    540 
    541     thelock->locked = 0;
    542 
    543     /* wake up someone (anyone, if any) waiting on the lock */
    544     status = pthread_cond_signal( &thelock->lock_released );
    545     CHECK_STATUS("pthread_cond_signal");
    546 
    547     status = pthread_mutex_unlock( &thelock->mut );
    548     CHECK_STATUS("pthread_mutex_unlock[3]");
    549 }
    550 
    551 #endif /* USE_SEMAPHORES */
    552 
    553 int
    554 PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
    555 {
    556     return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
    557 }
    558 
    559 /* set the thread stack size.
    560  * Return 0 if size is valid, -1 if size is invalid,
    561  * -2 if setting stack size is not supported.
    562  */
    563 static int
    564 _pythread_pthread_set_stacksize(size_t size)
    565 {
    566 #if defined(THREAD_STACK_SIZE)
    567     pthread_attr_t attrs;
    568     size_t tss_min;
    569     int rc = 0;
    570 #endif
    571 
    572     /* set to default */
    573     if (size == 0) {
    574         _pythread_stacksize = 0;
    575         return 0;
    576     }
    577 
    578 #if defined(THREAD_STACK_SIZE)
    579 #if defined(PTHREAD_STACK_MIN)
    580     tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
    581                                                    : THREAD_STACK_MIN;
    582 #else
    583     tss_min = THREAD_STACK_MIN;
    584 #endif
    585     if (size >= tss_min) {
    586         /* validate stack size by setting thread attribute */
    587         if (pthread_attr_init(&attrs) == 0) {
    588             rc = pthread_attr_setstacksize(&attrs, size);
    589             pthread_attr_destroy(&attrs);
    590             if (rc == 0) {
    591                 _pythread_stacksize = size;
    592                 return 0;
    593             }
    594         }
    595     }
    596     return -1;
    597 #else
    598     return -2;
    599 #endif
    600 }
    601 
    602 #define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
    603 
    604 #define Py_HAVE_NATIVE_TLS
    605 
    606 int
    607 PyThread_create_key(void)
    608 {
    609     pthread_key_t key;
    610     int fail = pthread_key_create(&key, NULL);
    611     if (fail)
    612         return -1;
    613     if (key > INT_MAX) {
    614         /* Issue #22206: handle integer overflow */
    615         pthread_key_delete(key);
    616         errno = ENOMEM;
    617         return -1;
    618     }
    619     return (int)key;
    620 }
    621 
    622 void
    623 PyThread_delete_key(int key)
    624 {
    625     pthread_key_delete(key);
    626 }
    627 
    628 void
    629 PyThread_delete_key_value(int key)
    630 {
    631     pthread_setspecific(key, NULL);
    632 }
    633 
    634 int
    635 PyThread_set_key_value(int key, void *value)
    636 {
    637     int fail;
    638     fail = pthread_setspecific(key, value);
    639     return fail ? -1 : 0;
    640 }
    641 
    642 void *
    643 PyThread_get_key_value(int key)
    644 {
    645     return pthread_getspecific(key);
    646 }
    647 
    648 void
    649 PyThread_ReInitTLS(void)
    650 {}
    651