Commit 7a3f4d06 authored by Marcus Holland-Moritz's avatar Marcus Holland-Moritz Committed by Facebook Github Bot

Fix UB from signed integer overflow in RWSpinLock

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
parent 1c6da6e3
...@@ -190,7 +190,7 @@ class RWSpinLock { ...@@ -190,7 +190,7 @@ class RWSpinLock {
// Lockable Concept // Lockable Concept
void lock() { void lock() {
int count = 0; uint_fast32_t count = 0;
while (!LIKELY(try_lock())) { while (!LIKELY(try_lock())) {
if (++count > 1000) std::this_thread::yield(); if (++count > 1000) std::this_thread::yield();
} }
...@@ -204,7 +204,7 @@ class RWSpinLock { ...@@ -204,7 +204,7 @@ class RWSpinLock {
// SharedLockable Concept // SharedLockable Concept
void lock_shared() { void lock_shared() {
int count = 0; uint_fast32_t count = 0;
while (!LIKELY(try_lock_shared())) { while (!LIKELY(try_lock_shared())) {
if (++count > 1000) std::this_thread::yield(); if (++count > 1000) std::this_thread::yield();
} }
...@@ -222,7 +222,7 @@ class RWSpinLock { ...@@ -222,7 +222,7 @@ class RWSpinLock {
// UpgradeLockable Concept // UpgradeLockable Concept
void lock_upgrade() { void lock_upgrade() {
int count = 0; uint_fast32_t count = 0;
while (!try_lock_upgrade()) { while (!try_lock_upgrade()) {
if (++count > 1000) std::this_thread::yield(); if (++count > 1000) std::this_thread::yield();
} }
...@@ -603,7 +603,7 @@ class RWTicketSpinLockT { ...@@ -603,7 +603,7 @@ class RWTicketSpinLockT {
// cores allocated to this process. This is less likely than the // cores allocated to this process. This is less likely than the
// corresponding situation in lock_shared(), but we still want to // corresponding situation in lock_shared(), but we still want to
// avoid it // avoid it
int count = 0; uint_fast32_t count = 0;
QuarterInt val = __sync_fetch_and_add(&ticket.users, 1); QuarterInt val = __sync_fetch_and_add(&ticket.users, 1);
while (val != load_acquire(&ticket.write)) { while (val != load_acquire(&ticket.write)) {
asm_volatile_pause(); asm_volatile_pause();
...@@ -653,7 +653,7 @@ class RWTicketSpinLockT { ...@@ -653,7 +653,7 @@ class RWTicketSpinLockT {
// std::this_thread::yield() is important here because we can't grab the // std::this_thread::yield() is important here because we can't grab the
// shared lock if there is a pending writeLockAggressive, so we // shared lock if there is a pending writeLockAggressive, so we
// need to let threads that already have a shared lock complete // need to let threads that already have a shared lock complete
int count = 0; uint_fast32_t count = 0;
while (!LIKELY(try_lock_shared())) { while (!LIKELY(try_lock_shared())) {
asm_volatile_pause(); asm_volatile_pause();
if (UNLIKELY((++count & 1023) == 0)) std::this_thread::yield(); if (UNLIKELY((++count & 1023) == 0)) std::this_thread::yield();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment