jemalloc_ctl 0.1.0 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ab59d11b2bfb3adb1e40476ed0902532eae1436edf9b0e31f64be2dd4f3d8da
4
- data.tar.gz: d771262a02cf483a43a85c3d0d643a499e5c5f1cde09bf4be70a5678995010bd
3
+ metadata.gz: ca9382bca94ee59c45b5cc6f1a5cd6bfafedb32b8ad62c8b24c4c4e1ddad33b8
4
+ data.tar.gz: 5dc23dfa0cc0a2ccc4c034aba3db9e554a2eaa75c0b8664f27c878b5132d0669
5
5
  SHA512:
6
- metadata.gz: 86e68a6ed91e73633fb5cbaa416152d374f266de91ff564e49145e62aa4cd766478b3d626640a4c53a55f5e30d8e47e73acc06d77af641e2fe205d32d5b0e418
7
- data.tar.gz: 865191340c23cfb157aa6f74800cf78ee25a21c611d3999813eaec291419cc6ccb9f4de9f6ff52b8d9bffc44ccc0c6aab4e5d71f91174a674d4493a68c32c860
6
+ metadata.gz: e5db0172c45f9c25f7f2783731098d948913586d23234b5bb9cafdf83702861eefe6fddd376473fe18611912acb1f9d73ef3a1eb4273ac018cadffbedc35cc52
7
+ data.tar.gz: a1211d9003b487b6a1b399f03db1556971478a3bb933798afe8d2455674943bafa3d8a008dd24cb058aeffb2230b6bcfa496452fd2cad79a0ee9a448148dc479
@@ -3,11 +3,17 @@
3
3
  #include <stdbool.h>
4
4
 
5
5
  typedef int (*mallctl_fn)(const char *, void *, size_t *, void *, size_t);
6
+ typedef void (*write_cb_t)(void *, const char *);
7
+ typedef void (*malloc_stats_print_fn)(write_cb_t, void *, const char *);
6
8
 
7
9
  static mallctl_fn my_mallctl = NULL;
10
+ static malloc_stats_print_fn my_malloc_stats_print = NULL;
8
11
 
9
12
  #define JEMALLOC_CTL_DLOPEN_FALLBACK 0
10
13
 
14
+ // From jemalloc.h: special arena index meaning "all arenas"
15
+ #define MALLCTL_ARENAS_ALL 4096
16
+
11
17
  #if JEMALLOC_CTL_DLOPEN_FALLBACK > 0
12
18
  // used for testing
13
19
  static const char *jemalloc_lib_names[] = {
@@ -76,20 +82,82 @@ static VALUE rb_jemalloc_ctl_disable_background_thread(VALUE self)
76
82
  return Qfalse;
77
83
  }
78
84
 
