|
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 |
#ifndef MPL_THREAD_SOLARIS_H_INCLUDED
|
|
Packit Service |
c5cf8c |
#define MPL_THREAD_SOLARIS_H_INCLUDED
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <thread.h>
|
|
Packit Service |
c5cf8c |
#include <synch.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
typedef mutex_t MPL_thread_mutex_t;
|
|
Packit Service |
c5cf8c |
typedef cond_t MPL_thread_cond_t;
|
|
Packit Service |
c5cf8c |
typedef thread_t MPL_thread_id_t;
|
|
Packit Service |
c5cf8c |
typedef thread_key_t MPL_thread_tls_t;
|
|
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 |
/*
|
|
Packit Service |
c5cf8c |
* Threads
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPL_thread_exit() \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
thr_exit(NULL); \
|
|
Packit Service |
c5cf8c |
} while (0)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPL_thread_self(id_ptr_) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
*(id_ptr_) = thr_self(); \
|
|
Packit Service |
c5cf8c |
} while (0)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPL_thread_same(id1_ptr_, id2_ptr_, same_ptr_) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
*(same_ptr_) = (*(id1_ptr_) == *(id2_ptr_)) ? TRUE : FALSE; \
|
|
Packit Service |
c5cf8c |
} while (0)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPL_thread_yield thr_yield
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Mutexes
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPL_thread_mutex_create(mutex_ptr_, err_ptr_) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
mutex_init(mutex_ptr_, USYNC_THREAD, NULL); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = mutex_init(mutex_ptr_, USYNC_THREAD, NULL); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to an MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
} while (0)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPL_thread_mutex_destroy(mutex_ptr_, err_ptr_) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
mutex_destroy(mutex_ptr_); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = mutex_destroy(mutex_ptr_); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to an MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
} while (0)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPL_thread_mutex_lock(mutex_ptr_, err_ptr_) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
mutex_lock(mutex_ptr_); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = mutex_lock(mutex_ptr_); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to an MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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__ = mutex_trylock(mutex_ptr_); \
|
|
Packit Service |
c5cf8c |
if (unlikely(err__ != 0 && err__ != EBUSY)) { \
|
|
Packit Service |
c5cf8c |
*(int*)cs_acq_ptr = 0; \
|
|
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 |
if (err_ptr_ != NULL) \
|
|
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 |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
mutex_unlock(mutex_ptr_); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = mutex_unlock(mutex_ptr_); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to an MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
cond_init(cond_ptr_, NULL, NULL); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) == cond_init(cond_ptr_, NULL, NULL); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to an MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
cond_destroy(cond_ptr_); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = cond_destroy(cond_ptr_); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to a MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
cond_wait((cond_ptr_), (mutex_ptr_)); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = cond_wait((cond_ptr_), (mutex_ptr_)); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to a MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
cond_broadcast(cond_ptr_); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = cond_broadcast(cond_ptr_); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to a MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
cond_signal(cond_ptr_); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = cond_signal(cond_ptr_); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to a MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
#define MPL_thread_tls_create(exit_func_ptr_, tls_ptr_, err_ptr_) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
thr_keycreate((tls_ptr_), (exit_func_ptr_)); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = thr_keycreate((tls_ptr_), (exit_func_ptr_)); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to a MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
/* \
|
|
Packit Service |
c5cf8c |
* FIXME: Solaris threads does not have a key destroy. We \
|
|
Packit Service |
c5cf8c |
* need to create equivalent functionality to prevent a \
|
|
Packit Service |
c5cf8c |
* callback from occuring when a thread exits after the TLS is \
|
|
Packit Service |
c5cf8c |
* destroyed. This is the only way to prevent subsystems that \
|
|
Packit Service |
c5cf8c |
* have shutdown from continuing to receive callbacks. \
|
|
Packit Service |
c5cf8c |
*/ \
|
|
Packit Service |
c5cf8c |
if ((err_ptr_) != NULL) { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = MPL_THREAD_SUCCESS; \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
thr_setspecific(*(tls_ptr_), (value_)); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = thr_setspecific(*(tls_ptr_), (value_)); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to a MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
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 |
if ((err_ptr_) == NULL) { \
|
|
Packit Service |
c5cf8c |
thr_setspecific(*(tls_ptr_), (value_ptr_)); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
else { \
|
|
Packit Service |
c5cf8c |
*(err_ptr_) = thr_setspecific(*(tls_ptr_), (value_ptr_)); \
|
|
Packit Service |
c5cf8c |
/* FIXME: convert error to a MPL_THREAD_ERR value */ \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
} while (0)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#endif /* MPL_THREAD_SOLARIS_H_INCLUDED */
|