Ruby: debug_counter.c Source File

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
26 MJIT_SYMBOL_EXPORT_BEGIN
27size_t rb_debug_counter[numberof(debug_counter_names)];
28void rb_debug_counter_add_atomic(enum rb_debug_counter_type type, int add);
29 MJIT_SYMBOL_EXPORT_END
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
54 ruby_debug_counter_reset(void)
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
73 ruby_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
87 return RB_DEBUG_COUNTER_MAX;
88}
89
90void
91 ruby_debug_counter_show_at_exit(int enable)
92{
93 debug_counter_disable_show_at_exit = !enable;
94}
95
96void
97 rb_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
114 VALUE
115rb_debug_counter_show(RB_UNUSED_VAR(VALUE klass))
116{
117 rb_debug_counter_show_results("show_debug_counters");
118 ruby_debug_counter_show_at_exit(FALSE);
119 return Qnil;
120}
121
122 VALUE
123rb_debug_counter_reset(RB_UNUSED_VAR(VALUE klass))
124{
125 ruby_debug_counter_reset();
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
141rb_debug_counter_show_results(const char *msg)
142{
143}
144
145size_t
146ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
147{
148 return 0;
149}
150void
151ruby_debug_counter_reset(void)
152{
153}
154
155void
156ruby_debug_counter_show_at_exit(int enable)
157{
158}
159
160#endif /* USE_DEBUG_COUNTER */
RB_UNUSED_VAR
#define RB_UNUSED_VAR(x)
Definition: attributes.h:168
add
#define add(x, y)
Definition: date_strftime.c:23
rb_debug_counter_show_results
void rb_debug_counter_show_results(const char *msg)
Definition: debug_counter.c:141
ruby_debug_counter_get
size_t ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr)
Definition: debug_counter.c:146
ruby_debug_counter_show_at_exit
void ruby_debug_counter_show_at_exit(int enable)
Definition: debug_counter.c:156
ruby_debug_counter_reset
void ruby_debug_counter_reset(void)
Definition: debug_counter.c:151
debug_counter.h
rb_debug_counter_type
rb_debug_counter_type
Definition: debug_counter.h:395
RB_DEBUG_COUNTER_MAX
@ RB_DEBUG_COUNTER_MAX
Definition: debug_counter.h:398
MJIT_SYMBOL_EXPORT_END
#define MJIT_SYMBOL_EXPORT_END
Definition: dllexport.h:63
MJIT_SYMBOL_EXPORT_BEGIN
#define MJIT_SYMBOL_EXPORT_BEGIN
Definition: dllexport.h:62
numberof
#define numberof(array)
Definition: etc.c:649
__attribute__
void *PTR64 __attribute__((mode(DI)))
Definition: ffi.c:41
internal.h
PRIuSIZE
#define PRIuSIZE
Definition: inttypes.h:127
int
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
FALSE
#define FALSE
Definition: nkf.h:174
NULL
#define NULL
Definition: regenc.h:69
Qnil
#define Qnil
Definition: special_consts.h:51
thread_native.h
rb_nativethread_lock_lock
void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock)
Definition: thread.c:442
rb_nativethread_lock_unlock
void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock)
Definition: thread.c:448
rb_nativethread_lock_initialize
void rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock)
Definition: thread.c:430
VALUE
unsigned long VALUE
Definition: value.h:38
getenv
#define getenv(name)
Definition: win32.c:80
env
#define env