mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fixed race in dtoa [Bug #17612]
Fixed the race condition when replacing `freelist` entry with its chained next element. At acquiring an entry, hold the entry once with the special value, then release by replacing it with the next element again after acquired. If another thread is holding the same entry at that time, spinning until the entry gets released. Co-Authored-By: Koichi Sasada <ko1@atdot.net>
This commit is contained in:
parent
ad2c7f8a1e
commit
3acc81d9e4
Notes:
git
2021-02-10 19:45:09 +09:00
2 changed files with 21 additions and 3 deletions
|
@ -158,6 +158,17 @@ assert_equal '[[:e1, 1], [:e2, 2]]', %q{
|
|||
a #
|
||||
}
|
||||
|
||||
# dtoa race condition
|
||||
assert_equal '[:ok, :ok, :ok]', %q{
|
||||
n = 3
|
||||
n.times.map{
|
||||
Ractor.new{
|
||||
10_000.times{ rand.to_s }
|
||||
:ok
|
||||
}
|
||||
}.map(&:take)
|
||||
}
|
||||
|
||||
###
|
||||
###
|
||||
# Ractor still has several memory corruption so skip huge number of tests
|
||||
|
|
|
@ -526,6 +526,8 @@ typedef struct Bigint Bigint;
|
|||
|
||||
static Bigint *freelist[Kmax+1];
|
||||
|
||||
#define BLOCKING_BIGINT ((Bigint *)(-1))
|
||||
|
||||
static Bigint *
|
||||
Balloc(int k)
|
||||
{
|
||||
|
@ -541,8 +543,10 @@ Balloc(int k)
|
|||
rv = freelist[k];
|
||||
while (rv) {
|
||||
Bigint *rvn = rv;
|
||||
rv = ATOMIC_PTR_CAS(freelist[k], rv, rv->next);
|
||||
if (LIKELY(rvn == rv)) {
|
||||
rv = ATOMIC_PTR_CAS(freelist[k], rv, BLOCKING_BIGINT);
|
||||
if (LIKELY(rv != BLOCKING_BIGINT && rvn == rv)) {
|
||||
rvn = ATOMIC_PTR_CAS(freelist[k], BLOCKING_BIGINT, rv->next);
|
||||
assert(rvn == BLOCKING_BIGINT);
|
||||
ASSUME(rv);
|
||||
break;
|
||||
}
|
||||
|
@ -589,7 +593,10 @@ Bfree(Bigint *v)
|
|||
}
|
||||
ACQUIRE_DTOA_LOCK(0);
|
||||
do {
|
||||
vn = v->next = freelist[v->k];
|
||||
do {
|
||||
vn = ATOMIC_PTR_CAS(freelist[v->k], 0, 0);
|
||||
} while (UNLIKELY(vn == BLOCKING_BIGINT));
|
||||
v->next = vn;
|
||||
} while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn));
|
||||
FREE_DTOA_LOCK(0);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue