X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Finclude%2Fgeneric%2Frte_rwlock.h;h=da9bc3e9c0e2fd98d2a040f1daae91de14555b9d;hb=df3ff6be2b33faea3edf3c112b9bdc5b74d6f684;hp=5751a0e6d5b9fb6d5e2ce88f057cee570829aef9;hpb=1587d36e22d0cf0e037a104e1e851acefd6597f0;p=dpdk.git diff --git a/lib/librte_eal/common/include/generic/rte_rwlock.h b/lib/librte_eal/common/include/generic/rte_rwlock.h index 5751a0e6d5..da9bc3e9c0 100644 --- a/lib/librte_eal/common/include/generic/rte_rwlock.h +++ b/lib/librte_eal/common/include/generic/rte_rwlock.h @@ -64,17 +64,49 @@ rte_rwlock_read_lock(rte_rwlock_t *rwl) int success = 0; while (success == 0) { - x = rwl->cnt; + x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED); /* write lock is held */ if (x < 0) { rte_pause(); continue; } - success = rte_atomic32_cmpset((volatile uint32_t *)&rwl->cnt, - (uint32_t)x, (uint32_t)(x + 1)); + success = __atomic_compare_exchange_n(&rwl->cnt, &x, x + 1, 1, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); } } +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * try to take a read lock. + * + * @param rwl + * A pointer to a rwlock structure. + * @return + * - zero if the lock is successfully taken + * - -EBUSY if lock could not be acquired for reading because a + * writer holds the lock + */ +__rte_experimental +static inline int +rte_rwlock_read_trylock(rte_rwlock_t *rwl) +{ + int32_t x; + int success = 0; + + while (success == 0) { + x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED); + /* write lock is held */ + if (x < 0) + return -EBUSY; + success = __atomic_compare_exchange_n(&rwl->cnt, &x, x + 1, 1, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); + } + + return 0; +} + /** * Release a read lock. * @@ -84,7 +116,34 @@ rte_rwlock_read_lock(rte_rwlock_t *rwl) static inline void rte_rwlock_read_unlock(rte_rwlock_t *rwl) { - rte_atomic32_dec((rte_atomic32_t *)(intptr_t)&rwl->cnt); + __atomic_fetch_sub(&rwl->cnt, 1, __ATOMIC_RELEASE); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * try to take a write lock. + * + * @param rwl + * A pointer to a rwlock structure. + * @return + * - zero if the lock is successfully taken + * - -EBUSY if lock could not be acquired for writing because + * it was already locked for reading or writing + */ +__rte_experimental +static inline int +rte_rwlock_write_trylock(rte_rwlock_t *rwl) +{ + int32_t x; + + x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED); + if (x != 0 || __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) == 0) + return -EBUSY; + + return 0; } /** @@ -100,14 +159,14 @@ rte_rwlock_write_lock(rte_rwlock_t *rwl) int success = 0; while (success == 0) { - x = rwl->cnt; + x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED); /* a lock is held */ if (x != 0) { rte_pause(); continue; } - success = rte_atomic32_cmpset((volatile uint32_t *)&rwl->cnt, - 0, (uint32_t)-1); + success = __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); } } @@ -120,7 +179,7 @@ rte_rwlock_write_lock(rte_rwlock_t *rwl) static inline void rte_rwlock_write_unlock(rte_rwlock_t *rwl) { - rte_atomic32_inc((rte_atomic32_t *)(intptr_t)&rwl->cnt); + __atomic_store_n(&rwl->cnt, 0, __ATOMIC_RELEASE); } /**