diff options
author | Nobuyoshi Nakada <[email protected]> | 2022-07-10 17:56:36 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2022-07-10 17:56:36 +0900 |
commit | ec09ba58d11f9679dade7df1973b60b1f6ebcaf3 (patch) | |
tree | b19bd919c48b627488bb09aa3bf2291a7da17c5c /gc.c | |
parent | 072a8bf76088232ac6e38d689e75323f560fa76d (diff) |
Extract `atomic_inc_wraparound` function
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 22 |
1 files changed, 12 insertions, 10 deletions
@@ -13979,23 +13979,25 @@ rb_raw_obj_info(char *const buff, const size_t buff_size, VALUE obj) static rb_atomic_t obj_info_buffers_index = 0; static char obj_info_buffers[OBJ_INFO_BUFFERS_NUM][OBJ_INFO_BUFFERS_SIZE]; -static char * -obj_info_next_buffer(void) +/* Increments *var atomically and resets *var to 0 when maxval is + * reached. Returns the wraparound old *var value (0...maxval). */ +static rb_atomic_t +atomic_inc_wraparound(rb_atomic_t *var, const rb_atomic_t maxval) { - const rb_atomic_t index = RUBY_ATOMIC_FETCH_ADD(obj_info_buffers_index, 1); - - rb_atomic_t next_index = (index + 1); - if (UNLIKELY(next_index >= OBJ_INFO_BUFFERS_NUM)) { - rb_atomic_t reset_index = next_index % OBJ_INFO_BUFFERS_NUM; - RUBY_ATOMIC_CAS(obj_info_buffers_index, next_index, reset_index); + rb_atomic_t oldval = RUBY_ATOMIC_FETCH_ADD(*var, 1); + if (UNLIKELY(oldval >= maxval - 1)) { // wraparound *var + const rb_atomic_t newval = oldval + 1; + RUBY_ATOMIC_CAS(*var, newval, newval % maxval); + oldval %= maxval; } - return obj_info_buffers[index % OBJ_INFO_BUFFERS_NUM]; + return oldval; } static const char * obj_info(VALUE obj) { - char *const buff = obj_info_next_buffer(); + rb_atomic_t index = atomic_inc_wraparound(&obj_info_buffers_index, OBJ_INFO_BUFFERS_NUM); + char *const buff = obj_info_buffers[index]; return rb_raw_obj_info(buff, OBJ_INFO_BUFFERS_SIZE, obj); } #else |