summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2022-07-07 00:28:45 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2022-07-10 13:11:06 +0900
commit233054a609a36cc441d26f9064bc3d16ff83b686 (patch)
treee563fb6292b82362da1702bdeaaf834dd47698a0 /gc.c
parenta006dcb73f105085eb2237c294a1618bd80c26a5 (diff)
Cycle `obj_info_buffers_index` atomically
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6092
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/gc.c b/gc.c
index 80e7fb596e..f487cb88ed 100644
--- a/gc.c
+++ b/gc.c
@@ -13942,19 +13942,26 @@ rb_raw_obj_info(char *const buff, const size_t buff_size, VALUE obj)
#if RGENGC_OBJ_INFO
#define OBJ_INFO_BUFFERS_NUM 10
#define OBJ_INFO_BUFFERS_SIZE 0x100
-static int 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 const char *
-obj_info(VALUE obj)
+static char *
+obj_info_next_buffer(void)
{
- const int index = obj_info_buffers_index++;
- char *const buff = &obj_info_buffers[index][0];
+ const rb_atomic_t index = RUBY_ATOMIC_FETCH_ADD(obj_info_buffers_index, 1);
- if (obj_info_buffers_index >= OBJ_INFO_BUFFERS_NUM) {
- obj_info_buffers_index = 0;
+ 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);
}
+ return obj_info_buffers[index % OBJ_INFO_BUFFERS_NUM];
+}
+static const char *
+obj_info(VALUE obj)
+{
+ char *const buff = obj_info_next_buffer();
return rb_raw_obj_info(buff, OBJ_INFO_BUFFERS_SIZE, obj);
}
#else