diff options
author | Eric Wong <e@yhbt.net> | 2011-02-06 08:04:42 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2011-02-06 08:51:00 +0000 |
commit | 415296ba1d398983a0ea047134b8ee7d58ac93bc (patch) | |
tree | 96fd3781a65037cf7d232949866d859826e162b8 | |
parent | ab9d3237f622e9db0be25f09bfb5c123318f3974 (diff) | |
download | mall-415296ba1d398983a0ea047134b8ee7d58ac93bc.tar.gz |
malloc_info() support from glibc as Mall.xml
XML FOR ENTERPRISE!
-rw-r--r-- | ext/mall/extconf.rb | 1 | ||||
-rw-r--r-- | ext/mall/mall.c.erb | 51 | ||||
-rw-r--r-- | test/test_mall.rb | 14 |
3 files changed, 66 insertions, 0 deletions
diff --git a/ext/mall/extconf.rb b/ext/mall/extconf.rb index a180c71..8fc6cbd 100644 --- a/ext/mall/extconf.rb +++ b/ext/mall/extconf.rb @@ -4,5 +4,6 @@ have_header('malloc.h') or abort "malloc.h header missing" have_type('struct mallinfo', 'malloc.h') or abort 'struct mallinfo missing' have_func('malloc_trim', 'malloc.h') have_func('malloc_stats', 'malloc.h') +have_func('malloc_info', 'malloc.h') dir_config('mall') create_makefile('mall') diff --git a/ext/mall/mall.c.erb b/ext/mall/mall.c.erb index 66c1973..1e15662 100644 --- a/ext/mall/mall.c.erb +++ b/ext/mall/mall.c.erb @@ -90,6 +90,52 @@ static VALUE dump_stats(VALUE klass) } #endif /* HAVE_MALLOC_STATS */ +#ifdef HAVE_MALLOC_INFO +static ID id_ltlt; +#include <stdio.h> +#include <errno.h> +static void xmlerr(FILE *fp, int err, const char *msg) +{ + fclose(fp); + errno = err ? err : EIO; /* gotta have something */ + rb_sys_fail(msg); +} + +static VALUE xml(int argc, VALUE *argv, VALUE self) +{ + int err; + long len; + VALUE options, out, buf; + int xoptions; + FILE *fp; + + rb_scan_args(argc, argv, "02", &options, &out); + xoptions = NIL_P(options) ? 0 : NUM2INT(options); + + fp = tmpfile(); + if (fp == NULL) + rb_sys_fail("tmpfile"); + + err = malloc_info(xoptions, fp); + if (err != 0) + xmlerr(fp, err, "malloc_info"); + + len = ftell(fp); + if (len < 0) + xmlerr(fp, errno, "ftell"); + + rewind(fp); + buf = rb_str_new(0, len); + if (fread(RSTRING_PTR(buf), 1, len, fp) != len) + xmlerr(fp, ferror(fp), "fread"); + fclose(fp); + + if (NIL_P(out)) + return buf; + return rb_funcall(out, id_ltlt, 1, buf); +} +#endif /* HAVE_MALLOC_INFO */ + void Init_mall(void) { mMall = rb_define_module("Mall"); @@ -101,6 +147,11 @@ void Init_mall(void) #ifdef HAVE_MALLOC_STATS rb_define_singleton_method(mMall, "dump_stats", dump_stats, 0); #endif /* HAVE_MALLOC_STATS */ +#ifdef HAVE_MALLOC_INFO + id_ltlt = rb_intern("<<"); + rb_define_singleton_method(mMall, "xml", xml, -1); +#endif /* HAVE_MALLOC_INFO*/ + <% mallinfo_keys.each { |x| %> sym_<%= x %> = ID2SYM(rb_intern("<%= x %>")); <% } %> diff --git a/test/test_mall.rb b/test/test_mall.rb index 1bbff85..5472acb 100644 --- a/test/test_mall.rb +++ b/test/test_mall.rb @@ -32,6 +32,20 @@ class TestMall < Test::Unit::TestCase end end + def test_xml + if Mall.respond_to?(:xml) + str = Mall.xml + assert_match /<malloc version=/, str + + tmp = [] + assert_equal tmp, Mall.xml(0, tmp) + assert_match /<malloc version=/, tmp[0] + assert_equal 1, tmp.size + else + warn "Mall.xml not supported" + end + end + def test_dump_stats if Mall.respond_to?(:dump_stats) olderr = $stderr.dup |