Back to index

python3.2  3.2.2
Classes | Defines | Functions
thread_pthread.h File Reference
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>

Go to the source code of this file.

Classes

struct  pthread_lock

Defines

#define pthread_attr_default   ((pthread_attr_t *)NULL)
#define pthread_mutexattr_default   ((pthread_mutexattr_t *)NULL)
#define pthread_condattr_default   ((pthread_condattr_t *)NULL)
#define SET_THREAD_SIGMASK   sigprocmask
#define GETTIMEOFDAY(ptv)   gettimeofday(ptv, (struct timezone *)NULL)
#define MICROSECONDS_TO_TIMESPEC(microseconds, ts)
#define CHECK_STATUS(name)   if (status != 0) { perror(name); error = 1; }
#define THREAD_SET_STACKSIZE(x)   _pythread_pthread_set_stacksize(x)
#define Py_HAVE_NATIVE_TLS

Functions

static void PyThread__init_thread (void)
long PyThread_start_new_thread (void(*func)(void *), void *arg)
long PyThread_get_thread_ident (void)
void PyThread_exit_thread (void)
PyThread_type_lock PyThread_allocate_lock (void)
void PyThread_free_lock (PyThread_type_lock lock)
PyLockStatus PyThread_acquire_lock_timed (PyThread_type_lock lock, PY_TIMEOUT_T microseconds, int intr_flag)
void PyThread_release_lock (PyThread_type_lock lock)
int PyThread_acquire_lock (PyThread_type_lock lock, int waitflag)
static int _pythread_pthread_set_stacksize (size_t size)
int PyThread_create_key (void)
void PyThread_delete_key (int key)
void PyThread_delete_key_value (int key)
int PyThread_set_key_value (int key, void *value)
voidPyThread_get_key_value (int key)
void PyThread_ReInitTLS (void)

Class Documentation

struct pthread_lock

Definition at line 134 of file thread_pthread.h.

Class Members
pthread_cond_t lock_released
char locked
pthread_mutex_t mut

Define Documentation

#define CHECK_STATUS (   name)    if (status != 0) { perror(name); error = 1; }

Definition at line 141 of file thread_pthread.h.

#define GETTIMEOFDAY (   ptv)    gettimeofday(ptv, (struct timezone *)NULL)

Definition at line 103 of file thread_pthread.h.

#define MICROSECONDS_TO_TIMESPEC (   microseconds,
  ts 
)
Value:
do { \
    struct timeval tv; \
    GETTIMEOFDAY(&tv); \
    tv.tv_usec += microseconds % 1000000; \
    tv.tv_sec += microseconds / 1000000; \
    tv.tv_sec += tv.tv_usec / 1000000; \
    tv.tv_usec %= 1000000; \
    ts.tv_sec = tv.tv_sec; \
    ts.tv_nsec = tv.tv_usec * 1000; \
} while(0)

Definition at line 106 of file thread_pthread.h.

#define pthread_attr_default   ((pthread_attr_t *)NULL)

Definition at line 66 of file thread_pthread.h.

#define pthread_condattr_default   ((pthread_condattr_t *)NULL)

Definition at line 72 of file thread_pthread.h.

#define pthread_mutexattr_default   ((pthread_mutexattr_t *)NULL)

Definition at line 69 of file thread_pthread.h.

Definition at line 597 of file thread_pthread.h.

#define SET_THREAD_SIGMASK   sigprocmask

Definition at line 95 of file thread_pthread.h.

Definition at line 595 of file thread_pthread.h.


Function Documentation

static int _pythread_pthread_set_stacksize ( size_t  size) [static]

Definition at line 557 of file thread_pthread.h.

