asar coverage - build #157


src/asar/
File: src/asar/platform/generic/thread-helpers-pthread.h
Date: 2024-01-26 19:56:48
Lines:
31/34
91.2%
Functions:
10/10
100.0%
Branches:
10/20
50.0%

Line Branch Exec Source
1 #pragma once
2
3 #include <stdint.h>
4 #include <pthread.h>
5
6 struct function_pointer_wrapper /*have this struct at global level*/
7 {
8 static void* (*thread_callback)(void*);
9 372 static void* execute_thread(void* parameter) { return thread_callback(parameter); }
10 };
11
12 void* (*function_pointer_wrapper::thread_callback)(void*) = nullptr;
13
14 template <typename functor>
15 372 bool run_as_thread(functor&& callback) {
16 struct thread_wrapper {
17 functor& callback;
18 bool result;
19
20 372 void* execute() {
21 372 result = callback();
22
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 76 times.
372 if (result)
23 296 pthread_exit(NULL);
24 else
25 76 pthread_exit(reinterpret_cast<void*>((uintptr_t)-1));
26 }
27
28 372 } wrapper{ callback, false };
29
30 372 function_pointer_wrapper::thread_callback = [](void* parameter) {
31 372 return reinterpret_cast<thread_wrapper*>(parameter)->execute();
32 };
33
34 pthread_attr_t settings;
35 pthread_t thread_id;
36 int ret;
37
38 372 ret = pthread_attr_init(&settings);
39
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 372 times.
372 if (ret == -1){
40 return callback();
41 }
42
43 372 ret = pthread_attr_setstacksize(&settings, 16 * 1024 * 1024);
44
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 372 times.
372 if (ret == -1){
45 return callback();
46 }
47
48 372 ret = pthread_create(&thread_id, &settings, &function_pointer_wrapper::execute_thread, &wrapper);
49
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 372 times.
372 if (ret == -1){
50 return callback();
51 }
52
53 void* thread_ret;
54
1/2
✓ Branch 0 taken 372 times.
✗ Branch 1 not taken.
372 pthread_join(thread_id, &thread_ret);
55
56 372 return wrapper.result;
57 }
58
59 #ifndef NO_USE_THREADS
60 void* stack_bottom = nullptr;
61 1086 void init_stack_use_check() {
62 pthread_attr_t attrs;
63 1086 size_t stack_size = 0;
64 1086 pthread_getattr_np(pthread_self(), &attrs);
65 1086 pthread_attr_getstack(&attrs, &stack_bottom, &stack_size);
66 1086 pthread_attr_destroy(&attrs);
67 1086 }
68 1071 void deinit_stack_use_check() {
69 1071 stack_bottom = nullptr;
70 1071 }
71 190388 bool have_enough_stack_left() {
72 #if defined(__clang__) || defined(__GNUC__)
73 // this is a GCC extension, but it's necessary for this function to work in ASan
74 // (regular local variables are banished to the shadow realm or some shit,
75 // so their addresses don't tell us anything about "real" stack usage)
76 190388 void* stack_top = __builtin_frame_address(0);
77 #else
78 // using a random local as a rough estimate for current top-of-stack
79 char stackvar;
80 void* stack_top = &stackvar;
81 #endif
82 190388 ssize_t stack_left = (char*)stack_top - (char*)stack_bottom;
83
4/4
✓ Branch 0 taken 190220 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 190217 times.
✓ Branch 3 taken 3 times.
190388 return stack_bottom == nullptr || stack_left >= 32768;
84 }
85 #endif
86