1 /**********************************************************************
5 created at: Tue Feb 21 16:51:18 2017
7 Copyright (C) 2017 Koichi Sasada
9 **********************************************************************/
11 #include "debug_counter.h"
15 #include "ruby/thread_native.h"
19 const char *const rb_debug_counter_names
[] = {
20 #define DEBUG_COUNTER_NAME_EMPTY "" /* Suppress -Wstring-concatenation */
21 DEBUG_COUNTER_NAME_EMPTY
22 #undef DEBUG_COUNTER_NAME_EMPTY
23 #define RB_DEBUG_COUNTER(name) #name,
24 #include "debug_counter.h"
25 #undef RB_DEBUG_COUNTER
28 size_t rb_debug_counter
[numberof(rb_debug_counter_names
)];
29 void rb_debug_counter_add_atomic(enum rb_debug_counter_type type
, int add
);
31 static rb_nativethread_lock_t debug_counter_lock
;
33 __attribute__((constructor
))
35 debug_counter_setup(void)
37 rb_nativethread_lock_initialize(&debug_counter_lock
);
41 rb_debug_counter_add_atomic(enum rb_debug_counter_type type
, int add
)
43 rb_nativethread_lock_lock(&debug_counter_lock
);
45 rb_debug_counter
[(int)type
] += add
;
47 rb_nativethread_lock_unlock(&debug_counter_lock
);
50 static int debug_counter_disable_show_at_exit
= 0;
52 // note that this operation is not atomic.
54 ruby_debug_counter_reset(void)
56 for (int i
= 0; i
< RB_DEBUG_COUNTER_MAX
; i
++) {
57 rb_debug_counter
[i
] = 0;
61 // note that this operation is not atomic.
63 ruby_debug_counter_get(const char **names_ptr
, size_t *counters_ptr
)
66 if (names_ptr
!= NULL
) {
67 for (i
=0; i
<RB_DEBUG_COUNTER_MAX
; i
++) {
68 names_ptr
[i
] = rb_debug_counter_names
[i
];
71 if (counters_ptr
!= NULL
) {
72 for (i
=0; i
<RB_DEBUG_COUNTER_MAX
; i
++) {
73 counters_ptr
[i
] = rb_debug_counter
[i
];
77 return RB_DEBUG_COUNTER_MAX
;
81 ruby_debug_counter_show_at_exit(int enable
)
83 debug_counter_disable_show_at_exit
= !enable
;
87 rb_debug_counter_show_results(const char *msg
)
89 const char *env
= getenv("RUBY_DEBUG_COUNTER_DISABLE");
91 setlocale(LC_NUMERIC
, "");
93 if (env
== NULL
|| strcmp("1", env
) != 0) {
95 fprintf(stderr
, "[RUBY_DEBUG_COUNTER]\t%d %s\n", getpid(), msg
);
96 for (i
=0; i
<RB_DEBUG_COUNTER_MAX
; i
++) {
97 fprintf(stderr
, "[RUBY_DEBUG_COUNTER]\t%-30s\t%'14"PRIuSIZE
"\n",
98 rb_debug_counter_names
[i
],
105 rb_debug_counter_show(RB_UNUSED_VAR(VALUE klass
))
107 rb_debug_counter_show_results("show_debug_counters");
108 ruby_debug_counter_show_at_exit(FALSE
);
113 rb_debug_counter_reset(RB_UNUSED_VAR(VALUE klass
))
115 ruby_debug_counter_reset();
119 __attribute__((destructor
))
121 debug_counter_show_results_at_exit(void)
123 if (debug_counter_disable_show_at_exit
== 0) {
124 rb_debug_counter_show_results("normal exit.");
131 rb_debug_counter_show_results(const char *msg
)
136 ruby_debug_counter_get(const char **names_ptr
, size_t *counters_ptr
)
141 ruby_debug_counter_reset(void)
146 ruby_debug_counter_show_at_exit(int enable
)
150 #endif /* USE_DEBUG_COUNTER */