diff options
author | Arkadiusz Hiler <arkadiusz.hiler@intel.com> | 2020-06-16 15:40:30 +0300 |
---|---|---|
committer | Arkadiusz Hiler <arkadiusz.hiler@intel.com> | 2020-06-22 13:31:32 +0300 |
commit | d2e4cb0cf92c7e3f3d8e88841ed9160e97aebbe4 (patch) | |
tree | 8fd2a623e0553a92aa658ed302513cf0e2fa0040 /lib/igt_thread.c | |
parent | b787a2f2a0a56e2009f7b8252d93b3a8694f0b53 (diff) |
lib/core: Handle asserts in threads
Since IGT is using magic control blocks (igt_subtest et al.) asserts
jump out the them using longjmp() causing a bunch of confusing messages
and occasionally crashing the whole process.
This is not the behavior we want :-)
With this patch:
1. simple_main, dynamic and subtest each clears the thread failure state
at the start
2. each of those blocks also asserts no thread failures at the end
3. igt_assert() in non-main thread prints out the error + stacktrace
and marks that we have failed thread
Issue: https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/issues/55
Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
Diffstat (limited to 'lib/igt_thread.c')
-rw-r--r-- | lib/igt_thread.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/igt_thread.c b/lib/igt_thread.c index deab62257..5bdda4102 100644 --- a/lib/igt_thread.c +++ b/lib/igt_thread.c @@ -22,12 +22,42 @@ */ #include <pthread.h> +#include <stdlib.h> +#include <stdatomic.h> #include "igt_core.h" #include "igt_thread.h" static pthread_key_t __igt_is_main_thread; +static _Atomic(bool) __thread_failed = false; + +void igt_thread_clear_fail_state(void) +{ + assert(igt_thread_is_main()); + + __thread_failed = false; +} + +void igt_thread_fail(void) +{ + assert(!igt_thread_is_main()); + + __thread_failed = true; +} + +void igt_thread_assert_no_failures(void) +{ + assert(igt_thread_is_main()); + + if (__thread_failed) { + /* so we won't get stuck in a loop */ + igt_thread_clear_fail_state(); + igt_critical("Failure in a thread!\n"); + igt_fail(IGT_EXIT_FAILURE); + } +} + bool igt_thread_is_main(void) { return pthread_getspecific(__igt_is_main_thread) != NULL; |