Coverage Report

Created: 2026-05-16 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/svt_threads.h
Line
Count
Source
1
/*
2
* Copyright(c) 2019 Intel Corporation
3
*
4
* This source code is subject to the terms of the BSD 2 Clause License and
5
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
* was not distributed with this source code in the LICENSE file, you can
7
* obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
8
* Media Patent License 1.0 was not distributed with this source code in the
9
* PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
10
*/
11
12
#ifndef EbThreads_h
13
#define EbThreads_h
14
15
#include "definitions.h"
16
17
#ifdef _WIN32
18
#include <windows.h>
19
#endif
20
21
#ifdef __cplusplus
22
extern "C" {
23
#endif
24
// Create wrapper functions that hide thread calls,
25
// semaphores, mutex, etc. These wrappers also hide
26
// platform specific implementations of these objects.
27
28
/**************************************
29
     * Threads
30
     **************************************/
31
EbHandle svt_create_thread(void* thread_function(void*), void* thread_context, const char* name);
32
33
EbErrorType svt_destroy_thread(EbHandle thread_handle);
34
35
// Format a per-instance worker thread name as `<prefix><index>` into a fixed
36
// buffer (typical size 16 to match TASK_COMM_LEN). Used by EB_CREATE_THREAD_ARRAY.
37
void svt_format_thread_name(char* buf, size_t size, const char* prefix, uint32_t index);
38
39
/**************************************
40
     * Semaphores
41
     **************************************/
42
EbHandle svt_create_semaphore(uint32_t initial_count, uint32_t max_count);
43
44
EbErrorType svt_post_semaphore(EbHandle semaphore_handle);
45
46
EbErrorType svt_block_on_semaphore(EbHandle semaphore_handle);
47
48
EbErrorType svt_destroy_semaphore(EbHandle semaphore_handle);
49
50
/**************************************
51
     * Mutex
52
     **************************************/
53
EbHandle    svt_create_mutex(void);
54
EbErrorType svt_release_mutex(EbHandle mutex_handle);
55
EbErrorType svt_block_on_mutex(EbHandle mutex_handle);
56
EbErrorType svt_destroy_mutex(EbHandle mutex_handle);
57
#ifndef _WIN32
58
#ifndef __USE_GNU
59
#define __USE_GNU
60
#endif
61
#ifndef _GNU_SOURCE
62
#define _GNU_SOURCE
63
#endif
64
#include <sched.h>
65
#include <pthread.h>
66
#endif
67
#define EB_CREATE_THREAD_NAMED(pointer, thread_function, thread_context, name) \
68
13.3k
    do {                                                                       \
69
13.3k
        pointer = svt_create_thread(thread_function, thread_context, name);    \
70
13.3k
        EB_ADD_MEM(pointer, 1, EB_THREAD);                                     \
71
13.3k
    } while (0)
72
73
/* `thread_function` must be a bare identifier here; the macro derives the
74
 * thread name via # stringification, so any cast or member access (e.g.
75
 * `(kernel_t)fn`, `ctx->fn`) would leak into the thread name. */
76
#define EB_CREATE_THREAD(pointer, thread_function, thread_context) \
77
2.84k
    EB_CREATE_THREAD_NAMED(pointer, thread_function, thread_context, #thread_function)
78
#define EB_DESTROY_THREAD(pointer)                   \
79
13.3k
    do {                                             \
80
13.3k
        if (pointer) {                               \
81
13.3k
            svt_destroy_thread(pointer);             \
82
13.3k
            EB_REMOVE_MEM_ENTRY(pointer, EB_THREAD); \
83
13.3k
            pointer = NULL;                          \
84
13.3k
        }                                            \
85
13.3k
    } while (0);
86
87
#define EB_CREATE_THREAD_ARRAY(pa, count, thread_function, thread_contexts, name_prefix)       \
88
4.74k
    do {                                                                                       \
89
4.74k
        EB_ALLOC_PTR_ARRAY(pa, count);                                                         \
90
15.2k
        for (uint32_t i = 0; i < count; i++) {                                                 \
91
10.5k
            char _svt_thr_name[16];                                                            \
92
10.5k
            svt_format_thread_name(_svt_thr_name, sizeof(_svt_thr_name), name_prefix, i);      \
93
10.5k
            EB_CREATE_THREAD_NAMED(pa[i], thread_function, thread_contexts[i], _svt_thr_name); \
94
10.5k
        }                                                                                      \
95
4.74k
    } while (0)
96
97
#define EB_DESTROY_THREAD_ARRAY(pa, count)       \
98
4.74k
    do {                                         \
99
4.74k
        if (pa) {                                \
100
15.2k
            for (uint32_t i = 0; i < count; i++) \
101
10.5k
                EB_DESTROY_THREAD(pa[i]);        \
102
4.74k
            EB_FREE_PTR_ARRAY(pa, count);        \
103
4.74k
        }                                        \
104
4.74k
    } while (0)
105
106
void svt_aom_atomic_set_u32(AtomicVarU32* var, uint32_t in);
107
108
/*
109
 Condition variable
110
*/
111
typedef struct CondVar {
112
    int32_t val;
113
#ifdef _WIN32
114
    CRITICAL_SECTION   cs;
115
    CONDITION_VARIABLE cv;
116
#else
117
    pthread_mutex_t m_mutex;
118
    pthread_cond_t  m_cond;
119
#endif
120
} CondVar;
121
122
EbErrorType svt_set_cond_var(CondVar* cond_var, int32_t newval);
123
EbErrorType svt_wait_cond_var(CondVar* cond_var, int32_t input);
124
EbErrorType svt_create_cond_var(CondVar* cond_var);
125
126
// once related functions and macros
127
#ifdef _WIN32
128
typedef INIT_ONCE OnceType;
129
#define ONCE_INIT INIT_ONCE_STATIC_INIT
130
#define ONCE_ROUTINE(name) BOOL CALLBACK name(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* lpContext)
131
#define ONCE_ROUTINE_EPILOG \
132
    do {                    \
133
        return TRUE;        \
134
    } while (0)
135
typedef PINIT_ONCE_FN OnceFn;
136
#else
137
typedef pthread_once_t OnceType;
138
#define ONCE_INIT PTHREAD_ONCE_INIT
139
#define ONCE_ROUTINE(name) void name(void)
140
#define ONCE_ROUTINE_EPILOG \
141
4
    do {                    \
142
4
        return;             \
143
4
    } while (0)
144
typedef void (*OnceFn)(void);
145
#endif
146
#define DEFINE_ONCE(once_control) static OnceType once_control = ONCE_INIT
147
148
// Macro to define a lazily-initialized mutex with once control
149
// Usage: DEFINE_ONCE_MUTEX(my_mutex)
150
// Then call: RUN_ONCE_MUTEX(my_mutex) before using svt_block_on_mutex(my_mutex)
151
#define DEFINE_ONCE_MUTEX(mutex_name)           \
152
    static EbHandle mutex_name = NULL;          \
153
2
    static void     deinit_##mutex_name(void) { \
154
2
        if (mutex_name) {                   \
155
2
            svt_destroy_mutex(mutex_name);  \
156
2
            mutex_name = NULL;              \
157
2
        }                                   \
158
2
    }                                           \
159
2
    ONCE_ROUTINE(init_##mutex_name) {           \
160
2
        mutex_name = svt_create_mutex();        \
161
2
        atexit(deinit_##mutex_name);            \
162
2
        ONCE_ROUTINE_EPILOG;                    \
163
2
    }                                           \
init_rtcd_init_mutex
Line
Count
Source
159
1
    ONCE_ROUTINE(init_##mutex_name) {           \
160
1
        mutex_name = svt_create_mutex();        \
161
1
        atexit(deinit_##mutex_name);            \
162
1
        ONCE_ROUTINE_EPILOG;                    \
163
1
    }                                           \
init_common_rtcd_init_mutex
Line
Count
Source
159
1
    ONCE_ROUTINE(init_##mutex_name) {           \
160
1
        mutex_name = svt_create_mutex();        \
161
1
        atexit(deinit_##mutex_name);            \
162
1
        ONCE_ROUTINE_EPILOG;                    \
163
1
    }                                           \
164
    DEFINE_ONCE(mutex_name##_once)
165
166
948
#define RUN_ONCE_MUTEX(mutex_name) svt_run_once(&mutex_name##_once, init_##mutex_name)
167
168
void svt_run_once(OnceType* once_control, OnceFn init_routine);
169
170
#ifdef __cplusplus
171
}
172
#endif
173
#endif // EbThreads_h