mwrap 2.1.0 → 2.2.0

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: abf683546f4fb8c006364863d126489983a232239dce12e98ab006a667a24220
4
- data.tar.gz: 3d23cf41c24d12f9e0422179c92389d63f90219307f9c7dfe71104cfd67e6060
3
+ metadata.gz: 406933abeb7d63d1304c63f0f5aa7a2f4deb9ecb1820816886df8bfcf2d01601
4
+ data.tar.gz: 214975358778869db55691d8ddcac9e078cc16be6870e143094bb837d88551eb
5
5
  SHA512:
6
- metadata.gz: 2617b3932aeb6b7b3cd72fba57b0d87513b45dee6b79c5a9c3bdf9b331e9e06757cc1c896840c8111a6f6d223cbf4fdad4d3ef4b64d8e97b3502f96e48864ed9
7
- data.tar.gz: 6eaab1b74b63c5800e0fd151a5662e3095d12f56ad228302aa8d0d733634e34e0ce3aa824003a06cc09414820660414cc21032afbf38a9eaa1c8805bd65a6000
6
+ metadata.gz: a0a353c1ed720192b6dc63699d7d53661fc80c204429df3c93d4795b39cdec1d0e1b83c90e4250ddee11abd1911d578dd4f83516368a787a21fb1327de0ac32b
7
+ data.tar.gz: 28fd47f870ec74cd4c15570e6f6df0b9ee80ff30eb460185f841d2bc796836dd8aa6d82a7e3304bf811d22acc2dfb3e00fa4f92143a0cbb04dbd78e99ae7231e
data/.document CHANGED
@@ -1,2 +1,3 @@
1
1
  ext/mwrap/mwrap.c
2
2
  lib/mwrap_rack.rb
3
+ README
data/.gitignore CHANGED
@@ -4,3 +4,6 @@
4
4
  /pkg
5
5
  /*.gem
6
6
  /doc
7
+ /NEWS
8
+ /NEWS.atom.xml
9
+ /LATEST
data/.olddoc.yml CHANGED
@@ -5,4 +5,6 @@ rdoc_url: https://80x24.org/mwrap/
5
5
  ml_url: https://80x24.org/mwrap-public/
6
6
  public_email: mwrap-public@80x24.org
7
7
  nntp_url:
8
- - nntp://news.public-inbox.org/inbox.comp.lang.ruby.mwrap
8
+ - nntps://news.public-inbox.org/inbox.comp.lang.ruby.mwrap
9
+ imap_url:
10
+ - imaps://;AUTH=ANONYMOUS@80x24.org/inbox.comp.lang.ruby.mwrap.0
data/README CHANGED
@@ -67,16 +67,18 @@ first two columns to find the hottest malloc locations.
67
67
  mwrap 2.0.0+ also supports a Rack application endpoint,
68
68
  it is documented at:
69
69
 
70
- https://80x24.org/mwrap/MwrapRack.html
70
+ https://80x24.org/mwrap/MwrapRack.html
71
71
 
72
72
  == Known problems
73
73
 
74
74
  * 32-bit machines are prone to overflow (WONTFIX)
75
75
 
76
- == Mail archives and list:
76
+ == Public mail archives and contact info:
77
77
 
78
- https://80x24.org/mwrap-public/
79
- nntp://80x24.org/inbox.comp.lang.ruby.mwrap
78
+ * https://80x24.org/mwrap-public/
79
+ * nntps://80x24.org/inbox.comp.lang.ruby.mwrap
80
+ * imaps://;AUTH=ANONYMOUS@80x24.org/inbox.comp.lang.ruby.mwrap.0
81
+ * https://80x24.org/mwrap-public/_/text/help/#pop3
80
82
 
81
83
  No subscription will ever be required to post, but HTML mail
82
84
  will be rejected:
@@ -88,7 +90,7 @@ will be rejected:
88
90
  git clone https://80x24.org/mwrap.git
89
91
 
90
92
  Send all patches and pull requests (use "git request-pull" to format) to
91
- the mailing list. We do not use centralized or proprietary messaging
93
+ mwrap-public@80x24.org. We do not use centralized or proprietary messaging
92
94
  systems.
93
95
 
94
96
  == License
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2018 mwrap hackers <mwrap-public@80x24.org>
1
+ # Copyright (C) mwrap hackers <mwrap-public@80x24.org>
2
2
  # License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
3
3
  require 'rake/testtask'
4
4
  begin
@@ -14,3 +14,31 @@ task :default => :compile
14
14
 
15
15
  c_files = File.readlines('MANIFEST').grep(%r{ext/.*\.[ch]$}).map!(&:chomp!)
16
16
  task 'compile:mwrap' => c_files
17
+
18
+ olddoc = ENV['OLDDOC'] || 'olddoc'
19
+ rdoc = ENV['RDOC'] || 'rdoc'
20
+ task :rsync_docs do
21
+ require 'fileutils'
22
+ top = %w(README COPYING LATEST NEWS NEWS.atom.xml)
23
+ system("git", "set-file-times")
24
+ dest = ENV["RSYNC_DEST"] || "80x24.org:/srv/80x24/mwrap/"
25
+ FileUtils.rm_rf('doc')
26
+ sh "#{olddoc} prepare"
27
+ sh "#{rdoc} -f dark216" # dark216 requires olddoc 1.7+
28
+ File.unlink('doc/created.rid') rescue nil
29
+ File.unlink('doc/index.html') rescue nil
30
+ FileUtils.cp(top, 'doc')
31
+ sh "#{olddoc} merge"
32
+
33
+ Dir['doc/**/*'].each do |txt|
34
+ st = File.stat(txt)
35
+ if st.file?
36
+ gz = "#{txt}.gz"
37
+ tmp = "#{gz}.#$$"
38
+ sh("gzip --rsyncable -9 <#{txt} >#{tmp}")
39
+ File.utime(st.atime, st.mtime, tmp) # make nginx gzip_static happy
40
+ File.rename(tmp, gz)
41
+ end
42
+ end
43
+ sh("rsync --chmod=Fugo=r #{ENV['RSYNC_OPT']} -av doc/ #{dest}/")
44
+ end
data/bin/mwrap CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
  # frozen_string_literal: true
