mwrap 2.1.0 → 2.2.0

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: 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