Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
debug_counter.c
Go to the documentation of this file.
1/**********************************************************************
2
3 debug_counter.c -
4
5 created at: Tue Feb 21 16:51:18 2017
6
7 Copyright (C) 2017 Koichi Sasada
8
9**********************************************************************/
10
11#include "debug_counter.h"
12#include "internal.h"
13#include <stdio.h>
14#include <locale.h>
15#include "ruby/thread_native.h"
16
17#if USE_DEBUG_COUNTER
18
19static const char *const debug_counter_names[] = {
20 ""
21#define RB_DEBUG_COUNTER(name) #name,
22#include "debug_counter.h"
23#undef RB_DEBUG_COUNTER
24};
25
27size_t rb_debug_counter[numberof(debug_counter_names)];
28void rb_debug_counter_add_atomic(enum rb_debug_counter_type type, int add);
30
31rb_nativethread_lock_t debug_counter_lock;
32
33__attribute__((constructor))
34static void
35debug_counter_setup(void)
36{
37 rb_nativethread_lock_initialize(&debug_counter_lock);
38}
39
40void
41rb_debug_counter_add_atomic(enum rb_debug_counter_type type, int add)
42{
43 rb_nativethread_lock_lock(&debug_counter_lock);
44 {
45 rb_debug_counter[(int)type] += add;
46 }
47 rb_nativethread_lock_unlock(&debug_counter_lock);
48}
49
50int debug_counter_disable_show_at_exit = 0;
51
52// note that this operation is not atomic.
53void
55{
56 for (int i = 0; i < RB_DEBUG_COUNTER_MAX; i++) {
57 switch (i) {
58 case RB_DEBUG_COUNTER_mjit_length_unit_queue:
59 case RB_DEBUG_COUNTER_mjit_length_active_units:
60 case RB_DEBUG_COUNTER_mjit_length_compact_units:
61 case RB_DEBUG_COUNTER_mjit_length_stale_units:
62 // These counters may be decreased and should not be reset.
63 break;
64 default:
65 rb_debug_counter[i] = 0;
66 break;
67 }
68 }
69}
70
71// note that this operation is not atomic.
72size_t
73ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
74{
75 int i;
76 if (names_ptr != NULL) {
77 for (i=0; i<RB_DEBUG_COUNTER_MAX; i++) {
78 names_ptr[i] = debug_counter_names[i];
79 }
80 }
81 if (counters_ptr != NULL) {
82 for (i=0; i<RB_DEBUG_COUNTER_MAX; i++) {
83 counters_ptr[i] = rb_debug_counter[i];
84 }
85 }
86
88}
89
90void
92{
93 debug_counter_disable_show_at_exit = !enable;
94}
95
96void
97rb_debug_counter_show_results(const char *msg)
98{
99 const char *env = getenv("RUBY_DEBUG_COUNTER_DISABLE");
100
101 setlocale(LC_NUMERIC, "");
102
103 if (env == NULL || strcmp("1", env) != 0) {
104 int i;
105 fprintf(stderr, "[RUBY_DEBUG_COUNTER]\t%d %s\n", getpid(), msg);
106 for (i=0; i<RB_DEBUG_COUNTER_MAX; i++) {
107 fprintf(stderr, "[RUBY_DEBUG_COUNTER]\t%-30s\t%'14"PRIuSIZE"\n",
108 debug_counter_names[i],
109 rb_debug_counter[i]);
110 }
111 }
112}
113
114VALUE
115rb_debug_counter_show(RB_UNUSED_VAR(VALUE klass))
116{
117 rb_debug_counter_show_results("show_debug_counters");
119 return Qnil;
120}
121
122VALUE
123rb_debug_counter_reset(RB_UNUSED_VAR(VALUE klass))
124{
126 return Qnil;
127}
128
129__attribute__((destructor))
130static void
131debug_counter_show_results_at_exit(void)
132{
133 if (debug_counter_disable_show_at_exit == 0) {
134 rb_debug_counter_show_results("normal exit.");
135 }
136}
137
138#else
139
140void
142{
143}
144
145size_t
146ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
147{
148 return 0;
149}
150void
152{
153}
154
155void
157{
158}
159
160#endif /* USE_DEBUG_COUNTER */
#define RB_UNUSED_VAR(x)
Definition: attributes.h:168
#define add(x, y)
Definition: date_strftime.c:23
void rb_debug_counter_show_results(const char *msg)
size_t ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
void ruby_debug_counter_show_at_exit(int enable)
void ruby_debug_counter_reset(void)
rb_debug_counter_type
@ RB_DEBUG_COUNTER_MAX
#define MJIT_SYMBOL_EXPORT_END
Definition: dllexport.h:63
#define MJIT_SYMBOL_EXPORT_BEGIN
Definition: dllexport.h:62
#define numberof(array)
Definition: etc.c:649
void *PTR64 __attribute__((mode(DI)))
Definition: ffi.c:41
#define PRIuSIZE
Definition: inttypes.h:127
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
#define FALSE
Definition: nkf.h:174
#define NULL
Definition: regenc.h:69
#define Qnil
void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock)
Definition: thread.c:442
void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock)
Definition: thread.c:448
void rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock)
Definition: thread.c:430
unsigned long VALUE
Definition: value.h:38
#define getenv(name)
Definition: win32.c:80
#define env