3
- # Copyright (C) 2018 mwrap hackers <mwrap-public@80x24.org>
3
+ # Copyright (C) mwrap hackers <mwrap-public@80x24.org>
4
4
  # License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
5
5
  require 'mwrap'
6
6
  mwrap_so = $".grep(%r{/mwrap\.so\z})[0] or abort "mwrap.so not loaded"
data/ext/mwrap/extconf.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # Copyright (C) 2018 mwrap hackers <mwrap-public@80x24.org>
2
+ # Copyright (C) mwrap hackers <mwrap-public@80x24.org>
3
3
  # License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
4
4
  require 'mkmf'
5
5
 
@@ -25,4 +25,11 @@ else
25
25
  abort 'missing __builtin_add_overflow'
26
26
  end
27
27
 
28
+ begin
29
+ if n = GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE]
30
+ $defs << "-DHEAP_PAGE_SIZE=#{n}"
31
+ end
32
+ rescue NameError
33
+ end
34
+
28
35
  create_makefile 'mwrap'
data/ext/mwrap/mwrap.c CHANGED
@@ -1,9 +1,9 @@
1
1
  /*
2
- * Copyright (C) 2018 mwrap hackers <mwrap-public@80x24.org>
2
+ * Copyright (C) mwrap hackers <mwrap-public@80x24.org>
3
3
  * License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
4
4
  */
5
5
  #define _LGPL_SOURCE /* allows URCU to inline some stuff */
6
- #include <ruby/ruby.h>
6
+ #include <ruby.h> /* defines HAVE_RUBY_RACTOR_H on 3.0+ */
7
7
  #include <ruby/thread.h>
8
8
  #include <ruby/io.h>
9
9
  #include <execinfo.h>
@@ -22,10 +22,24 @@
22
22
  #include <urcu/rculist.h>
23
23
  #include "jhash.h"
24
24
 
25
+ #if __STDC_VERSION__ >= 201112
26
+ # define MWRAP_TSD _Thread_local
27
+ #elif defined(__GNUC__)
28
+ # define MWRAP_TSD __thread
29
+ #else
30
+ # error _Thread_local nor __thread supported
31
+ #endif
32
+
25
33
  static ID id_uminus;
26
34
  const char *rb_source_location_cstr(int *line); /* requires 2.6.0dev */
27
35
  extern int __attribute__((weak)) ruby_thread_has_gvl_p(void);
36
+
37
+ #ifdef HAVE_RUBY_RACTOR_H /* Ruby 3.0+ */
38
+ extern MWRAP_TSD void * __attribute__((weak)) ruby_current_ec;
39
+ #else /* Ruby 2.6-2.7 */
28
40
  extern void * __attribute__((weak)) ruby_current_execution_context_ptr;
