jemalloc_ctl 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/jemalloc_ctl/jemalloc_ctl.c +57 -11
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6358746cbb29a35a956a8b738a3b52f2dd643256d48cb76d5ae5e55ff9c093ae
|
|
4
|
+
data.tar.gz: 135a5d7a5e9ef51bac5709cb99d9fdacbd2f6d0245b72e49405becc270cbc3bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 24b769826c3f509efc442aeca2ee62ce768b27f86b2f9f6ee12e8a624b01420042d0ee2d7b420b73e19e7704e4f6f2172f607e47638d7d7c15377215386b8827
|
|
7
|
+
data.tar.gz: 7e8ab5599ff137fb5b8fe8efd9e96eda75e9bb1cab439a39bea39d7fb6e9f9f179e8b21b6b239e83c0143383c4b4fc8a4ce01cacca49e9eee5a851a156efbfbc
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include <ruby.h>
|
|
2
|
+
#include <ruby/debug.h>
|
|
2
3
|
#include <dlfcn.h>
|
|
3
4
|
#include <stdbool.h>
|
|
4
5
|
|
|
@@ -33,6 +34,11 @@ static malloc_stats_print_fn my_malloc_stats_print = NULL;
|
|
|
33
34
|
#endif
|
|
34
35
|
|
|
35
36
|
static VALUE rb_mJemallocCtl;
|
|
37
|
+
static VALUE rb_eJemallocCtlError;
|
|
38
|
+
static VALUE rb_eJemallocCtlJemallocNotFound;
|
|
39
|
+
|
|
40
|
+
static VALUE main_thread_val = Qnil;
|
|
41
|
+
static int gc_exit_hook_installed = 0;
|
|
36
42
|
|
|
37
43
|
static VALUE rb_jemalloc_ctl_enabled_p(VALUE self)
|
|
38
44
|
{
|
|
@@ -42,14 +48,14 @@ static VALUE rb_jemalloc_ctl_enabled_p(VALUE self)
|
|
|
42
48
|
static VALUE rb_jemalloc_ctl_version(VALUE self)
|
|
43
49
|
{
|
|
44
50
|
if (my_mallctl == NULL)
|
|
45
|
-
rb_raise(
|
|
51
|
+
rb_raise(rb_eJemallocCtlJemallocNotFound, "jemalloc is not available");
|
|
46
52
|
|
|
47
53
|
const char *version;
|
|
48
54
|
size_t sz = sizeof(version);
|
|
49
55
|
int err = my_mallctl("version", &version, &sz, NULL, 0);
|
|
50
56
|
|
|
51
57
|
if (err != 0)
|
|
52
|
-
rb_raise(
|
|
58
|
+
rb_raise(rb_eJemallocCtlError, "mallctl(\"version\") failed with error %d", err);
|
|
53
59
|
|
|
54
60
|
return rb_str_new_cstr(version);
|
|
55
61
|
}
|
|
@@ -57,13 +63,13 @@ static VALUE rb_jemalloc_ctl_version(VALUE self)
|
|
|
57
63
|
static VALUE rb_jemalloc_ctl_toggle_background_thread(VALUE self, VALUE onoff)
|
|
58
64
|
{
|
|
59
65
|
if (my_mallctl == NULL)
|
|
60
|
-
rb_raise(
|
|
66
|
+
rb_raise(rb_eJemallocCtlJemallocNotFound, "jemalloc is not available");
|
|
61
67
|
|
|
62
68
|
bool val = RTEST(onoff);
|
|
63
69
|
int err = my_mallctl("background_thread", NULL, NULL, &val, sizeof(bool));
|
|
64
70
|
|
|
65
71
|
if (err != 0)
|
|
66
|
-
rb_raise(
|
|
72
|
+
rb_raise(rb_eJemallocCtlError, "mallctl(\"background_thread\") failed with error %d", err);
|
|
67
73
|
|
|
68
74
|
return Qtrue;
|
|
69
75
|
}
|
|
@@ -71,13 +77,13 @@ static VALUE rb_jemalloc_ctl_toggle_background_thread(VALUE self, VALUE onoff)
|
|
|
71
77
|
static VALUE rb_jemalloc_ctl_toggle_current_thread_tcache(VALUE self, VALUE onoff)
|
|
72
78
|
{
|
|
73
79
|
if (my_mallctl == NULL)
|
|
74
|
-
rb_raise(
|
|
80
|
+
rb_raise(rb_eJemallocCtlJemallocNotFound, "jemalloc is not available");
|
|
75
81
|
|
|
76
82
|
bool enabled = RTEST(onoff);
|
|
77
83
|
int err = my_mallctl("thread.tcache.enabled", NULL, NULL, &enabled, sizeof(enabled));
|
|
78
84
|
|
|
79
85
|
if (err != 0)
|
|
80
|
-
rb_raise(
|
|
86
|
+
rb_raise(rb_eJemallocCtlError, "mallctl(\"thread.tcache.enabled\") failed with error %d", err);
|
|
81
87
|
|
|
82
88
|
return Qtrue;
|
|
83
89
|
}
|
|
@@ -85,20 +91,56 @@ static VALUE rb_jemalloc_ctl_toggle_current_thread_tcache(VALUE self, VALUE onof
|
|
|
85
91
|
static VALUE rb_jemalloc_ctl_flush_current_thread_tcache(VALUE self)
|
|
86
92
|
{
|
|
87
93
|
if (my_mallctl == NULL)
|
|
88
|
-
rb_raise(
|
|
94
|
+
rb_raise(rb_eJemallocCtlJemallocNotFound, "jemalloc is not available");
|
|
89
95
|
|
|
90
96
|
int err = my_mallctl("thread.tcache.flush", NULL, NULL, NULL, 0);
|
|
91
97
|
|
|
92
98
|
if (err != 0)
|
|
93
|
-
rb_raise(
|
|
99
|
+
rb_raise(rb_eJemallocCtlError, "mallctl(\"thread.tcache.flush\") failed with error %d", err);
|
|
100
|
+
|
|
101
|
+
return Qtrue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static void gc_exit_tcache_flush_hook(rb_event_flag_t flag, VALUE data,
|
|
105
|
+
VALUE self, ID mid, VALUE klass)
|
|
106
|
+
{
|
|
107
|
+
// Runs inside GC: must not allocate Ruby objects or raise.
|
|
108
|
+
if (my_mallctl == NULL) return;
|
|
109
|
+
if (rb_thread_current() == main_thread_val) return;
|
|
110
|
+
my_mallctl("thread.tcache.flush", NULL, NULL, NULL, 0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static VALUE rb_jemalloc_ctl_enable_gc_exit_tcache_flush(VALUE self)
|
|
114
|
+
{
|
|
115
|
+
if (my_mallctl == NULL)
|
|
116
|
+
rb_raise(rb_eJemallocCtlJemallocNotFound, "jemalloc is not available");
|
|
117
|
+
|
|
118
|
+
if (gc_exit_hook_installed)
|
|
119
|
+
return Qfalse;
|
|
120
|
+
|
|
121
|
+
if (main_thread_val == Qnil) {
|
|
122
|
+
main_thread_val = rb_thread_main();
|
|
123
|
+
rb_gc_register_address(&main_thread_val);
|
|
124
|
+
}
|
|
125
|
+
rb_add_event_hook(gc_exit_tcache_flush_hook, RUBY_INTERNAL_EVENT_GC_EXIT, Qnil);
|
|
126
|
+
gc_exit_hook_installed = 1;
|
|
127
|
+
return Qtrue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static VALUE rb_jemalloc_ctl_disable_gc_exit_tcache_flush(VALUE self)
|
|
131
|
+
{
|
|
132
|
+
if (!gc_exit_hook_installed)
|
|
133
|
+
return Qfalse;
|
|
94
134
|
|
|
135
|
+
rb_remove_event_hook(gc_exit_tcache_flush_hook);
|
|
136
|
+
gc_exit_hook_installed = 0;
|
|
95
137
|
return Qtrue;
|
|
96
138
|
}
|
|
97
139
|
|
|
98
140
|
static VALUE rb_jemalloc_ctl_purge_arenas(VALUE self)
|
|
99
141
|
{
|
|
100
142
|
if (my_mallctl == NULL)
|
|
101
|
-
rb_raise(
|
|
143
|
+
rb_raise(rb_eJemallocCtlJemallocNotFound, "jemalloc is not available");
|
|
102
144
|
|
|
103
145
|
char ctl[32];
|
|
104
146
|
snprintf(ctl, sizeof(ctl), "arena.%d.purge", MALLCTL_ARENAS_ALL);
|
|
@@ -106,7 +148,7 @@ static VALUE rb_jemalloc_ctl_purge_arenas(VALUE self)
|
|
|
106
148
|
int err = my_mallctl(ctl, NULL, NULL, NULL, 0);
|
|
107
149
|
|
|
108
150
|
if (err != 0)
|
|
109
|
-
rb_raise(
|
|
151
|
+
rb_raise(rb_eJemallocCtlError, "mallctl(\"%s\") failed with error %d", ctl, err);
|
|
110
152
|
|
|
111
153
|
return Qtrue;
|
|
112
154
|
}
|
|
@@ -119,7 +161,7 @@ static void write_stats_cb(void *opaque, const char *buf)
|
|
|
119
161
|
static VALUE rb_jemalloc_ctl_print_stats(VALUE self, VALUE filename)
|
|
120
162
|
{
|
|
121
163
|
if (my_malloc_stats_print == NULL)
|
|
122
|
-
rb_raise(
|
|
164
|
+
rb_raise(rb_eJemallocCtlError, "malloc_stats_print is not available");
|
|
123
165
|
|
|
124
166
|
const char *path = StringValueCStr(filename);
|
|
125
167
|
FILE *f = fopen(path, "w");
|
|
@@ -173,6 +215,8 @@ void Init_jemalloc_ctl(void)
|
|
|
173
215
|
#endif
|
|
174
216
|
|
|
175
217
|
rb_mJemallocCtl = rb_define_module("JemallocCtl");
|
|
218
|
+
rb_eJemallocCtlError = rb_define_class_under(rb_mJemallocCtl, "Error", rb_eStandardError);
|
|
219
|
+
rb_eJemallocCtlJemallocNotFound = rb_define_class_under(rb_mJemallocCtl, "JemallocNotFound", rb_eJemallocCtlError);
|
|
176
220
|
rb_define_singleton_method(rb_mJemallocCtl, "enabled?", rb_jemalloc_ctl_enabled_p, 0);
|
|
177
221
|
rb_define_singleton_method(rb_mJemallocCtl, "version", rb_jemalloc_ctl_version, 0);
|
|
178
222
|
rb_define_singleton_method(rb_mJemallocCtl, "print_stats", rb_jemalloc_ctl_print_stats, 1);
|
|
@@ -180,4 +224,6 @@ void Init_jemalloc_ctl(void)
|
|
|
180
224
|
rb_define_singleton_method(rb_mJemallocCtl, "purge_arenas", rb_jemalloc_ctl_purge_arenas, 0);
|
|
181
225
|
rb_define_singleton_method(rb_mJemallocCtl, "flush_current_thread_tcache", rb_jemalloc_ctl_flush_current_thread_tcache, 0);
|
|
182
226
|
rb_define_singleton_method(rb_mJemallocCtl, "toggle_current_thread_tcache", rb_jemalloc_ctl_toggle_current_thread_tcache, 1);
|
|
227
|
+
rb_define_singleton_method(rb_mJemallocCtl, "enable_gc_exit_tcache_flush!", rb_jemalloc_ctl_enable_gc_exit_tcache_flush, 0);
|
|
228
|
+
rb_define_singleton_method(rb_mJemallocCtl, "disable_gc_exit_tcache_flush!", rb_jemalloc_ctl_disable_gc_exit_tcache_flush, 0);
|
|
183
229
|
}
|