diff options
Diffstat (limited to 'testsuite')
-rw-r--r-- | testsuite/tests/rts/Makefile | 4 | ||||
-rw-r--r-- | testsuite/tests/rts/all.T | 7 | ||||
-rw-r--r-- | testsuite/tests/rts/outofmem.stderr-ws-64 | 2 | ||||
-rw-r--r-- | testsuite/tests/rts/outofmem.stdout | 2 | ||||
-rw-r--r-- | testsuite/tests/rts/testmblockalloc.c | 75 |
5 files changed, 86 insertions, 4 deletions
diff --git a/testsuite/tests/rts/Makefile b/testsuite/tests/rts/Makefile index 5e5782a3cb..52de19c876 100644 --- a/testsuite/tests/rts/Makefile +++ b/testsuite/tests/rts/Makefile @@ -7,14 +7,14 @@ outofmem-prep:: outofmem:: @$(MAKE) outofmem-prep - @ulimit -v 10000000 2>/dev/null; ./outofmem || echo "exit($$?)" + @ulimit -m 10000000 2>/dev/null; ./outofmem || echo "exit($$?)" outofmem2-prep:: '$(TEST_HC)' $(TEST_HC_OPTS) -v0 -rtsopts --make -fforce-recomp outofmem2.hs -o outofmem2 outofmem2:: @$(MAKE) outofmem2-prep - @ulimit -v 1000000 2>/dev/null; ./outofmem2 +RTS -M5m -RTS || echo "exit($$?)" + @ulimit -m 1000000 2>/dev/null; ./outofmem2 +RTS -M5m -RTS || echo "exit($$?)" T2615-prep: $(RM) libfoo_T2615.so diff --git a/testsuite/tests/rts/all.T b/testsuite/tests/rts/all.T index 5be36349d0..0e891e8f1b 100644 --- a/testsuite/tests/rts/all.T +++ b/testsuite/tests/rts/all.T @@ -2,6 +2,13 @@ test('testblockalloc', [c_src, only_ways(['normal','threaded1']), extra_run_opts('+RTS -I0')], compile_and_run, ['']) +test('testmblockalloc', + [c_src, only_ways(['normal','threaded1']), extra_run_opts('+RTS -I0')], + compile_and_run, ['']) +# -I0 is important: the idle GC will run the memory leak detector, +# which will crash because the mblocks we allocate are not in a state +# the leak detector is expecting. + # See bug #101, test requires +RTS -c (or equivalently +RTS -M<something>) # only GHCi triggers the bug, but we run the test all ways for completeness. diff --git a/testsuite/tests/rts/outofmem.stderr-ws-64 b/testsuite/tests/rts/outofmem.stderr-ws-64 index 42a4696fcf..dca02c7ed8 100644 --- a/testsuite/tests/rts/outofmem.stderr-ws-64 +++ b/testsuite/tests/rts/outofmem.stderr-ws-64 @@ -1 +1 @@ -outofmem: out of memory (requested 2148532224 bytes) +outofmem: out of memory diff --git a/testsuite/tests/rts/outofmem.stdout b/testsuite/tests/rts/outofmem.stdout index 63a3a6988c..1acdde769d 100644 --- a/testsuite/tests/rts/outofmem.stdout +++ b/testsuite/tests/rts/outofmem.stdout @@ -1 +1 @@ -exit(1) +exit(251) diff --git a/testsuite/tests/rts/testmblockalloc.c b/testsuite/tests/rts/testmblockalloc.c new file mode 100644 index 0000000000..df03658387 --- /dev/null +++ b/testsuite/tests/rts/testmblockalloc.c @@ -0,0 +1,75 @@ +#include "Rts.h" + +#include <stdio.h> + +// 16 * 64 == max 1GB +const int MAXALLOC = 16; +const int ARRSIZE = 64; + +const int LOOPS = 1000; +const int SEED = 0xf00f00; + +extern lnat mblocks_allocated; + +int main (int argc, char *argv[]) +{ + int i, j, b; + + void *a[ARRSIZE]; + nat sizes[ARRSIZE]; + + srand(SEED); + + { + RtsConfig conf = defaultRtsConfig; + conf.rts_opts_enabled = RtsOptsAll; + hs_init_ghc(&argc, &argv, conf); + } + + // repeatedly sweep though the array, allocating new random-sized + // objects and deallocating the old ones. + for (i=0; i < LOOPS; i++) + { + for (j=0; j < ARRSIZE; j++) + { + if (i > 0) + { + freeMBlocks(a[j], sizes[j]); + } + b = (rand() % MAXALLOC) + 1; + a[j] = getMBlocks(b); + sizes[j] = b; + } + } + + releaseFreeMemory(); + + for (j=0; j < ARRSIZE; j++) + { + freeMBlocks(a[j], sizes[j]); + } + + releaseFreeMemory(); + + // this time, sweep forwards allocating new blocks, and then + // backwards deallocating them. + for (i=0; i < LOOPS; i++) + { + for (j=0; j < ARRSIZE; j++) + { + b = (rand() % MAXALLOC) + 1; + a[j] = getMBlocks(b); + sizes[j] = b; + } + for (j=ARRSIZE-1; j >= 0; j--) + { + freeMBlocks(a[j], sizes[j]); + } + } + + releaseFreeMemory(); + + hs_exit(); // will do a memory leak test + + exit(0); +} |