]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix finalizer flakiness
authorRuss Cox <rsc@golang.org>
Tue, 4 Mar 2014 14:46:40 +0000 (09:46 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 4 Mar 2014 14:46:40 +0000 (09:46 -0500)
The flakiness appears to be just in tests, not in the actual code.
Specifically, the many tests call runtime.GC once and expect that
the finalizers will be running in the background when GC returns.
Now that the sweep phase is concurrent with execution, however,
the finalizers will not be run until sweep finishes, which might
be quite a bit later. To force sweep to finish, implement runtime.GC
by calling the actual collection twice. The second will complete the
sweep from the first.

This was reliably broken after a few runs before the CL and now
passes tens of runs:

while GOMAXPROCS=2 ./runtime.test -test.run=Finalizer -test.short \
        -test.timeout=300s -test.cpu=$(perl -e 'print ("1,2,4," x 100) . "1"')
do true; done

Fixes #7328.

LGTM=dvyukov
R=dvyukov, dave
CC=golang-codereviews
https://golang.org/cl/71080043

src/pkg/runtime/malloc.goc

index 07ca9aa1d450c82d0cab266ab6d2dd103a6c3cee..0470211506df5b57d35e18fccac7db3a0c0a813a 100644 (file)
@@ -803,6 +803,15 @@ runtime·cnewarray(Type *typ, intgo n)
 }
 
 func GC() {
+       // We assume that the user expects unused memory to have
+       // been freed when GC returns. To ensure this, run gc(1) twice.
+       // The first will do a collection, and the second will force the
+       // first's sweeping to finish before doing a second collection.
+       // The second collection is overkill, but we assume the user
+       // has a good reason for calling runtime.GC and can stand the
+       // expense. At the least, this fixes all the calls to runtime.GC in
+       // tests that expect finalizers to start running when GC returns.
+       runtime·gc(1);
        runtime·gc(1);
 }