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

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
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
#ifndef MPL_THREAD_PRIV_H_INCLUDED
Packit Service c5cf8c
#define MPL_THREAD_PRIV_H_INCLUDED
Packit Service c5cf8c
Packit Service c5cf8c
#if MPL_THREAD_PACKAGE_NAME != MPL_THREAD_PACKAGE_NONE && !defined(MPL_TLS)
Packit Service c5cf8c
/* We need to provide a function that will cleanup the storage attached
Packit Service c5cf8c
 * to the key.  */
Packit Service c5cf8c
void MPLI_cleanup_tls(void *a);
Packit Service c5cf8c
Packit Service c5cf8c
/* In the case where the thread level is set in MPI_Init_thread, we
Packit Service c5cf8c
   need a blended version of the non-threaded and the thread-multiple
Packit Service c5cf8c
   definitions.
Packit Service c5cf8c
Packit Service c5cf8c
   The approach is to have TWO MPLI_per_thread_t pointers.  One is local
Packit Service c5cf8c
   (The MPL_THREADPRIV_DECL is used in the routines local definitions),
Packit Service c5cf8c
   as in the threaded version of these macros.  This is set by using a routine
Packit Service c5cf8c
   to get thread-private storage.  The second is a preallocated, extern
Packit Service c5cf8c
   MPLI_per_thread_t struct, as in the single threaded case.  Based on
Packit Service c5cf8c
   whether MPL is initialized with thread safety, one or the other is used.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_THREADPRIV_KEY_CREATE(key, var, err_ptr_, class_)           \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        void *thread_ptr;                                               \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
        MPL_thread_tls_create(MPLI_cleanup_tls, &(key) , err_ptr_);     \
Packit Service c5cf8c
        if (unlikely(*((int *) err_ptr_)))                              \
Packit Service c5cf8c
            break;                                                      \
Packit Service c5cf8c
        thread_ptr = MPL_calloc(1, sizeof(var), class_);                \
Packit Service c5cf8c
        if (unlikely(!thread_ptr)) {                                    \
Packit Service c5cf8c
            *((int *) err_ptr_) = MPL_THREAD_ERROR;                     \
Packit Service c5cf8c
            break;                                                      \
Packit Service c5cf8c
        }                                                               \
Packit Service c5cf8c
        MPL_thread_tls_set(&(key), thread_ptr, err_ptr_);               \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_THREADPRIV_KEY_GET_ADDR(is_threaded, key, var, addr, err_ptr_)  \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        if (is_threaded) {                                              \
Packit Service c5cf8c
            void *thread_ptr;                                           \
Packit Service c5cf8c
            MPL_thread_tls_get(&(key), &thread_ptr, err_ptr_);          \
Packit Service c5cf8c
            if (unlikely(*((int *) err_ptr_)))                          \
Packit Service c5cf8c
                break;                                                  \
Packit Service c5cf8c
            if (!thread_ptr) {                                          \
Packit Service c5cf8c
                thread_ptr = MPL_calloc(1, sizeof(var), MPL_MEM_OTHER); \
Packit Service c5cf8c
                if (unlikely(!thread_ptr)) {                            \
Packit Service c5cf8c
                    *((int *) err_ptr_) = MPL_THREAD_ERROR;             \
Packit Service c5cf8c
                    break;                                              \
Packit Service c5cf8c
                }                                                       \
Packit Service c5cf8c
                MPL_thread_tls_set(&(key), thread_ptr, err_ptr_);       \
Packit Service c5cf8c
                if (unlikely(*((int *) err_ptr_)))                      \
Packit Service c5cf8c
                    break;                                              \
Packit Service c5cf8c
            }                                                           \
Packit Service c5cf8c
            addr = thread_ptr;                                          \
Packit Service c5cf8c
        }                                                               \
Packit Service c5cf8c
        else {                                                          \
Packit Service c5cf8c
            addr = &(var);                                              \
Packit Service c5cf8c
        }                                                               \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPL_THREADPRIV_KEY_DESTROY(key, err_ptr_)       \
Packit Service c5cf8c
    do {                                                \
Packit Service c5cf8c
        void *thread_ptr;                               \
Packit Service c5cf8c
                                                        \
Packit Service c5cf8c
        MPL_thread_tls_get(&(key), &thread_ptr, err_ptr_); \
Packit Service c5cf8c
        if (unlikely(*((int *) err_ptr_)))                 \
Packit Service c5cf8c
            break;                                      \
Packit Service c5cf8c
                                                        \
Packit Service c5cf8c
        if (thread_ptr)                                 \
Packit Service c5cf8c
            MPL_free(thread_ptr);                       \
Packit Service c5cf8c
                                                        \
Packit Service c5cf8c
        MPL_thread_tls_set(&(key), NULL, err_ptr_);     \
Packit Service c5cf8c
        if (unlikely(*((int *) err_ptr_)))              \
Packit Service c5cf8c
            break;                                      \
Packit Service c5cf8c
                                                        \
Packit Service c5cf8c
        MPL_thread_tls_destroy(&(key), err_ptr_);       \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#else /* MPL_THREAD_PACKAGE_NAME != MPL_THREAD_PACKAGE_NONE || defined(MPL_TLS) */
Packit Service c5cf8c
Packit Service c5cf8c
/* We have proper thread-local storage (TLS) support from the compiler, which
Packit Service c5cf8c
 * should yield the best performance and simplest code, so we'll use that. */
Packit Service c5cf8c
#define MPL_THREADPRIV_KEY_CREATE(...)
Packit Service c5cf8c
#define MPL_THREADPRIV_KEY_GET_ADDR(is_threaded, key, var, addr, err_ptr_) \
Packit Service c5cf8c
    do {                                                                \
Packit Service c5cf8c
        addr = &(var);                                                  \
Packit Service c5cf8c
        *((int *) err_ptr_) = MPL_THREAD_SUCCESS;                       \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
#define MPL_THREADPRIV_KEY_DESTROY(...)
Packit Service c5cf8c
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
#endif /* MPL_THREAD_PRIV_H_INCLUDED */