Blame src/mpi/romio/mpl/include/mpl_thread_posix.h

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *
Packit Service c5cf8c
 *  (C) 2001 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 * Threads
Packit Service c5cf8c
 */
Packit Service c5cf8c
#ifndef MPL_THREAD_POSIX_H_INCLUDED
Packit Service c5cf8c
#define MPL_THREAD_POSIX_H_INCLUDED
Packit Service c5cf8c
Packit Service c5cf8c
#include "mpl.h"        /* for MPL_sched_yield */
Packit Service c5cf8c
Packit Service c5cf8c
#include <errno.h>
Packit Service c5cf8c
#include <pthread.h>
Packit Service c5cf8c
Packit Service c5cf8c
typedef pthread_mutex_t MPL_thread_mutex_t;
Packit Service c5cf8c
typedef pthread_cond_t MPL_thread_cond_t;
Packit Service c5cf8c
typedef pthread_t MPL_thread_id_t;
Packit Service c5cf8c
typedef pthread_key_t MPL_thread_tls_t;
Packit Service c5cf8c
Packit Service c5cf8c
#if defined(MPL_NEEDS_PTHREAD_MUTEXATTR_SETTYPE_DECL)
Packit Service c5cf8c
int pthread_mutexattr_settype(pthread_mutexattr_t * attr, int kind);
Packit Service c5cf8c
#endif /* MPL_NEEDS_PTHREAD_MUTEXATTR_SETTYPE_DECL */
Packit Service c5cf8c
Packit Service c5cf8c
typedef void (*MPL_thread_func_t) (void *data);
Packit Service c5cf8c
void MPL_thread_create(MPL_thread_func_t func, void *data, MPL_thread_id_t * id, int *err);
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_exit()                       \
Packit Service c5cf8c
    do {                                        \
Packit Service c5cf8c
        pthread_exit(NULL);                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_self(id_)                    \
Packit Service c5cf8c
    do {                                        \
Packit Service c5cf8c
        *(id_) = pthread_self();                \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_same(id1_, id2_, same_)                              \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        *(same_) = pthread_equal(*(id1_), *(id2_)) ? TRUE : FALSE;      \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_yield MPL_sched_yield
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *    Mutexes
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/* FIXME: mutex creation and destruction should be implemented as routines
Packit Service c5cf8c
   because there is no reason to use macros (these are not on the performance
Packit Service c5cf8c
   critical path).  Making these macros requires that any code that might use
Packit Service c5cf8c
   these must load all of the pthread.h (or other thread library) support.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/* FIXME: using constant initializer if available */
Packit Service c5cf8c
Packit Service c5cf8c
/* FIXME: convert errors to an MPL_THREAD_ERR value */
Packit Service c5cf8c
Packit Service c5cf8c
#if !defined(MPL_PTHREAD_MUTEX_ERRORCHECK_VALUE)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_mutex_create(mutex_ptr_, err_ptr_)                   \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_mutex_init(mutex_ptr_, NULL);                   \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_mutex_init", err__,  \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#else /* defined(MPL_PTHREAD_MUTEX_ERRORCHECK_VALUE) */
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_mutex_create(mutex_ptr_, err_ptr_)                   \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
        pthread_mutexattr_t attr__;                                     \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        pthread_mutexattr_init(&attr__);                                \
Packit Service c5cf8c
        pthread_mutexattr_settype(&attr__, MPL_PTHREAD_MUTEX_ERRORCHECK_VALUE); \
Packit Service c5cf8c
        err__ = pthread_mutex_init(mutex_ptr_, &attr__);                \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_mutex_init", err__,  \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#endif /* defined(MPL_PTHREAD_MUTEX_ERRORCHECK_VALUE) */
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_mutex_destroy(mutex_ptr_, err_ptr_)                  \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_mutex_destroy(mutex_ptr_);                      \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_mutex_destroy", err__, \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_mutex_lock(mutex_ptr_, err_ptr_)                     \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
        err__ = pthread_mutex_lock(mutex_ptr_);                         \
Packit Service c5cf8c
        if (unlikely(err__)) {                                          \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_mutex_lock", err__,  \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
        }                                                               \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_mutex_trylock(mutex_ptr_, err_ptr_, cs_acq_ptr)      \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
        *(int*)cs_acq_ptr = 1;                                          \
Packit Service c5cf8c
        err__ = pthread_mutex_trylock(mutex_ptr_);                      \
Packit Service c5cf8c
        if (unlikely(err__ != 0 && err__ != EBUSY)) {                   \
Packit Service c5cf8c
            *(int*)cs_acq_ptr = 0;                                      \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_mutex_trylock", err__,  \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
        }                                                               \
Packit Service c5cf8c
        else {                                                          \
Packit Service c5cf8c
            if (unlikely(err__ != 0))                                   \
Packit Service c5cf8c
                *(int*)cs_acq_ptr = 0;                                  \
Packit Service c5cf8c
             err__ = 0;                                                 \
Packit Service c5cf8c
        }                                                               \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_mutex_unlock(mutex_ptr_, err_ptr_)                   \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_mutex_unlock(mutex_ptr_);                       \
Packit Service c5cf8c
        if (unlikely(err__)) {                                          \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_mutex_unlock", err__, \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
        }                                                               \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 * Condition Variables
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_cond_create(cond_ptr_, err_ptr_)                     \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_cond_init((cond_ptr_), NULL);                   \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_cond_init", err__,   \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_cond_destroy(cond_ptr_, err_ptr_)                    \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_cond_destroy(cond_ptr_);                        \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_cond_destroy", err__, \
Packit Service c5cf8c
            "    %s:%d\n", __FILE__, __LINE__);                         \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_cond_wait(cond_ptr_, mutex_ptr_, err_ptr_)           \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        /* The latest pthread specification says that cond_wait         \
Packit Service c5cf8c
         * routines aren't allowed to return EINTR, but some of the     \
Packit Service c5cf8c
         * older implementations still do. */                           \
Packit Service c5cf8c
        do {                                                            \
Packit Service c5cf8c
            err__ = pthread_cond_wait((cond_ptr_), mutex_ptr_);         \
Packit Service c5cf8c
        } while (err__ == EINTR);                                       \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_cond_wait", err__,   \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_cond_broadcast(cond_ptr_, err_ptr_)                  \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_cond_broadcast(cond_ptr_);                      \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_cond_broadcast", err__, \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_cond_signal(cond_ptr_, err_ptr_)                     \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_cond_signal(cond_ptr_);                         \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_cond_signal", err__, \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 * Thread Local Storage
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_tls_create(exit_func_ptr_, tls_ptr_, err_ptr_)       \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_key_create((tls_ptr_), (exit_func_ptr_));       \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_key_create", err__,  \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_tls_destroy(tls_ptr_, err_ptr_)                      \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_key_delete(*(tls_ptr_));                        \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_key_delete", err__,  \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_tls_set(tls_ptr_, value_, err_ptr_)                  \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        int err__;                                                      \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        err__ = pthread_setspecific(*(tls_ptr_), (value_));             \
Packit Service c5cf8c
        if (unlikely(err__))                                            \
Packit Service c5cf8c
            MPL_internal_sys_error_printf("pthread_setspecific", err__, \
Packit Service c5cf8c
                                          "    %s:%d\n", __FILE__, __LINE__); \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        *(int *)(err_ptr_) = err__;                                     \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_thread_tls_get(tls_ptr_, value_ptr_, err_ptr_)      \
Packit Service c5cf8c
    do {                                                        \
Packit Service c5cf8c
        *(value_ptr_) = pthread_getspecific(*(tls_ptr_));       \
Packit Service c5cf8c
                                                                \
Packit Service c5cf8c
        *(int *)(err_ptr_) = MPL_THREAD_SUCCESS;                \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#endif /* MPL_THREAD_POSIX_H_INCLUDED */