/* * Copyright (C) by Argonne National Laboratory * See COPYRIGHT in top-level directory */ /* * Interprocess Mutex */ #ifndef MPL_PROC_MUTEX_POSIX_H_INCLUDED #define MPL_PROC_MUTEX_POSIX_H_INCLUDED #include #include typedef pthread_mutex_t MPL_proc_mutex_t; #if defined(MPL_NEEDS_PTHREAD_MUTEXATTR_SETTYPE_DECL) int pthread_mutexattr_settype(pthread_mutexattr_t * attr, int kind); #endif /* MPL_NEEDS_PTHREAD_MUTEXATTR_SETTYPE_DECL */ #ifdef MPL_HAVE_PTHREAD_MUTEXATTR_SETPSHARED static inline int MPL_proc_mutex_enabled(void) { int mutex_err; pthread_mutexattr_t attr; /* Test for PTHREAD_PROCESS_SHARED support. Some platforms do not support * this capability even though it is a part of the pthreads core API (e.g., * FreeBSD does not support this as of version 9.1) */ pthread_mutexattr_init(&attr); mutex_err = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); pthread_mutexattr_destroy(&attr); return !mutex_err; /* if no error, return 1 */ } #define PROC_MUTEX_EINTR_PRINT_BREAK(func_name, err__, err_ptr_) { \ MPL_internal_sys_error_printf(func_name, err__, \ " %s:%d\n", __FILE__, __LINE__); \ *(int *)(err_ptr_) = MPL_ERR_PROC_MUTEX_EINTR; \ break; /* do not wrap by do-while (0) to break from caller's loop.*/ \ } #ifdef MPL_PTHREAD_MUTEX_ERRORCHECK_VALUE #define PROC_MUTEX_SET_MUTEXATTR_SETTYPE \ do { \ err__ = pthread_mutexattr_settype(&attr__, MPL_PTHREAD_MUTEX_ERRORCHECK_VALUE); \ } while (0) #else #define PROC_MUTEX_SET_MUTEXATTR_SETTYPE do {} while (0) #endif /* MPL_PTHREAD_MUTEX_ERRORCHECK_VALUE */ #define MPL_proc_mutex_create(mutex_ptr_, err_ptr_) \ do { \ int err__; \ pthread_mutexattr_t attr__; \ *(int *)(err_ptr_) = MPL_SUCCESS; \ \ err__ = pthread_mutexattr_init(&attr__); \ if (unlikely(err__)) \ PROC_MUTEX_EINTR_PRINT_BREAK("pthread_mutexattr_init", err__, err_ptr_); \ err__ = pthread_mutexattr_setpshared(&attr__, PTHREAD_PROCESS_SHARED); \ if (unlikely(err__)) \ PROC_MUTEX_EINTR_PRINT_BREAK("pthread_mutexattr_setpshared", err__, err_ptr_); \ PROC_MUTEX_SET_MUTEXATTR_SETTYPE; \ if (unlikely(err__)) \ PROC_MUTEX_EINTR_PRINT_BREAK("pthread_mutexattr_settype", err__, err_ptr_); \ err__ = pthread_mutex_init(mutex_ptr_, &attr__); \ if (unlikely(err__)) \ PROC_MUTEX_EINTR_PRINT_BREAK("pthread_mutex_init", err__, err_ptr_); \ err__ = pthread_mutexattr_destroy(&attr__); \ if (unlikely(err__)) \ PROC_MUTEX_EINTR_PRINT_BREAK("pthread_mutexattr_destroy", err__, err_ptr_); \ } while (0) #define MPL_proc_mutex_destroy(mutex_ptr_, err_ptr_) \ do { \ int err__; \ *(int *)(err_ptr_) = MPL_SUCCESS; \ err__ = pthread_mutex_destroy(mutex_ptr_); \ if (unlikely(err__)) \ PROC_MUTEX_EINTR_PRINT_BREAK("pthread_mutex_destroy", err__, err_ptr_); \ } while (0) #define MPL_proc_mutex_lock(mutex_ptr_, err_ptr_) \ do { \ int err__; \ *(int *)(err_ptr_) = MPL_SUCCESS; \ err__ = pthread_mutex_lock(mutex_ptr_); \ if (unlikely(err__)) \ PROC_MUTEX_EINTR_PRINT_BREAK("pthread_mutex_lock", err__, err_ptr_); \ } while (0) #define MPL_proc_mutex_unlock(mutex_ptr_, err_ptr_) \ do { \ int err__; \ *(int *)(err_ptr_) = MPL_SUCCESS; \ err__ = pthread_mutex_unlock(mutex_ptr_); \ if (unlikely(err__)) \ PROC_MUTEX_EINTR_PRINT_BREAK("pthread_mutex_unlock", err__, err_ptr_); \ } while (0) #else static inline int MPL_proc_mutex_enabled(void) { return 0; /* always disabled */ } #define MPL_proc_mutex_create(mutex_ptr_, err_ptr_) { *((int*)err_ptr_) = MPL_ERR_PROC_MUTEX_EINVAL;} #define MPL_proc_mutex_destroy(mutex_ptr_, err_ptr_) { *((int*)err_ptr_) = MPL_ERR_PROC_MUTEX_EINVAL;} #define MPL_proc_mutex_lock(mutex_ptr_, err_ptr_) { *((int*)err_ptr_) = MPL_ERR_PROC_MUTEX_EINVAL;} #define MPL_proc_mutex_unlock(mutex_ptr_, err_ptr_) { *((int*)err_ptr_) = MPL_ERR_PROC_MUTEX_EINVAL;} #endif /* MPL_HAVE_PTHREAD_MUTEXATTR_SETPSHARED */ #endif /* MPL_PROC_MUTEX_POSIX_H_INCLUDED */