41
+ # define ruby_current_ec ruby_current_execution_context_ptr
42
+ #endif
29
43
  extern void * __attribute__((weak)) ruby_current_vm_ptr; /* for rb_gc_count */
30
44
  extern size_t __attribute__((weak)) rb_gc_count(void);
31
45
  extern VALUE __attribute__((weak)) rb_cObject;
@@ -40,9 +54,12 @@ static size_t total_bytes_inc, total_bytes_dec;
40
54
  /* match values in Ruby gc.c */
41
55
  #define HEAP_PAGE_ALIGN_LOG 14
42
56
  enum {
43
- HEAP_PAGE_ALIGN = (1UL << HEAP_PAGE_ALIGN_LOG),
57
+ HEAP_PAGE_ALIGN = (1UL << HEAP_PAGE_ALIGN_LOG)
58
+ #ifndef HEAP_PAGE_SIZE /* Ruby 2.6-2.7 only */
59
+ ,
44
60
  REQUIRED_SIZE_BY_MALLOC = (sizeof(size_t) * 5),
45
61
  HEAP_PAGE_SIZE = (HEAP_PAGE_ALIGN - REQUIRED_SIZE_BY_MALLOC)
62
+ #endif
46
63
  };
47
64
 
48
65
  #define IS_HEAP_PAGE_BODY ((struct src_loc *)-1)
@@ -75,7 +92,7 @@ static int resolving_malloc;
75
92
  } \
76
93
  } while (0)
77
94
 
78
- static __thread size_t locating;
95
+ static MWRAP_TSD size_t locating;
79
96
  static size_t generation;
80
97
  static size_t page_size;
81
98
  static struct cds_lfht *totals;
@@ -139,8 +156,8 @@ __attribute__((constructor)) static void resolve_malloc(void)
139
156
  _exit(1);
140
157
  }
141
158
  #endif /* !FreeBSD */
142
- totals = lfht_new();
143
- if (!totals)
159
+ CMM_STORE_SHARED(totals, lfht_new());
160
+ if (!CMM_LOAD_SHARED(totals))
144
161
  fprintf(stderr, "failed to allocate totals table\n");
145
162
 
146
163
  err = pthread_atfork(call_rcu_before_fork,
@@ -152,11 +169,18 @@ __attribute__((constructor)) static void resolve_malloc(void)
152
169
  --locating;
153
170
  }
154
171
 
172
+ #ifdef NDEBUG
173
+ #define QUIET_CC_WARNING(var) (void)var;
174
+ #else
175
+ #define QUIET_CC_WARNING(var)
176
+ #endif
177
+
155
178
  static void
156
179
  mutex_lock(pthread_mutex_t *m)
157
180
  {
158
181
  int err = pthread_mutex_lock(m);
159
182
  assert(err == 0);
183
+ QUIET_CC_WARNING(err)
160
184
  }
161
185
 
162
186
  static void
@@ -164,6 +188,7 @@ mutex_unlock(pthread_mutex_t *m)
164
188
  {
165
189
  int err = pthread_mutex_unlock(m);
166
190
  assert(err == 0);
191
+ QUIET_CC_WARNING(err)
167
192
  }
168
193
 
169
194
  #ifndef HAVE_MEMPCPY
@@ -214,7 +239,7 @@ static char *int2str(int num, char *dst, size_t * size)
214
239
  static int has_ec_p(void)
215
240
  {
216
241
  return (ruby_thread_has_gvl_p() && ruby_current_vm_ptr &&
217
- ruby_current_execution_context_ptr);
242
+ ruby_current_ec);
218
243
  }
219
244
 
220
245
  struct acc {
@@ -367,7 +392,7 @@ acc_stddev(const struct acc *acc)
367
392
  return DBL2NUM(acc_stddev_dbl(acc));
368
393
  }
369
394
 
