diff options
author | Rickard Green <[email protected]> | 2012-02-27 18:45:47 +0100 |
---|---|---|
committer | Rickard Green <[email protected]> | 2012-04-27 12:41:57 +0200 |
commit | 4bcffe41e193bfa03f54f77e2158b3d989a001d0 (patch) | |
tree | 322a8c6f5f7de2458b0fbd274cb5356a76689519 /erts/emulator/beam/erl_alloc_util.c | |
parent | 414f4fb8dc9a188f8148a1f92e5f9125108e170d (diff) | |
download | otp-4bcffe41e193bfa03f54f77e2158b3d989a001d0.tar.gz otp-4bcffe41e193bfa03f54f77e2158b3d989a001d0.tar.bz2 otp-4bcffe41e193bfa03f54f77e2158b3d989a001d0.zip |
Optimize process state changes
Diffstat (limited to 'erts/emulator/beam/erl_alloc_util.c')
-rw-r--r-- | erts/emulator/beam/erl_alloc_util.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index e0d525bdde..62225d3572 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -832,14 +832,14 @@ init_dd_queue(ErtsAllctrDDQueue_t *ddq) static ERTS_INLINE erts_aint_t ddq_managed_thread_enqueue(ErtsAllctrDDQueue_t *ddq, void *ptr) { - erts_aint_t ilast, itmp; + erts_aint_t first_ilast, ilast, itmp; ErtsAllctrDDBlock_t *this = ptr; erts_atomic_init_nob(&this->atmc_next, ERTS_AINT_NULL); /* Enqueue at end of list... */ - ilast = erts_atomic_read_nob(&ddq->tail.data.last); + first_ilast = ilast = erts_atomic_read_nob(&ddq->tail.data.last); while (1) { ErtsAllctrDDBlock_t *last = (ErtsAllctrDDBlock_t *) ilast; itmp = erts_atomic_cmpxchg_mb(&last->atmc_next, @@ -853,8 +853,11 @@ ddq_managed_thread_enqueue(ErtsAllctrDDQueue_t *ddq, void *ptr) /* Move last pointer forward... */ while (1) { if (erts_atomic_read_rb(&this->atmc_next) != ERTS_AINT_NULL) { - /* Someone else will move it forward */ - return erts_atomic_read_rb(&ddq->tail.data.last); + ilast = erts_atomic_read_rb(&ddq->tail.data.last); + if (first_ilast != ilast) { + /* Someone else will move it forward */ + return ilast; + } } itmp = erts_atomic_cmpxchg_mb(&ddq->tail.data.last, (erts_aint_t) this, |