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:
Kevin Wolf 2012-06-29 13:40:27 +02:00
parent 9e559533bd
commit 3f4349dc8b
2 changed files with 48 additions and 0 deletions

20
configure vendored
View File

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

View File

@ -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);
}