Branch data Line data Source code
1 : : #include "precizer.h"
2 : :
3 : : #include <errno.h>
4 : : #include <stdint.h>
5 : :
6 : : /**
7 : : * @brief Pause execution at a selected test wait point.
8 : : *
9 : : * The function reads `TESTITALL_SIGNAL_WAIT_POINT` and
10 : : * `TESTITALL_SIGNAL_WAIT_MS`. When the configured point matches @p point_id,
11 : : * it waits for the requested number of milliseconds, checking
12 : : * `global_interrupt_flag` between short sleep chunks for early resume.
13 : : */
14 : 235 : void signal_wait_at_point(unsigned int point_id)
15 : : {
16 : 235 : const char *configured_point = getenv("TESTITALL_SIGNAL_WAIT_POINT");
17 : :
18 [ + + - + ]: 235 : if(NULL == configured_point || '\0' == configured_point[0])
19 : : {
20 : 235 : return;
21 : : }
22 : :
23 : 6 : errno = 0;
24 : 6 : char *point_end_ptr = NULL;
25 : 6 : unsigned long long parsed_point_id = strtoull(configured_point,&point_end_ptr,10);
26 : :
27 [ + - + - : 6 : if(errno != 0 || point_end_ptr == configured_point || '\0' != *point_end_ptr)
- + ]
28 : : {
29 : 0 : return;
30 : : }
31 : :
32 [ + + ]: 6 : if(parsed_point_id != (unsigned long long)point_id)
33 : : {
34 : 2 : return;
35 : : }
36 : :
37 : 4 : const char *timeout_text = getenv("TESTITALL_SIGNAL_WAIT_MS");
38 : :
39 [ + - - + ]: 4 : if(NULL == timeout_text || '\0' == timeout_text[0])
40 : : {
41 : 0 : return;
42 : : }
43 : :
44 : 4 : errno = 0;
45 : 4 : char *end_ptr = NULL;
46 : 4 : unsigned long long parsed_timeout_ms = strtoull(timeout_text,&end_ptr,10);
47 : :
48 [ + - + - : 4 : if(errno != 0 || end_ptr == timeout_text || '\0' != *end_ptr || parsed_timeout_ms == 0ULL)
+ - - + ]
49 : : {
50 : 0 : return;
51 : : }
52 : :
53 : 4 : uint64_t remaining_timeout_ms = (uint64_t)parsed_timeout_ms;
54 : :
55 [ + - ]: 112 : while(remaining_timeout_ms > 0U)
56 : : {
57 : : /* Allow tests to release the delay as soon as the signal handler sets the flag. */
58 [ - + ]: 112 : if(atomic_load(&global_interrupt_flag) == true)
59 : : {
60 : 4 : return;
61 : : }
62 : :
63 : 112 : uint64_t chunk_ms = remaining_timeout_ms;
64 : :
65 [ + - ]: 112 : if(chunk_ms > 10U)
66 : : {
67 : 112 : chunk_ms = 10U;
68 : : }
69 : :
70 : 112 : struct timespec delay = {
71 : : .tv_sec = 0,
72 : 112 : .tv_nsec = (long)(chunk_ms * 1000000ULL)
73 : : };
74 : :
75 [ + + + - ]: 112 : while(nanosleep(&delay,&delay) == -1 && errno == EINTR)
76 : : {
77 [ + - ]: 4 : if(atomic_load(&global_interrupt_flag) == true)
78 : : {
79 : 4 : return;
80 : : }
81 : : }
82 : :
83 : 108 : remaining_timeout_ms -= chunk_ms;
84 : : }
85 : : }
|