[前][次][番号順一覧][スレッド一覧]

ruby-changes:69816

From: Koichi <ko1@a...>
Date: Fri, 19 Nov 2021 08:32:23 +0900 (JST)
Subject: [ruby-changes:69816] 349a179782 (master): support `GC.stat(:time)` take 2

https://git.ruby-lang.org/ruby.git/commit/?id=349a179782

From 349a1797828a1fa6acc3c0d30a2a24e884d02907 Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Thu, 19 Aug 2021 16:14:46 +0900
Subject: support `GC.stat(:time)` take 2

---
 gc.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/gc.c b/gc.c
index 670fb4afd35..1029306cfdb 100644
--- a/gc.c
+++ b/gc.c
@@ -807,6 +807,8 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L807
 	size_t total_freed_objects;
 	size_t total_allocated_pages;
 	size_t total_freed_pages;
+        size_t total_time_ns;
+        struct timespec start_time;
     } profile;
     struct gc_list *global_list;
 
@@ -9163,11 +9165,56 @@ gc_enter_count(enum gc_enter_event event) https://github.com/ruby/ruby/blob/trunk/gc.c#L9165
     }
 }
 
+#define MEASURE_GC 1
+
+static bool
+gc_enter_event_measure_p(enum gc_enter_event event)
+{
+    if (!MEASURE_GC) return false;
+
+    switch (event) {
+      case gc_enter_event_start:
+      case gc_enter_event_mark_continue:
+      case gc_enter_event_sweep_continue:
+      case gc_enter_event_rest:
+        return true;
+      case gc_enter_event_finalizer:
+      case gc_enter_event_rb_memerror:
+        return false;
+    }
+}
+
+static void
+gc_enter_clock(rb_objspace_t *objspace, enum gc_enter_event event)
+{
+    if (gc_enter_event_measure_p(event)) {
+        clock_gettime(CLOCK_MONOTONIC, &objspace->profile.start_time);
+    }
+}
+
+static void
+gc_exit_clock(rb_objspace_t *objspace, enum gc_enter_event event)
+{
+    if (gc_enter_event_measure_p(event)) {
+        struct timespec end_time;
+
+        clock_gettime(CLOCK_MONOTONIC, &end_time);
+        if (end_time.tv_sec < objspace->profile.start_time.tv_sec) {
+            return; // ignore
+        }
+        size_t ns = (end_time.tv_sec - objspace->profile.start_time.tv_sec) * 1000 * 1000 * 1000 + end_time.tv_nsec - objspace->profile.start_time.tv_nsec;
+
+        objspace->profile.total_time_ns += ns;
+    }
+}
+
 static inline void
 gc_enter(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_lev)
 {
     RB_VM_LOCK_ENTER_LEV(lock_lev);
 
+    gc_enter_clock(objspace, event);
+
     switch (event) {
       case gc_enter_event_rest:
         if (!is_marking(objspace)) break;
@@ -9206,6 +9253,7 @@ gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_l https://github.com/ruby/ruby/blob/trunk/gc.c#L9253
     during_gc = FALSE;
 
     mjit_gc_exit_hook();
+    gc_exit_clock(objspace, event);
     RB_VM_LOCK_LEAVE_LEV(lock_lev);
 }
 
@@ -10444,6 +10492,7 @@ gc_latest_gc_info(rb_execution_context_t *ec, VALUE self, VALUE arg) https://github.com/ruby/ruby/blob/trunk/gc.c#L10492
 
 enum gc_stat_sym {
     gc_stat_sym_count,
+    gc_stat_sym_time,
     gc_stat_sym_heap_allocated_pages,
     gc_stat_sym_heap_sorted_length,
     gc_stat_sym_heap_allocatable_pages,
@@ -10492,6 +10541,7 @@ setup_gc_stat_symbols(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L10541
     if (gc_stat_symbols[0] == 0) {
 #define S(s) gc_stat_symbols[gc_stat_sym_##s] = ID2SYM(rb_intern_const(#s))
 	S(count);
+        S(time);
 	S(heap_allocated_pages);
 	S(heap_sorted_length);
 	S(heap_allocatable_pages);
@@ -10558,6 +10608,7 @@ gc_stat_internal(VALUE hash_or_sym) https://github.com/ruby/ruby/blob/trunk/gc.c#L10608
 	rb_hash_aset(hash, gc_stat_symbols[gc_stat_sym_##name], SIZET2NUM(attr));
 
     SET(count, objspace->profile.count);
+    SET(time, objspace->profile.total_time_ns / (1000 * 1000) /* ns -> ms */);
 
     /* implementation dependent counters */
     SET(heap_allocated_pages, heap_allocated_pages);
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]