#define PLOCKSTAT_MUTEX_RELEASE(x, y)
#endif /* PLOCKSTAT */
-extern int __semwait_signal(int, int, int, int, int64_t, int32_t);
extern int _pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *, int);
extern int __unix_conforming;
extern int usenew_mtximpl;
oldval64 |= lcntval;
newval64 = oldval64;
- if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
+ if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
goto retry;
cond->sig = _PTHREAD_NO_SIG;
ret = 0;
volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt;
uint32_t * pmtx = NULL;
uint32_t nlval, ulval;
- int needclearpre = 0, retry_count = 0;
+ int needclearpre = 0, retry_count = 0, uretry_count = 0;
+ int ucountreset = 0;
/* to provide backwards compat for apps using united condtn vars */
if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init))
oldval64 |= lcntval;
newval64 = oldval64;
- if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
+ if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
goto retry;
#if _KSYN_TRACE_
(void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, 0xf1f1f1f1, 0);
return(0);
}
- if (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK)) || is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
+ /* validate to eliminate spurious values, race snapshots */
+ if (is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
/* since ucntval may be newer, just redo */
retry_count++;
if (retry_count > 8192) {
sched_yield();
goto retry;
}
- }
+ } else if (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
+ /* since ucntval may be newer, just redo */
+ uretry_count++;
+ if (uretry_count > 8192) {
+ /*
+ * U value if not used for a while can go out of sync
+ * set this to S value and try one more time.
+ */
+ if (ucountreset != 0)
+ return(EAGAIN);
+ else
+ if (OSAtomicCompareAndSwap32Barrier(ucntval, (scntval & PTHRW_COUNT_MASK), (volatile int32_t *)c_useqcnt) == TRUE) {
+ /* now the U is reset to S value */
+ ucountreset = 1;
+ uretry_count = 0;
+ }
+ }
+ sched_yield();
+ goto retry;
+ }
if (is_seqlower(ucntval & PTHRW_COUNT_MASK, scntval & PTHRW_COUNT_MASK) != 0) {
/* If U < S, set U = S+diff due to intr's TO, etc */
/* set U = L */
ulval = (lcntval & PTHRW_COUNT_MASK);
- if (OSAtomicCompareAndSwap32(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) {
+ if (OSAtomicCompareAndSwap32Barrier(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) {
goto retry;
}
(void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, 0x25, nlval, scntval, updateval, 0);
#endif
- if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
+ if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
goto retry2;
/* if L == S, then reset associated mutex */
uint32_t nlval, ulval=0;
volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt;
uint64_t oldval64, newval64, mugen, cvlsgen, mtid = 0;
- int needclearpre = 0, retry_count = 0;
- int error;
+ int needclearpre = 0, retry_count = 0, uretry_count = 0;
+ int error, ucountreset = 0;
/* to provide backwards compat for apps using united condtn vars */
oldval64 |= lcntval;
newval64 = oldval64;
- if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
+ if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
goto retry;
#if _KSYN_TRACE_
(void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, 0xf1f1f1f1, 0);
return(0);
}
- if (((thread == 0) && (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK)))) || is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
- /* since ucntval may be newer, just redo */
- retry_count++;
- if (retry_count > 8192) {
- return(EAGAIN);
- } else {
+ if (thread == 0) {
+ /* validate to eliminate spurious values, race snapshots */
+ if (is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
+ /* since ucntval may be newer, just redo */
+ retry_count++;
+ if (retry_count > 8192) {
+ return(EAGAIN);
+ } else {
+ sched_yield();
+ goto retry;
+ }
+ } else if (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
+ /* since ucntval may be newer, just redo */
+ uretry_count++;
+ if (uretry_count > 8192) {
+ /*
+ * U value if not used for a while can go out of sync
+ * set this to S value and try one more time.
+ */
+ if (ucountreset != 0)
+ return(EAGAIN);
+ else
+ if (OSAtomicCompareAndSwap32Barrier(ucntval, (scntval & PTHRW_COUNT_MASK), (volatile int32_t *)c_useqcnt) == TRUE) {
+ /* now the U is reset to S value */
+ ucountreset = 1;
+ uretry_count = 0;
+ }
+ }
sched_yield();
goto retry;
}
- }
+ } /* thread == 0 ) */
if (thread == 0) {
/*
ulval = (ucntval & PTHRW_COUNT_MASK) + PTHRW_INC;
}
- if (OSAtomicCompareAndSwap32(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) {
+ if (OSAtomicCompareAndSwap32Barrier(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) {
goto retry;
}
}
(void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, 0x25, nlval, ulval, updateval, 0);
#endif
- if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
+ if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
goto retry2;
/* if L == S, then reset associated mutex */
newval64 = (((uint64_t)ulval) << 32);
newval64 |= nlval;
- if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
+ if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
goto retry;
cond->busy = mutex;
if (isconforming) {
pthread_cleanup_push(cond_cleanup, (void *)cond);
updateval = __psynch_cvwait(ocond, cvlsgen, ucntval, (pthread_mutex_t *)npmtx, mugen, flags, (int64_t)then.tv_sec, (int32_t)then.tv_nsec);
+ _pthread_testcancel(pthread_self(), isconforming);
pthread_cleanup_pop(0);
} else {
updateval = __psynch_cvwait(ocond, cvlsgen, ucntval, (pthread_mutex_t *)npmtx, mugen, flags, (int64_t)then.tv_sec, (int32_t)then.tv_nsec);
oldval64 = (((uint64_t)scntval) << 32);
oldval64 |= lcntval;
newval64 = oldval64;
- if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
+ if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
goto retry;
#if _KSYN_TRACE_
(void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0);
#if _KSYN_TRACE_
(void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, 0xffff, nlval, ulval, 0);
#endif
- if (OSAtomicCompareAndSwap64(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
+ if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
goto retry;
#if _KSYN_TRACE_