Extract `atomic_inc_wraparound` function

This commit is contained in:
Nobuyoshi Nakada 2022-07-10 17:56:36 +09:00
Родитель 072a8bf760
Коммит ec09ba58d1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7CD2805BFA3770C6
1 изменённых файлов: 12 добавлений и 10 удалений

22
gc.c
Просмотреть файл

@ -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 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_buffers[OBJ_INFO_BUFFERS_NUM][OBJ_INFO_BUFFERS_SIZE];
static char * /* Increments *var atomically and resets *var to 0 when maxval is
obj_info_next_buffer(void) * 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 oldval = RUBY_ATOMIC_FETCH_ADD(*var, 1);
if (UNLIKELY(oldval >= maxval - 1)) { // wraparound *var
rb_atomic_t next_index = (index + 1); const rb_atomic_t newval = oldval + 1;
if (UNLIKELY(next_index >= OBJ_INFO_BUFFERS_NUM)) { RUBY_ATOMIC_CAS(*var, newval, newval % maxval);
rb_atomic_t reset_index = next_index % OBJ_INFO_BUFFERS_NUM; oldval %= maxval;
RUBY_ATOMIC_CAS(obj_info_buffers_index, next_index, reset_index);
} }
return obj_info_buffers[index % OBJ_INFO_BUFFERS_NUM]; return oldval;
} }
static const char * static const char *
obj_info(VALUE obj) 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); return rb_raw_obj_info(buff, OBJ_INFO_BUFFERS_SIZE, obj);
} }
#else #else