#ifndef __SYNCH_INTERNAL_H__
#define __SYNCH_INTERNAL_H__
#define _PTHREAD_MTX_OPT_PSHARED 0x010
#define _PTHREAD_MTX_OPT_NOTIFY 0x1000
#define _PTHREAD_MTX_OPT_MUTEX 0x2000
#define PTHRW_COUNT_SHIFT 8
#define PTHRW_INC (1 << PTHRW_COUNT_SHIFT)
#define PTHRW_BIT_MASK ((1 << PTHRW_COUNT_SHIFT) - 1)
#define PTHRW_COUNT_MASK ((uint32_t)~PTHRW_BIT_MASK)
#define PTHRW_MAX_READERS PTHRW_COUNT_MASK
#define PTH_RWL_KBIT 0x01 // cannot acquire in user mode
#define PTH_RWL_EBIT 0x02 // exclusive lock in progress
#define PTH_RWL_WBIT 0x04 // write waiters pending in kernel
#define PTH_RWL_PBIT 0x04 // prepost (cv) pending in kernel
#define PTH_RWL_MTX_WAIT 0x20 // in cvar in mutex wait
#define PTH_RWL_RBIT 0x40 // reader pending in kernel (not used)
#define PTH_RWL_MBIT 0x40 // overlapping grants from kernel
#define PTH_RWL_IBIT 0x80 // lock reset, held until first successful unlock
#define PTHRW_RWL_INIT PTH_RWL_IBIT // reset on the lock bits (U)
#define PTHRW_RWLOCK_INIT (PTH_RWL_IBIT | PTH_RWL_RBIT) // reset on the lock bits (U)
#define PTH_RWLOCK_RESET_RBIT ((uint32_t)~PTH_RWL_RBIT)
#define PTH_RWS_SBIT 0x01 // kernel transition seq not set yet
#define PTH_RWS_IBIT 0x02 // Sequence is not set on return from kernel
#define PTH_RWS_CV_CBIT PTH_RWS_SBIT // kernel has cleared all info w.r.s.t CV
#define PTH_RWS_CV_PBIT PTH_RWS_IBIT // kernel has prepost/fake structs only,no waiters
#define PTH_RWS_CV_BITSALL (PTH_RWS_CV_CBIT | PTH_RWS_CV_PBIT)
#define PTH_RWS_CV_MBIT PTH_RWL_MBIT // to indicate prepost return from kernel
#define PTH_RWS_CV_RESET_PBIT ((uint32_t)~PTH_RWS_CV_PBIT)
#define PTH_RWS_WSVBIT 0x04 // save W bit
#define PTHRW_RWS_SAVEMASK (PTH_RWS_WSVBIT) // save bits mask
#define PTHRW_RWS_INIT PTH_RWS_SBIT // reset on the lock bits (U)
#define PTHRW_SW_Reset_BIT_MASK (PTHRW_BIT_MASK & ~PTH_RWS_SBIT) // All bits except the S bit
#define PTHRW_KERN_PROCESS_SHARED 0x10
#define PTHRW_KERN_PROCESS_PRIVATE 0x20
#define PTHREAD_MTX_TID_SWITCHING (uint64_t)-1
#define can_rwl_readinuser(x) (((x) & (PTH_RWL_WBIT | PTH_RWL_KBIT)) == 0)
#define is_rwl_ebit_set(x) (((x) & PTH_RWL_EBIT) != 0)
#define is_rwl_wbit_set(x) (((x) & PTH_RWL_WBIT) != 0)
#define is_rwl_ebit_clear(x) (((x) & PTH_RWL_EBIT) == 0)
#define is_rwl_readoverlap(x) (((x) & PTH_RWL_MBIT) != 0)
#define is_rws_setseq(x) (((x) & PTH_RWS_SBIT))
#define is_rws_setunlockinit(x) (((x) & PTH_RWS_IBIT))
static inline int
is_seqlower(uint32_t x, uint32_t y)
{
x &= PTHRW_COUNT_MASK;
y &= PTHRW_COUNT_MASK;
if (x < y) {
return ((y - x) < (PTHRW_MAX_READERS / 2));
} else {
return ((x - y) > (PTHRW_MAX_READERS / 2));
}
}
static inline int
is_seqlower_eq(uint32_t x, uint32_t y)
{
if ((x & PTHRW_COUNT_MASK) == (y & PTHRW_COUNT_MASK)) {
return 1;
} else {
return is_seqlower(x, y);
}
}
static inline int
is_seqhigher(uint32_t x, uint32_t y)
{
x &= PTHRW_COUNT_MASK;
y &= PTHRW_COUNT_MASK;
if (x > y) {
return ((x - y) < (PTHRW_MAX_READERS / 2));
} else {
return ((y - x) > (PTHRW_MAX_READERS / 2));
}
}
static inline int
is_seqhigher_eq(uint32_t x, uint32_t y)
{
if ((x & PTHRW_COUNT_MASK) == (y & PTHRW_COUNT_MASK)) {
return 1;
} else {
return is_seqhigher(x,y);
}
}
static inline int
diff_genseq(uint32_t x, uint32_t y)
{
x &= PTHRW_COUNT_MASK;
y &= PTHRW_COUNT_MASK;
if (x == y) {
return 0;
} else if (x > y) {
return x - y;
} else {
return ((PTHRW_MAX_READERS - y) + x + PTHRW_INC);
}
}
static inline int
find_diff(uint32_t upto, uint32_t lowest)
{
uint32_t diff;
if (upto == lowest)
return(0);
#if 0
diff = diff_genseq(upto, lowest);
#else
if (is_seqlower(upto, lowest) != 0)
diff = diff_genseq(lowest, upto);
else
diff = diff_genseq(upto, lowest);
#endif
diff = (diff >> PTHRW_COUNT_SHIFT);
return(diff);
}
#endif