370
- static struct src_loc *totals_add_rcu(struct src_loc *k)
395
+ static struct src_loc *totals_add_rcu(const struct src_loc *k)
371
396
  {
372
397
  struct cds_lfht_iter iter;
373
398
  struct cds_lfht_node *cur;
@@ -375,7 +400,7 @@ static struct src_loc *totals_add_rcu(struct src_loc *k)
375
400
  struct cds_lfht *t;
376
401
 
377
402
  again:
378
- t = rcu_dereference(totals);
403
+ t = CMM_LOAD_SHARED(totals);
379
404
  if (!t) goto out_unlock;
380
405
  cds_lfht_lookup(t, k->hval, loc_eq, k, &iter);
381
406
  cur = cds_lfht_iter_get_node(&iter);
@@ -417,7 +442,7 @@ static struct src_loc *update_stats_rcu_lock(size_t size, uintptr_t caller)
417
442
  static const size_t xlen = sizeof(caller);
418
443
  char *dst;
419
444
 
420
- if (caa_unlikely(!totals)) return 0;
445
+ if (caa_unlikely(!CMM_LOAD_SHARED(totals))) return 0;
421
446
  if (locating++) goto out; /* do not recurse into another *alloc */
422
447
 
423
448
  uatomic_add(&total_bytes_inc, size);
@@ -632,9 +657,9 @@ internal_memalign(void **pp, size_t alignment, size_t size, uintptr_t caller)
632
657
  p = ptr_align(p, alignment);
633
658
  h = ptr2hdr(p);
634
659
  alloc_insert_rcu(l, h, size, real);
635
- update_stats_rcu_unlock(l);
636
660
  *pp = p;
637
661
  }
662
+ update_stats_rcu_unlock(l);
638
663
  }
639
664
 
640
665
  return real ? 0 : ENOMEM;
@@ -643,16 +668,14 @@ internal_memalign(void **pp, size_t alignment, size_t size, uintptr_t caller)
643
668
  static void *
644
669
  memalign_result(int err, void *p)
645
670
  {
646
- if (caa_unlikely(err)) {
671
+ if (caa_unlikely(err))
647
672
  errno = err;
648
- return 0;
649
- }
650
673
  return p;
651
674
  }
652
675
 
653
676
  void *memalign(size_t alignment, size_t size)
654
677
  {
655
- void *p;
678
+ void *p = NULL;
656
679
  int err = internal_memalign(&p, alignment, size, RETURN_ADDRESS(0));
657
680
  return memalign_result(err, p);
658
681
  }
@@ -667,7 +690,7 @@ void cfree(void *) __attribute__((alias("free")));
667
690
 
668
691
  void *valloc(size_t size)
669
692
  {
670
- void *p;
693
+ void *p = NULL;
671
694
  int err = internal_memalign(&p, page_size, size, RETURN_ADDRESS(0));
672
695
  return memalign_result(err, p);
673
696
  }
@@ -685,7 +708,7 @@ void *valloc(size_t size)
685
708
  void *pvalloc(size_t size)
