mwrap 2.0.0 → 2.0.0.4.gd1ea

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8559afec1946b7f545c944085aac5e205601deb82fa9f1529785dd3ef7526e5a
4
- data.tar.gz: 34ea90410103ec59f367baa00e1e4df6424fe67af8608b5c7a3a0cb66fec2440
3
+ metadata.gz: a0c1d38278467de929383b9a6415bd0364aa176c18e480c68553978536d37f2b
4
+ data.tar.gz: 96ae575c69d8dfa9204434acd5fd3cc2aebe64d6ef2ef51cf37ad6e924aa84a5
5
5
  SHA512:
6
- metadata.gz: ff91f6f250e7a18cb465a6dc04ddee374411a10a92cd1b3227e09a4ccd0be1b8597f475f71d5061bd5bc36e8c0418ce3bf6faa3a78b37aec5d21b0340f736031
7
- data.tar.gz: 06311f2949ae4dae6bd2d0e95e6b0d147b44b6bae6cd4464e4c1d160fc1f5f3f99b2a6a3a3e711a10b8894da3bdb6220ccfeb72dfb18545170edbbc65dbad225
6
+ metadata.gz: facf03ed2e533fc8fa3faa14069101ed218e922b94cab228f5e651f89ebbd590972d44ff479374ccff9c0ed666426975fb3386df6a2eb4d2e174fb9268b8a18b
7
+ data.tar.gz: '0393004af3b3f22d6cc8581f239b838067764d48cfab0eb5d759b614edfb97a9f30c7e89bae658486f970d692951b4adb15ba08d12d326ccfd7191c60fff38e1'
data/.olddoc.yml ADDED
@@ -0,0 +1,8 @@
1
+ ---
2
+ cgit_url: https://80x24.org/mwrap.git
3
+ git_url: https://80x24.org/mwrap.git
4
+ rdoc_url: https://80x24.org/mwrap/
5
+ ml_url: https://80x24.org/mwrap-public/
6
+ public_email: mwrap-public@80x24.org
7
+ nntp_url:
8
+ - nntp://news.public-inbox.org/inbox.comp.lang.ruby.mwrap
data/MANIFEST CHANGED
@@ -1,5 +1,6 @@
1
1
  .document
2
2
  .gitignore
3
+ .olddoc.yml
3
4
  COPYING
4
5
  MANIFEST
5
6
  README
data/ext/mwrap/mwrap.c CHANGED
@@ -32,6 +32,8 @@ extern size_t __attribute__((weak)) rb_gc_count(void);
32
32
  extern VALUE __attribute__((weak)) rb_cObject;
33
33
  extern VALUE __attribute__((weak)) rb_yield(VALUE);
34
34
 
35
+ static size_t total_bytes_inc, total_bytes_dec;
36
+
35
37
  /* true for glibc/dlmalloc/ptmalloc, not sure about jemalloc */
36
38
  #define ASSUMED_MALLOC_ALIGNMENT (sizeof(void *) * 2)
37
39
 
@@ -327,6 +329,8 @@ static struct src_loc *update_stats_rcu_lock(size_t size, uintptr_t caller)
327
329
  if (caa_unlikely(!totals)) return 0;
328
330
  if (locating++) goto out; /* do not recurse into another *alloc */
329
331
 
332
+ uatomic_add(&total_bytes_inc, size);
333
+
330
334
  rcu_read_lock();
