提交 3f4349dc 编写于 作者: K Kevin Wolf

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: NKevin Wolf <kwolf@redhat.com>
Reviewed-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 9e559533
...@@ -2870,6 +2870,22 @@ if compile_prog "" "" ; then ...@@ -2870,6 +2870,22 @@ if compile_prog "" "" ; then
linux_magic_h=yes linux_magic_h=yes
fi 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 # check if environ is declared
...@@ -3379,6 +3395,10 @@ if test "$linux_magic_h" = "yes" ; then ...@@ -3379,6 +3395,10 @@ if test "$linux_magic_h" = "yes" ; then
echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak
fi fi
if test "$valgrind_h" = "yes" ; then
echo "CONFIG_VALGRIND_H=y" >> $config_host_mak
fi
if test "$has_environ" = "yes" ; then if test "$has_environ" = "yes" ; then
echo "CONFIG_HAS_ENVIRON=y" >> $config_host_mak echo "CONFIG_HAS_ENVIRON=y" >> $config_host_mak
fi fi
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "qemu-coroutine-int.h" #include "qemu-coroutine-int.h"
#ifdef CONFIG_VALGRIND_H
#include <valgrind/valgrind.h>
#endif
enum { enum {
/* Maximum free pool size prevents holding too many freed coroutines */ /* Maximum free pool size prevents holding too many freed coroutines */
POOL_MAX_SIZE = 64, POOL_MAX_SIZE = 64,
...@@ -43,6 +47,11 @@ typedef struct { ...@@ -43,6 +47,11 @@ typedef struct {
Coroutine base; Coroutine base;
void *stack; void *stack;
jmp_buf env; jmp_buf env;
#ifdef CONFIG_VALGRIND_H
unsigned int valgrind_stack_id;
#endif
} CoroutineUContext; } CoroutineUContext;
/** /**
...@@ -159,6 +168,11 @@ static Coroutine *coroutine_new(void) ...@@ -159,6 +168,11 @@ static Coroutine *coroutine_new(void)
uc.uc_stack.ss_size = stack_size; uc.uc_stack.ss_size = stack_size;
uc.uc_stack.ss_flags = 0; 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; arg.p = co;
makecontext(&uc, (void (*)(void))coroutine_trampoline, makecontext(&uc, (void (*)(void))coroutine_trampoline,
...@@ -185,6 +199,16 @@ Coroutine *qemu_coroutine_new(void) ...@@ -185,6 +199,16 @@ Coroutine *qemu_coroutine_new(void)
return co; 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_) void qemu_coroutine_delete(Coroutine *co_)
{ {
CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_); CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
...@@ -196,6 +220,10 @@ void qemu_coroutine_delete(Coroutine *co_) ...@@ -196,6 +220,10 @@ void qemu_coroutine_delete(Coroutine *co_)
return; return;
} }
#ifdef CONFIG_VALGRIND_H
valgrind_stack_deregister(co);
#endif
g_free(co->stack); g_free(co->stack);
g_free(co); g_free(co);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册