79
- static mallctl_fn find_mallctl_in(void *handle)
85
+ static VALUE rb_jemalloc_ctl_flush_current_thread_tcache(VALUE self)
86
+ {
87
+ if (my_mallctl == NULL)
88
+ rb_raise(rb_eRuntimeError, "jemalloc is not available");
89
+
90
+ int err = my_mallctl("thread.tcache.flush", NULL, NULL, NULL, 0);
91
+
92
+ if (err != 0)
93
+ rb_raise(rb_eRuntimeError, "mallctl(\"thread.tcache.flush\") failed with error %d", err);
94
+
95
+ return Qtrue;
96
+ }
97
+
98
+ static VALUE rb_jemalloc_ctl_purge_arenas(VALUE self)
99
+ {
100
+ if (my_mallctl == NULL)
101
+ rb_raise(rb_eRuntimeError, "jemalloc is not available");
102
+
103
+ char ctl[32];
104
+ snprintf(ctl, sizeof(ctl), "arena.%d.purge", MALLCTL_ARENAS_ALL);
105
+
106
+ int err = my_mallctl(ctl, NULL, NULL, NULL, 0);
107
+
108
+ if (err != 0)
109
+ rb_raise(rb_eRuntimeError, "mallctl(\"%s\") failed with error %d", ctl, err);
110
+
111
+ return Qtrue;
112
+ }
113
+
114
+ static void write_stats_cb(void *opaque, const char *buf)
115
+ {
116
+ fputs(buf, (FILE *)opaque);
117
+ }
118
+
119
+ static VALUE rb_jemalloc_ctl_print_stats(VALUE self, VALUE filename)
120
+ {
121
+ if (my_mallctl == NULL)
122
+ rb_raise(rb_eRuntimeError, "jemalloc is not available");
123
+
124
+ if (my_malloc_stats_print == NULL)
125
+ rb_raise(rb_eRuntimeError, "malloc_stats_print is not available");
126
+
127
+ const char *path = StringValueCStr(filename);
128
+ FILE *f = fopen(path, "w");
129
+ if (f == NULL)
130
+ rb_sys_fail(path);
131
+
132
+ my_malloc_stats_print(write_stats_cb, f, NULL);
133
+
134
+ fclose(f);
135
+ return Qtrue;
136
+ }
137
+
138
+ static bool find_jemalloc_fns_in(void *handle)
80
139
  {
81
140
  // Try unprefixed (jemalloc as default allocator) then je_-prefixed
82
- mallctl_fn fn = (mallctl_fn)dlsym(handle, "mallctl");
83
- if (fn == NULL)
84
- fn = (mallctl_fn)dlsym(handle, "je_mallctl");
85
- return fn;
141
+ mallctl_fn mallctl = (mallctl_fn)dlsym(handle, "mallctl");
142
+ if (mallctl == NULL)
143
+ mallctl = (mallctl_fn)dlsym(handle, "je_mallctl");
144
+ if (mallctl == NULL)
145
+ return false;
146
+
147
+ malloc_stats_print_fn print_fn = (malloc_stats_print_fn)dlsym(handle, "malloc_stats_print");
148
+ if (print_fn == NULL)
149
+ print_fn = (malloc_stats_print_fn)dlsym(handle, "je_malloc_stats_print");
150
+
151
+ my_mallctl = mallctl;
152
+ my_malloc_stats_print = print_fn;
153
+ return true;
86
154
  }
87
155
 
88
156
  void Init_jemalloc_ctl(void)
89
157
  {
90
158
  // First: check if mallctl is already in the process
91
159
  // (jemalloc compiled into Ruby or LD_PRELOADed)
92
- my_mallctl = find_mallctl_in(RTLD_DEFAULT);
160
+ find_jemalloc_fns_in(RTLD_DEFAULT);
93
161
 
94
162
  #if JEMALLOC_CTL_DLOPEN_FALLBACK > 0
95
163
  // Fallback: try to dlopen jemalloc from common paths
@@ -98,8 +166,7 @@ void Init_jemalloc_ctl(void)
98
166
  for (const char **name = jemalloc_lib_names; *name != NULL; name++) {
99
167
  jemalloc_handle = dlopen(*name, RTLD_LAZY);
100
168
  if (jemalloc_handle != NULL) {
101
- my_mallctl = find_mallctl_in(jemalloc_handle);
102
- if (my_mallctl != NULL)
169
+ if (find_jemalloc_fns_in(jemalloc_handle))
103
170
  break;
104
171
  dlclose(jemalloc_handle);
105
172
  jemalloc_handle = NULL;
@@ -113,4 +180,7 @@ void Init_jemalloc_ctl(void)
113
180
  rb_define_singleton_method(rb_mJemallocCtl, "version", rb_jemalloc_ctl_version, 0);
114
181
  rb_define_singleton_method(rb_mJemallocCtl, "enable_background_thread", rb_jemalloc_ctl_enable_background_thread, 0);
115
182
  rb_define_singleton_method(rb_mJemallocCtl, "disable_background_thread", rb_jemalloc_ctl_disable_background_thread, 0);
183
+ rb_define_singleton_method(rb_mJemallocCtl, "print_stats", rb_jemalloc_ctl_print_stats, 1);
184
+ rb_define_singleton_method(rb_mJemallocCtl, "purge_arenas", rb_jemalloc_ctl_purge_arenas, 0);
185
+ rb_define_singleton_method(rb_mJemallocCtl, "flush_current_thread_tcache", rb_jemalloc_ctl_flush_current_thread_tcache, 0);
116
186
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jemalloc_ctl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Gruber
@@ -40,5 +40,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
40
40
  requirements: []
41
41
  rubygems_version: 4.0.6
42
42
  specification_version: 4
43
- summary: Configure jemalloc via mallctl
43
+ summary: Configure jemalloc via mallctl from Ruby
44
44
  test_files: []