/* * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2005 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #ifndef ORTE_CONDITION_SPINLOCK_H #define ORTE_CONDITION_SPINLOCK_H #include "orte_config.h" #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_TIME_H #include #endif #if OPAL_HAVE_POSIX_THREADS #include #elif OPAL_HAVE_SOLARIS_THREADS #include #include #endif #include "opal/threads/threads.h" #include "opal/runtime/opal_cr.h" BEGIN_C_DECLS static inline int orte_condition_wait(opal_condition_t *c, opal_mutex_t *m) { int rc = 0; c->c_waiting++; #if OPAL_HAVE_POSIX_THREADS rc = pthread_cond_wait(&c->c_cond, &m->m_lock_pthread); #elif OPAL_HAVE_SOLARIS_THREADS rc = cond_wait(&c->c_cond, &m->m_lock_solaris); #else if (c->c_signaled) { c->c_waiting--; opal_mutex_unlock(m); opal_progress(); OPAL_CR_TEST_CHECKPOINT_READY_STALL(); opal_mutex_lock(m); return 0; } while (c->c_signaled == 0) { opal_mutex_unlock(m); opal_progress(); OPAL_CR_TEST_CHECKPOINT_READY_STALL(); opal_mutex_lock(m); } #endif c->c_signaled--; c->c_waiting--; return rc; } static inline int orte_condition_timedwait(opal_condition_t *c, opal_mutex_t *m, const struct timespec *abstime) { int rc = 0; c->c_waiting++; #if OPAL_HAVE_POSIX_THREADS rc = pthread_cond_timedwait(&c->c_cond, &m->m_lock_pthread, abstime); #elif OPAL_HAVE_SOLARIS_THREADS { /* deal with const-ness */ timestruc_t to; to.tv_sec = abstime->tv_sec; to.tv_nsec = abstime->tv_nsec; rc = cond_timedwait(&c->c_cond, &m->m_lock_solaris, &to); } #else { struct timeval tv; struct timeval absolute; absolute.tv_sec = abstime->tv_sec; absolute.tv_usec = abstime->tv_nsec * 1000; gettimeofday(&tv,NULL); if (c->c_signaled == 0) { do { opal_mutex_unlock(m); opal_progress(); gettimeofday(&tv,NULL); opal_mutex_lock(m); } while (c->c_signaled == 0 && (tv.tv_sec <= absolute.tv_sec || (tv.tv_sec == absolute.tv_sec && tv.tv_usec < absolute.tv_usec))); } } #endif if (c->c_signaled != 0) c->c_signaled--; c->c_waiting--; return rc; } static inline int orte_condition_signal(opal_condition_t *c) { if (c->c_waiting) { c->c_signaled++; #if OPAL_HAVE_POSIX_THREADS pthread_cond_signal(&c->c_cond); #elif OPAL_HAVE_SOLARIS_THREADS cond_signal(&c->c_cond); #endif } return 0; } static inline int orte_condition_broadcast(opal_condition_t *c) { c->c_signaled = c->c_waiting; #if OPAL_HAVE_POSIX_THREADS if( 1 == c->c_waiting ) { pthread_cond_signal(&c->c_cond); } else { pthread_cond_broadcast(&c->c_cond); } #elif OPAL_HAVE_SOLARIS_THREADS cond_broadcast(&c->c_cond); #endif return 0; } END_C_DECLS #endif