Summary:
The signed counters used in a couple of places can in theory (and practice)
overflow, yielding UB. Use unsigned counters instead.
Reviewed By: luciang, philippv
Differential Revision:
D5818606
fbshipit-source-id:
c5928b779e76b309b00b7f6308a220e2bf6cbf79
// Lockable Concept
void lock() {
// Lockable Concept
void lock() {
+ uint_fast32_t count = 0;
while (!LIKELY(try_lock())) {
if (++count > 1000) std::this_thread::yield();
}
while (!LIKELY(try_lock())) {
if (++count > 1000) std::this_thread::yield();
}
// SharedLockable Concept
void lock_shared() {
// SharedLockable Concept
void lock_shared() {
+ uint_fast32_t count = 0;
while (!LIKELY(try_lock_shared())) {
if (++count > 1000) std::this_thread::yield();
}
while (!LIKELY(try_lock_shared())) {
if (++count > 1000) std::this_thread::yield();
}
// UpgradeLockable Concept
void lock_upgrade() {
// UpgradeLockable Concept
void lock_upgrade() {
+ uint_fast32_t count = 0;
while (!try_lock_upgrade()) {
if (++count > 1000) std::this_thread::yield();
}
while (!try_lock_upgrade()) {
if (++count > 1000) std::this_thread::yield();
}
// cores allocated to this process. This is less likely than the
// corresponding situation in lock_shared(), but we still want to
// avoid it
// cores allocated to this process. This is less likely than the
// corresponding situation in lock_shared(), but we still want to
// avoid it
+ uint_fast32_t count = 0;
QuarterInt val = __sync_fetch_and_add(&ticket.users, 1);
while (val != load_acquire(&ticket.write)) {
asm_volatile_pause();
QuarterInt val = __sync_fetch_and_add(&ticket.users, 1);
while (val != load_acquire(&ticket.write)) {
asm_volatile_pause();
// std::this_thread::yield() is important here because we can't grab the
// shared lock if there is a pending writeLockAggressive, so we
// need to let threads that already have a shared lock complete
// std::this_thread::yield() is important here because we can't grab the
// shared lock if there is a pending writeLockAggressive, so we
// need to let threads that already have a shared lock complete
+ uint_fast32_t count = 0;
while (!LIKELY(try_lock_shared())) {
asm_volatile_pause();
if (UNLIKELY((++count & 1023) == 0)) std::this_thread::yield();
while (!LIKELY(try_lock_shared())) {
asm_volatile_pause();
if (UNLIKELY((++count & 1023) == 0)) std::this_thread::yield();