coroutine-ucontext: Help valgrind understand coroutines
valgrind tends to get confused and report false positives when you switch stacks and don't tell it about it. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9e559533bd
commit
3f4349dc8b
20
configure
vendored
20
configure
vendored
@ -2870,6 +2870,22 @@ if compile_prog "" "" ; then
|
||||
linux_magic_h=yes
|
||||
fi
|
||||
|
||||
########################################
|
||||
# check if we have valgrind/valgrind.h
|
||||
|
||||
valgrind_h=no
|
||||
cat > $TMPC << EOF
|
||||
#include <valgrind/valgrind.h>
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
int main(void) {
|
||||
VALGRIND_STACK_DEREGISTER(0);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
if compile_prog "" "" ; then
|
||||
valgrind_h=yes
|
||||
fi
|
||||
|
||||
########################################
|
||||
# check if environ is declared
|
||||
|
||||
@ -3379,6 +3395,10 @@ if test "$linux_magic_h" = "yes" ; then
|
||||
echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$valgrind_h" = "yes" ; then
|
||||
echo "CONFIG_VALGRIND_H=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$has_environ" = "yes" ; then
|
||||
echo "CONFIG_HAS_ENVIRON=y" >> $config_host_mak
|
||||
fi
|
||||
|
@ -30,6 +30,10 @@
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-coroutine-int.h"
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
#include <valgrind/valgrind.h>
|
||||
#endif
|
||||
|
||||
enum {
|
||||
/* Maximum free pool size prevents holding too many freed coroutines */
|
||||
POOL_MAX_SIZE = 64,
|
||||
@ -43,6 +47,11 @@ typedef struct {
|
||||
Coroutine base;
|
||||
void *stack;
|
||||
jmp_buf env;
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
unsigned int valgrind_stack_id;
|
||||
#endif
|
||||
|
||||
} CoroutineUContext;
|
||||
|
||||
/**
|
||||
@ -159,6 +168,11 @@ static Coroutine *coroutine_new(void)
|
||||
uc.uc_stack.ss_size = stack_size;
|
||||
uc.uc_stack.ss_flags = 0;
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
co->valgrind_stack_id =
|
||||
VALGRIND_STACK_REGISTER(co->stack, co->stack + stack_size);
|
||||
#endif
|
||||
|
||||
arg.p = co;
|
||||
|
||||
makecontext(&uc, (void (*)(void))coroutine_trampoline,
|
||||
@ -185,6 +199,16 @@ Coroutine *qemu_coroutine_new(void)
|
||||
return co;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
/* Work around an unused variable in the valgrind.h macro... */
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
static inline void valgrind_stack_deregister(CoroutineUContext *co)
|
||||
{
|
||||
VALGRIND_STACK_DEREGISTER(co->valgrind_stack_id);
|
||||
}
|
||||
#pragma GCC diagnostic error "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
void qemu_coroutine_delete(Coroutine *co_)
|
||||
{
|
||||
CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
|
||||
@ -196,6 +220,10 @@ void qemu_coroutine_delete(Coroutine *co_)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
valgrind_stack_deregister(co);
|
||||
#endif
|
||||
|
||||
g_free(co->stack);
|
||||
g_free(co);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user