diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2018-04-26 10:54:52 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2018-04-26 10:54:52 +0300 |
commit | b59413253fa0204d6897a05193c58c42ee0c029c (patch) | |
tree | e37457266e42ef8ff700171da80885bb33489d83 /mach_dep.c | |
parent | fcdd0bbabdf112e5bcd8882620877f868b9810ee (diff) | |
download | bdwgc-b59413253fa0204d6897a05193c58c42ee0c029c.tar.gz |
Avoid multiple 'getcontext failed' warnings if getcontext is broken
Issue #133 (bdwgc).
* mach_dep.c [!HAVE_PUSH_REGS && UNIX_LIKE && !NO_GETCONTEXT]
(GC_with_callee_saves_pushed): Define getcontext_works static variable;
do not call getcontext() if getcontext_works < 0; add comment; set
getcontext_works to 1 or -1 (depending whether getcontext is working)
if getcontext_works is zero.
* misc.c [THREADS && UNIX_LIKE && !NO_GETCONTEXT]
(callee_saves_pushed_dummy_fn): New static function (empty).
* misc.c [THREADS && UNIX_LIKE && !NO_GETCONTEXT] (GC_init): Call
GC_with_callee_saves_pushed(callee_saves_pushed_dummy_fn) if GC_dont_gc
or GC_dont_precollect (otherwise it is called by GC_gcollect_inner);
add comment.
Diffstat (limited to 'mach_dep.c')
-rw-r--r-- | mach_dep.c | 18 |
1 files changed, 12 insertions, 6 deletions
@@ -237,6 +237,7 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *), /* Older versions of Darwin seem to lack getcontext(). */ /* ARM and MIPS Linux often doesn't support a real */ /* getcontext(). */ + static signed char getcontext_works = 0; /* (-1) - broken, 1 - works */ ucontext_t ctxt; # ifdef GETCONTEXT_FPU_EXCMASK_BUG /* Workaround a bug (clearing the FPU exception mask) in */ @@ -255,12 +256,17 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *), # endif # endif - if (getcontext(&ctxt) < 0) { - WARN("getcontext failed:" - " using another register retrieval method...\n", 0); - /* E.g., to workaround a bug in Docker ubuntu_32bit. */ - } else { - context = &ctxt; + if (getcontext_works >= 0) { + if (getcontext(&ctxt) < 0) { + WARN("getcontext failed:" + " using another register retrieval method...\n", 0); + /* getcontext() is broken, do not try again. */ + /* E.g., to workaround a bug in Docker ubuntu_32bit. */ + } else { + context = &ctxt; + } + if (EXPECT(0 == getcontext_works, FALSE)) + getcontext_works = context != NULL 1 : -1; } # ifdef GETCONTEXT_FPU_EXCMASK_BUG # ifdef X86_64 |