331
335
  if (has_ec_p()) {
332
336
  int line;
@@ -390,6 +394,7 @@ void free(void *p)
390
394
  if (l) {
391
395
  size_t age = generation - h->as.live.gen;
392
396
 
397
+ uatomic_add(&total_bytes_dec, h->size);
393
398
  uatomic_set(&h->size, 0);
394
399
  uatomic_add(&l->frees, 1);
395
400
  uatomic_add(&l->age_total, age);
@@ -710,12 +715,16 @@ static VALUE mwrap_dump(int argc, VALUE * argv, VALUE mod)
710
715
  return Qnil;
711
716
  }
712
717
 
718
+ /* The whole operation is not remotely atomic... */
713
719
  static void *totals_reset(void *ign)
714
720
  {
715
721
  struct cds_lfht *t;
716
722
  struct cds_lfht_iter iter;
717
723
  struct src_loc *l;
718
724
 
725
+ uatomic_set(&total_bytes_inc, 0);
726
+ uatomic_set(&total_bytes_dec, 0);
727
+
719
728
  rcu_read_lock();
720
729
  t = rcu_dereference(totals);
721
730
  cds_lfht_for_each_entry(t, &iter, l, hnode) {
@@ -1033,6 +1042,16 @@ static VALUE mwrap_quiet(VALUE mod)
1033
1042
  return rb_ensure(rb_yield, SIZET2NUM(cur), reset_locating, 0);
1034
1043
  }
1035
1044
 
1045
+ static VALUE total_inc(VALUE mod)
1046
+ {
1047
+ return SIZET2NUM(total_bytes_inc);
1048
+ }
1049
+
1050
+ static VALUE total_dec(VALUE mod)
1051
+ {
1052
+ return SIZET2NUM(total_bytes_dec);
1053
+ }
1054
+
1036
1055
  /*
1037
1056
  * Document-module: Mwrap
1038
1057
  *
@@ -1084,6 +1103,8 @@ void Init_mwrap(void)
1084
1103
  rb_define_singleton_method(mod, "each", mwrap_each, -1);
1085
1104
  rb_define_singleton_method(mod, "[]", mwrap_aref, 1);
1086
1105
  rb_define_singleton_method(mod, "quiet", mwrap_quiet, 0);
1106
+ rb_define_singleton_method(mod, "total_bytes_allocated", total_inc, 0);
1107
+ rb_define_singleton_method(mod, "total_bytes_freed", total_dec, 0);
1087
1108
  rb_define_method(cSrcLoc, "each", src_loc_each, 0);
1088
1109
  rb_define_method(cSrcLoc, "frees", src_loc_frees, 0);
1089
1110
  rb_define_method(cSrcLoc, "allocations", src_loc_allocations, 0);
data/lib/mwrap_rack.rb ADDED
@@ -0,0 +1,121 @@
1
+ # Copyright (C) 2018 all contributors <mwrap@80x24.org>
2
+ # License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
3
+ # frozen_string_literal: true
4
+ require 'mwrap'
5
+ require 'rack'
6
+ require 'cgi'
7
+
8
+ # MwrapRack is a standalone Rack application which can be
9
+ # mounted to run within your application process.
10
+ #
11
+ # Using the Rack::Builder API in config.ru, you can map it to
12
+ # the "/MWRAP/" endpoint. As with the rest of the Mwrap API,
13
+ # your Rack server needs to be spawned with the mwrap(1)
14
+ # wrapper to enable the LD_PRELOAD.
15
+ #
16
+ # require 'mwrap_rack'
17
+ # map('/MWRAP') { run(MwrapRack.new) }
18
+ # map('/') { run(your_normal_app) }
19
+ #
20
+ # A live demo is available at https://80x24.org/MWRAP/
21
+ # (warning the demo machine is 32-bit, so counters will overflow)
22
+ #
23
+ # This module is only available in mwrap 2.0.0+
24
+ class MwrapRack
25
+ module HtmlResponse # :nodoc:
26
+ def response
27
+ [ 200, {
28
+ 'Expires' => 'Fri, 01 Jan 1980 00:00:00 GMT',
29
+ 'Pragma' => 'no-cache',
30
+ 'Cache-Control' => 'no-cache, max-age=0, must-revalidate',
31
+ 'Content-Type' => 'text/html; charset=UTF-8',
32
+ }, self ]
33
+ end
34
+ end
35
+
36
+ class Each < Struct.new(:script_name, :min, :sort) # :nodoc:
37
+ include HtmlResponse
38
+ HEADER = '<tr><th>' + %w(total allocations frees mean_life max_life
39
+ location).join('</th><th>') + '</th></tr>'
40
+ FIELDS = %w(total allocations frees mean_life max_life location)
41
+ def each
42
+ Mwrap.quiet do
43
+ t = -"Mwrap.each(#{min})"
44
+ sn = script_name
45
+ all = []
46
+ f = FIELDS.dup
47
+ sc = FIELDS.index(sort || 'total') || 0
48
+ f[sc] = -"<b>#{f[sc]}</b>"
49
+ f.map! do |hdr|
50
+ if hdr.start_with?('<b>')
51
+ hdr
52
+ else
53
+ -%Q(<a\nhref="#{sn}/each/#{min}?sort=#{hdr}">#{hdr}</a>)
54
+ end
55
+ end
56
+ Mwrap.each(min) do |loc, total, allocations, frees, age_sum, max_life|
57
+ mean_life = frees == 0 ? Float::INFINITY : age_sum/frees.to_f
58
+ all << [total,allocations,frees,mean_life,max_life,loc]
59
+ end
60
+ all.sort_by! { |cols| -cols[sc] }
61
+
62
+ yield(-"<html><head><title>#{t}</title></head>" \
63
+ "<body><h1>#{t}</h1>\n" \
64
+ "<h2>Current generation: #{GC.count}</h2>\n<table>\n" \
65
+ "<tr><th>#{f.join('</th><th>')}</th></tr>\n")
66
+ all.each do |cols|
67
+ loc = cols.pop
68
+ cols[3] = sprintf('%0.3f', cols[3]) # mean_life
69
+ href = -(+"#{sn}/at/#{CGI.escape(loc)}").encode!(xml: :attr)
70
+ yield(%Q(<tr><td>#{cols.join('</td><td>')}<td><a\nhref=#{
71
+ href}>#{-loc.encode(xml: :text)}</a></td></tr>\n))
72
+ cols.clear
73
+ end.clear
74
+ yield "</table></body></html>\n"
75
+ end
76
+ end
77
+ end
78
+
79
+ class EachAt < Struct.new(:loc) # :nodoc:
80
+ include HtmlResponse
81
+ HEADER = '<tr><th>size</th><th>generation</th></tr>'
82
+
83
+ def each
84
+ t = loc.name.encode(xml: :text)
85
+ yield(-"<html><head><title>#{t}</title></head>" \
86
+ "<body><h1>live allocations at #{t}</h1>" \
87
+ "<h2>Current generation: #{GC.count}</h2>\n<table>#{HEADER}")
88
+ loc.each do |size, generation|
89
+ yield("<tr><td>#{size}</td><td>#{generation}</td></tr>\n")
90
+ end
91
+ yield "</table></body></html>\n"
92
+ end
93
+ end
94
+
95
+ def r404 # :nodoc:
96
+ [404,{'Content-Type'=>'text/plain'},["Not found\n"]]
97
+ end
98
+
99
+ # The standard Rack application endpoint for MwrapRack
100
+ def call(env)
101
+ case env['PATH_INFO']
102
+ when %r{\A/each/(\d+)\z}
103
+ min = $1.to_i
104
+ m = env['QUERY_STRING'].match(/\bsort=(\w+)/)
105
+ Each.new(env['SCRIPT_NAME'], min, m ? m[1] : nil).response
106
+ when %r{\A/at/(.*)\z}
107
+ loc = -CGI.unescape($1)
108
+ loc = Mwrap[loc] or return r404
109
+ EachAt.new(loc).response
110
+ when '/'
111
+ n = 2000
112
+ u = 'https://80x24.org/mwrap/README.html'
113
+ b = -('<html><head><title>Mwrap demo</title></head>' \
114
+ "<body><p><a href=\"each/#{n}\">allocations &gt;#{n} bytes</a>" \
115
+ "<p><a href=\"#{u}\">#{u}</a></body></html>\n")
116
+ [ 200, {'Content-Type'=>'text/html','Content-Length'=>-b.size.to_s},[b]]
117
+ else
118
+ r404
119
+ end
120
+ end
121
+ end
data/mwrap.gemspec CHANGED
@@ -8,9 +8,11 @@ if git_manifest[0] && manifest != git_manifest
8
8
  system('git add MANIFEST')
9
9
  end
10
10
 
11
+ desc = `git describe --abbrev=4 HEAD`.strip.tr('-', '.').delete_prefix('v')
12
+
11
13
  Gem::Specification.new do |s|
12
14
  s.name = 'mwrap'
13
- s.version = '2.0.0'
15
+ s.version = desc.empty? ? '2.0.0' : desc
14
16
  s.homepage = 'https://80x24.org/mwrap/'
15
17
  s.authors = ["Ruby hackers"]
16
18
  s.summary = 'LD_PRELOAD malloc wrapper for Ruby'
data/test/test_mwrap.rb CHANGED
@@ -272,4 +272,15 @@ class TestMwrap < Test::Unit::TestCase
272
272
  res == :foo or abort 'Mwrap.quiet did not return block result'
273
273
  end;
274
274
  end
275
+
276
+ def test_total_bytes
277
+ assert_separately(+"#{<<~"begin;"}\n#{<<~'end;'}")
278
+ begin;
279
+ require 'mwrap'
280
+ Mwrap.total_bytes_allocated > 0 or abort 'nothing allocated'
281
+ Mwrap.total_bytes_freed > 0 or abort 'nothing freed'
282
+ Mwrap.total_bytes_allocated > Mwrap.total_bytes_freed or
283
+ abort 'freed more than allocated'
284
+ end;
285
+ end
275
286
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mwrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.0.4.gd1ea
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruby hackers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-20 00:00:00.000000000 Z
11
+ date: 2018-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -50,6 +50,7 @@ extra_rdoc_files: []
50
50
  files:
51
51
  - ".document"
52
52
  - ".gitignore"
53
+ - ".olddoc.yml"
53
54
  - COPYING
54
55
  - MANIFEST
55
56
  - README
@@ -58,6 +59,7 @@ files:
58
59
  - ext/mwrap/extconf.rb
59
60
  - ext/mwrap/jhash.h
60
61
  - ext/mwrap/mwrap.c
62
+ - lib/mwrap_rack.rb
61
63
  - mwrap.gemspec
62
64
  - test/test_mwrap.rb
63
65
  homepage: https://80x24.org/mwrap/
@@ -75,9 +77,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
77
  version: '0'
76
78
  required_rubygems_version: !ruby/object:Gem::Requirement
77
79
  requirements:
78
- - - ">="
80
+ - - ">"
79
81
  - !ruby/object:Gem::Version
80
- version: '0'
82
+ version: 1.3.1
81
83
  requirements: []
82
84
  rubyforge_project:
83
85
  rubygems_version: 2.7.7