diff --git a/src/cm_concurrency/cm_spinlock.h b/src/cm_concurrency/cm_spinlock.h index 6045291ff153e99d0ebdc71a6aa207e70059f9bd..99250bdb9d39eaa89f83187df34f7888e907fb96 100644 --- a/src/cm_concurrency/cm_spinlock.h +++ b/src/cm_concurrency/cm_spinlock.h @@ -332,6 +332,48 @@ static inline void cm_spin_lock_by_sid(uint32 sid, spinlock_t *lock, spin_statis } } +static inline bool32 cm_spin_timed_lock_by_sid(uint32 sid, spinlock_t *lock, spin_statis_t *stat, uint32 timeout_ticks) +{ + uint32 spin_times = 0, wait_ticks = 0; + uint32 sleep_times = 0; + + if (SECUREC_UNLIKELY(lock == NULL)) { + return CM_TRUE; + } + + for (;;) { +#if defined(__arm__) || defined(__aarch64__) + while (__atomic_load_n(lock, __ATOMIC_SEQ_CST) != 0) { +#else + while (*lock != 0) { +#endif + if (SECUREC_UNLIKELY(wait_ticks >= timeout_ticks)) { + return CM_FALSE; + } + SPIN_STAT_INC(stat, spins); + spin_times++; + if (SECUREC_UNLIKELY(spin_times == GS_SPIN_COUNT)) { + cm_spin_sleep_and_stat(stat); + spin_times = 0; + wait_ticks++; + } + } + + if (SECUREC_LIKELY(cm_spin_set(lock, sid) == 0)) { + break; + } + + SPIN_STAT_INC(stat, fails); + sleep_times++; +#ifndef WIN32 + for (uint32 i = 0; i < sleep_times; i++) { + fas_cpu_pause(); + } +#endif + } + return CM_TRUE; +} + #ifdef __cplusplus } #endif