686
709
  {
687
710
  size_t alignment = page_size;
688
- void *p;
711
+ void *p = NULL;
689
712
  int err;
690
713
 
691
714
  if (add_overflow_p(size, alignment)) {
@@ -808,7 +831,7 @@ static void *dump_to_file(void *x)
808
831
 
809
832
  ++locating;
810
833
  rcu_read_lock();
811
- t = rcu_dereference(totals);
834
+ t = CMM_LOAD_SHARED(totals);
812
835
  if (!t)
813
836
  goto out_unlock;
814
837
  cds_lfht_for_each_entry(t, &iter, l, hnode) {
@@ -877,7 +900,7 @@ static void *totals_reset(void *ign)
877
900
  uatomic_set(&total_bytes_dec, 0);
878
901
 
879
902
  rcu_read_lock();
880
- t = rcu_dereference(totals);
903
+ t = CMM_LOAD_SHARED(totals);
881
904
  cds_lfht_for_each_entry(t, &iter, l, hnode) {
882
905
  uatomic_set(&l->total, 0);
883
906
  uatomic_set(&l->allocations, 0);
@@ -945,7 +968,7 @@ static VALUE dump_each_rcu(VALUE x)
945
968
  struct cds_lfht_iter iter;
946
969
  struct src_loc *l;
947
970
 
948
- t = rcu_dereference(totals);
971
+ t = CMM_LOAD_SHARED(totals);
949
972
  cds_lfht_for_each_entry(t, &iter, l, hnode) {
950
973
  VALUE v[6];
951
974
  if (l->total <= a->min) continue;
@@ -1049,9 +1072,9 @@ static VALUE mwrap_aref(VALUE mod, VALUE loc)
1049
1072
 
1050
1073
  if (!k) return val;
1051
1074
 
1075
+ t = CMM_LOAD_SHARED(totals);
1076
+ if (!t) return val;
1052
1077
  rcu_read_lock();
1053
- t = rcu_dereference(totals);
1054
- if (!t) goto out_unlock;
1055
1078
 
1056
1079
  cds_lfht_lookup(t, k->hval, loc_eq, k, &iter);
1057
1080
  cur = cds_lfht_iter_get_node(&iter);
@@ -1059,7 +1082,6 @@ static VALUE mwrap_aref(VALUE mod, VALUE loc)
1059
1082
  l = caa_container_of(cur, struct src_loc, hnode);
1060
1083
  val = TypedData_Wrap_Struct(cSrcLoc, &src_loc_type, l);
1061
1084
  }
1062
- out_unlock:
1063
1085
  rcu_read_unlock();
1064
1086
  return val;
1065
1087
  }
data/lib/mwrap_rack.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2018 all contributors <mwrap@80x24.org>
1
+ # Copyright (C) all contributors <mwrap-public@80x24.org>
2
2
  # License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
3
3
  # frozen_string_literal: true
4
4
  require 'mwrap'
@@ -17,9 +17,6 @@ require 'cgi'
17
17
  # map('/MWRAP') { run(MwrapRack.new) }
18
18
  # map('/') { run(your_normal_app) }
19
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
20
  # This module is only available in mwrap 2.0.0+
24
21
  class MwrapRack
25
22
  module HtmlResponse # :nodoc:
@@ -115,10 +112,11 @@ class MwrapRack
115
112
  end
116
113
 
117
114
  GC_STAT_URL = 'https://docs.ruby-lang.org/en/trunk/GC.html#method-c-stat'
118
- GC_STAT_HELP = <<~""
115
+ GC_STAT_HELP = <<~EOM
119
116
  <p>Non-Infinity lifespans can indicate fragmentation.
120
117
  <p>See <a
121
118
  href="#{GC_STAT_URL}">#{GC_STAT_URL}</a> for info on GC.stat values.
119
+ EOM
122
120
 
123
121
  def each
124
122
  Mwrap.quiet do
data/mwrap.gemspec CHANGED
@@ -12,9 +12,9 @@ desc = `git describe --abbrev=4 HEAD`.strip.tr('-', '.').delete_prefix('v')
12
12
 
13
13
  Gem::Specification.new do |s|
14
14
  s.name = 'mwrap'
15
- s.version = desc.empty? ? '2.1.0' : desc
15
+ s.version = desc.empty? ? '2.2.0' : desc
16
16
  s.homepage = 'https://80x24.org/mwrap/'
17
- s.authors = ["Ruby hackers"]
17
+ s.authors = ["mwrap hackers"]
18
18
  s.summary = 'LD_PRELOAD malloc wrapper for Ruby'
19
19
  s.executables = %w(mwrap)
20
20
  s.files = manifest
data/test/test_mwrap.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # Copyright (C) 2018 mwrap hackers <mwrap-public@80x24.org>
2
+ # Copyright (C) mwrap hackers <mwrap-public@80x24.org>
3
3
  # License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
4
4
  require 'test/unit'
5
5
  require 'mwrap'
@@ -29,7 +29,8 @@ class TestMwrap < Test::Unit::TestCase
29
29
  tmp.rewind
30
30
  lines = tmp.readlines
31
31
  line_1 = lines.grep(/\s-e:1\b/)[0].strip
32
- assert_equal '10001', line_1.split(/\s+/)[0]
32
+ bytes = line_1.split(/\s+/)[0].to_i
33
+ assert_operator bytes, :>=, 10001
33
34
  end
34
35
  end
35
36
 
@@ -42,7 +43,7 @@ class TestMwrap < Test::Unit::TestCase
42
43
  res = system(env, *cmd, { 5 => tmp })
43
44
  assert res, $?.inspect
44
45
  tmp.rewind
45
- assert_match(/\b10001\s+1\s+-e:1$/, tmp.read)
46
+ assert_match(/\b1\d{4}\s+[1-9]\d*\s+-e:1$/, tmp.read)
46
47
 
47
48
  env['MWRAP'] = 'dump_fd:1,dump_min:10000'
48
49
  tmp.rewind
@@ -50,14 +51,14 @@ class TestMwrap < Test::Unit::TestCase
50
51
  res = system(env, *cmd, { 1 => tmp })
51
52
  assert res, $?.inspect
52
53
  tmp.rewind
53
- assert_match(/\b10001\s+1\s+-e:1$/, tmp.read)
54
+ assert_match(/\b1\d{4}\s+[1-9]\d*\s+-e:1$/, tmp.read)
54
55
 
55
56
  tmp.rewind
56
57
  tmp.truncate(0)
57
58
  env['MWRAP'] = "dump_path:#{tmp.path},dump_min:10000"
58
59
  res = system(env, *cmd)
59
60
  assert res, $?.inspect
60
- assert_match(/\b10001\s+1\s+-e:1$/, tmp.read)
61
+ assert_match(/\b1\d{4}\s+[1-9]\d*\s+-e:1$/, tmp.read)
61
62
 
62
63
  tmp.rewind
63
64
  tmp.truncate(0)
@@ -98,7 +99,7 @@ class TestMwrap < Test::Unit::TestCase
98
99
  tmp.rewind
99
100
  buf = tmp.read
100
101
  assert_not_match(/\s+-e:1$/, buf)
101
- assert_match(/\b20001\s+1\s+-e:3$/, buf)
102
+ assert_match(/\b2\d{4}\s+[0-9]\d*\s+-e:3$/, buf)
102
103
  end
103
104
  end
104
105
 
@@ -176,8 +177,8 @@ class TestMwrap < Test::Unit::TestCase
176
177
  -e GC.disable
177
178
  -e keep=("0"*10000)
178
179
  -e loc=Mwrap["-e:3"]
179
- -e loc.each{|size,gen|p([size,gen,count])}
180
- )
180
+ -e
181
+ ) + [ 'loc.each{|size,gen|p([size,gen,count]) if size > 10000}' ]
181
182
  buf = IO.popen(@@env, cmd, &:read)
182
183
  assert_predicate $?, :success?
183
184
  assert_match(/\A\[\s*\d+,\s*\d+,\s*\d+\]\s*\z/s, buf)
@@ -230,7 +231,8 @@ class TestMwrap < Test::Unit::TestCase
230
231
  loc.name == k or abort 'SourceLocation#name broken'
231
232
  loc.total >= 10000 or abort 'SourceLocation#total broken'
232
233
  loc.frees == 0 or abort 'SourceLocation#frees broken'
233
- loc.allocations == 1 or abort 'SourceLocation#allocations broken'
234
+ loc.allocations >= 1 or
235
+ abort "SourceLocation#allocations broken: #{loc.allocations}"
234
236
  seen = false
235
237
  loc.each do |*x| seen = x end
236
238
  seen[1] == loc.total or 'SourceLocation#each broken'
@@ -240,7 +242,9 @@ class TestMwrap < Test::Unit::TestCase
240
242
  freed = false
241
243
  until freed
242
244
  freed = true
243
- loc.each do freed = false end
245
+ loc.each do |size, gen|
246
+ freed = false if size >= 10000
247
+ end
244
248
  end
245
249
  loc.frees == 1 or abort 'SourceLocation#frees broken (after free)'
246
250
  Float === loc.mean_lifespan or abort 'mean_lifespan broken'
@@ -264,8 +268,9 @@ class TestMwrap < Test::Unit::TestCase
264
268
  assert_separately(+"#{<<~"begin;"}\n#{<<~'end;'}")
265
269
  begin;
266
270
  require 'mwrap'
267
- before = __LINE__
271
+ before = nil
268
272
  res = Mwrap.quiet do |depth|
273
+ before = __LINE__
269
274
  depth == 1 or abort 'depth is not 1'
270
275
  ('a' * 10000).clear
271
276
  Mwrap.quiet { |d| d == 2 or abort 'depth is not 2' }
@@ -304,7 +309,9 @@ class TestMwrap < Test::Unit::TestCase
304
309
  gen <= GC.count && gen >= 0 or abort "bad generation: #{gen}"
305
310
  (0 == (addr & 16383)) or abort "addr not aligned: #{'%x' % addr}"
306
311
  end
307
- nr == ap or abort 'HeapPageBody.each missed page'
312
+ if RUBY_VERSION.to_f < 3.1 # 3.1+ uses mmap on platforms we care about
313
+ nr == ap or abort "HeapPageBody.each missed page #{nr} != #{ap}"
314
+ end
308
315
  10.times { (1..20000).to_a.map(&:to_s) }
309
316
  3.times { GC.start }
310
317
  Mwrap::HeapPageBody.stat(h)
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.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - Ruby hackers
7
+ - mwrap hackers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-11 00:00:00.000000000 Z
11
+ date: 2022-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -81,8 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  requirements: []
84
- rubyforge_project:
85
- rubygems_version: 2.7.7
84
+ rubygems_version: 3.0.2
86
85
  signing_key:
87
86
  specification_version: 4
88
87
  summary: LD_PRELOAD malloc wrapper for Ruby