{
#if defined(THREAD_STACK_SIZE)
    pthread_attr_t attrs;
    size_t tss_min;
    int rc = 0;
#endif

    /* set to default */
    if (size == 0) {
        _pythread_stacksize = 0;
        return 0;
    }

#if defined(THREAD_STACK_SIZE)
#if defined(PTHREAD_STACK_MIN)
    tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
                                                   : THREAD_STACK_MIN;
#else
    tss_min = THREAD_STACK_MIN;
#endif
    if (size >= tss_min) {
        /* validate stack size by setting thread attribute */
        if (pthread_attr_init(&attrs) == 0) {
            rc = pthread_attr_setstacksize(&attrs, size);
            pthread_attr_destroy(&attrs);
            if (rc == 0) {
                _pythread_stacksize = size;
                return 0;
            }
        }
    }
    return -1;
#else
    return -2;
#endif
}
static void PyThread__init_thread ( void  ) [static]

Definition at line 166 of file thread_pthread.h.

{
#if defined(_AIX) && defined(__GNUC__)
    pthread_init();
#endif
}
int PyThread_acquire_lock ( PyThread_type_lock  lock,
int  waitflag 
)

Definition at line 547 of file thread_pthread.h.

{
    return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
}

Here is the call graph for this function:

PyLockStatus PyThread_acquire_lock_timed ( PyThread_type_lock  lock,
PY_TIMEOUT_T  microseconds,
int  intr_flag 
)

Definition at line 458 of file thread_pthread.h.

{
    PyLockStatus success;
    pthread_lock *thelock = (pthread_lock *)lock;
    int status, error = 0;

    dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
             lock, microseconds, intr_flag));

    status = pthread_mutex_lock( &thelock->mut );
    CHECK_STATUS("pthread_mutex_lock[1]");

    if (thelock->locked == 0) {
        success = PY_LOCK_ACQUIRED;
    } else if (microseconds == 0) {
        success = PY_LOCK_FAILURE;
    } else {
        struct timespec ts;
        if (microseconds > 0)
            MICROSECONDS_TO_TIMESPEC(microseconds, ts);
        /* continue trying until we get the lock */

        /* mut must be locked by me -- part of the condition
         * protocol */
        success = PY_LOCK_FAILURE;
        while (success == PY_LOCK_FAILURE) {
            if (microseconds > 0) {
                status = pthread_cond_timedwait(
                    &thelock->lock_released,
                    &thelock->mut, &ts);
                if (status == ETIMEDOUT)
                    break;
                CHECK_STATUS("pthread_cond_timed_wait");
            }
            else {
                status = pthread_cond_wait(
                    &thelock->lock_released,
                    &thelock->mut);
                CHECK_STATUS("pthread_cond_wait");
            }

            if (intr_flag && status == 0 && thelock->locked) {
                /* We were woken up, but didn't get the lock.  We probably received
                 * a signal.  Return PY_LOCK_INTR to allow the caller to handle
                 * it and retry.  */
                success = PY_LOCK_INTR;
                break;
            } else if (status == 0 && !thelock->locked) {
                success = PY_LOCK_ACQUIRED;
            } else {
                success = PY_LOCK_FAILURE;
            }
        }
    }
    if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
    status = pthread_mutex_unlock( &thelock->mut );
    CHECK_STATUS("pthread_mutex_unlock[1]");

    if (error) success = PY_LOCK_FAILURE;
    dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
             lock, microseconds, intr_flag, success));
    return success;
}

Here is the call graph for this function:

Definition at line 402 of file thread_pthread.h.

{
    pthread_lock *lock;
    int status, error = 0;

    dprintf(("PyThread_allocate_lock called\n"));
    if (!initialized)
        PyThread_init_thread();

    lock = (pthread_lock *) malloc(sizeof(pthread_lock));
    if (lock) {
        memset((void *)lock, '\0', sizeof(pthread_lock));
        lock->locked = 0;

        status = pthread_mutex_init(&lock->mut,
                                    pthread_mutexattr_default);
        CHECK_STATUS("pthread_mutex_init");
        /* Mark the pthread mutex underlying a Python mutex as
           pure happens-before.  We can't simply mark the
           Python-level mutex as a mutex because it can be
           acquired and released in different threads, which
           will cause errors. */
        _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);

        status = pthread_cond_init(&lock->lock_released,
                                   pthread_condattr_default);
        CHECK_STATUS("pthread_cond_init");

        if (error) {
            free((void *)lock);
            lock = 0;
        }
    }

    dprintf(("PyThread_allocate_lock() -> %p\n", lock));
    return (PyThread_type_lock) lock;
}

