aboutsummaryrefslogtreecommitdiff
path: root/coroutine-ucontext.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2012-06-29 13:40:27 +0200
committerKevin Wolf <kwolf@redhat.com>2012-07-17 16:48:32 +0200
commit3f4349dc8b9494315f8331b2ea4e8d1f83fb801d (patch)
tree1e0267b1c907a90c3dddef494be13b9076fa2d9f /coroutine-ucontext.c
parent9e559533bd825a3e371497875576137a8586c831 (diff)
downloadqemu-3f4349dc8b9494315f8331b2ea4e8d1f83fb801d.zip
qemu-3f4349dc8b9494315f8331b2ea4e8d1f83fb801d.tar.gz
qemu-3f4349dc8b9494315f8331b2ea4e8d1f83fb801d.tar.bz2
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>
Diffstat (limited to 'coroutine-ucontext.c')
-rw-r--r--coroutine-ucontext.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
index 5f43083..e3c450b 100644
--- a/coroutine-ucontext.c
+++ b/coroutine-ucontext.c
@@ -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);
}