Here is the call graph for this function:

Definition at line 600 of file thread_pthread.h.

{
    pthread_key_t key;
    int fail = pthread_key_create(&key, NULL);
    return fail ? -1 : key;
}

Here is the call graph for this function:

Definition at line 608 of file thread_pthread.h.

{
    pthread_key_delete(key);
}

Definition at line 614 of file thread_pthread.h.

{
    pthread_setspecific(key, NULL);
}

Definition at line 262 of file thread_pthread.h.

{
    dprintf(("PyThread_exit_thread called\n"));
    if (!initialized)
        exit(0);
    pthread_exit(0);
}

Definition at line 441 of file thread_pthread.h.

{
    pthread_lock *thelock = (pthread_lock *)lock;
    int status, error = 0;

    dprintf(("PyThread_free_lock(%p) called\n", lock));

    status = pthread_mutex_destroy( &thelock->mut );
    CHECK_STATUS("pthread_mutex_destroy");

    status = pthread_cond_destroy( &thelock->lock_released );
    CHECK_STATUS("pthread_cond_destroy");

    free((void *)thelock);
}

Here is the call graph for this function:

Definition at line 631 of file thread_pthread.h.

{
    return pthread_getspecific(key);
}

Definition at line 247 of file thread_pthread.h.

{
    volatile pthread_t threadid;
    if (!initialized)
        PyThread_init_thread();
    /* Jump through some hoops for Alpha OSF/1 */
    threadid = pthread_self();
#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
    return (long) threadid;
#else
    return (long) *(long *) &threadid;
#endif
}

Here is the call graph for this function:

Definition at line 637 of file thread_pthread.h.

{}

Definition at line 524 of file thread_pthread.h.

{
    pthread_lock *thelock = (pthread_lock *)lock;
    int status, error = 0;

    dprintf(("PyThread_release_lock(%p) called\n", lock));

    status = pthread_mutex_lock( &thelock->mut );
    CHECK_STATUS("pthread_mutex_lock[3]");

    thelock->locked = 0;

    status = pthread_mutex_unlock( &thelock->mut );
    CHECK_STATUS("pthread_mutex_unlock[3]");

    /* wake up someone (anyone, if any) waiting on the lock */
    status = pthread_cond_signal( &thelock->lock_released );
    CHECK_STATUS("pthread_cond_signal");
}

Here is the call graph for this function:

int PyThread_set_key_value ( int  key,
void value 
)

Definition at line 620 of file thread_pthread.h.

{
    int fail;
    void *oldValue = pthread_getspecific(key);
    if (oldValue != NULL)
        return 0;
    fail = pthread_setspecific(key, value);
    return fail ? -1 : 0;
}

Here is the call graph for this function:

long PyThread_start_new_thread ( void(*)(void *)  func,
void arg 
)

Definition at line 181 of file thread_pthread.h.

{
    pthread_t th;
    int status;
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    pthread_attr_t attrs;
#endif
#if defined(THREAD_STACK_SIZE)
    size_t      tss;
#endif

    dprintf(("PyThread_start_new_thread called\n"));
    if (!initialized)
        PyThread_init_thread();

#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    if (pthread_attr_init(&attrs) != 0)
        return -1;
#endif
#if defined(THREAD_STACK_SIZE)
    tss = (_pythread_stacksize != 0) ? _pythread_stacksize
                                     : THREAD_STACK_SIZE;
    if (tss != 0) {
        if (pthread_attr_setstacksize(&attrs, tss) != 0) {
            pthread_attr_destroy(&attrs);
            return -1;
        }
    }
#endif
#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
#endif

    status = pthread_create(&th,
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
                             &attrs,
#else
                             (pthread_attr_t*)NULL,
#endif
                             (void* (*)(void *))func,
                             (void *)arg
                             );

#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
    pthread_attr_destroy(&attrs);
#endif
    if (status != 0)
        return -1;

    pthread_detach(th);

#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
    return (long) th;
#else
    return (long) *(long *) &th;
#endif
}

Here is the call graph for this function: