Line | Count | Source |
1 | | /* |
2 | | * Copyright © 2018, VideoLAN and dav1d authors |
3 | | * Copyright © 2018, Two Orioles, LLC |
4 | | * All rights reserved. |
5 | | * |
6 | | * Redistribution and use in source and binary forms, with or without |
7 | | * modification, are permitted provided that the following conditions are met: |
8 | | * |
9 | | * 1. Redistributions of source code must retain the above copyright notice, this |
10 | | * list of conditions and the following disclaimer. |
11 | | * |
12 | | * 2. Redistributions in binary form must reproduce the above copyright notice, |
13 | | * this list of conditions and the following disclaimer in the documentation |
14 | | * and/or other materials provided with the distribution. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |
20 | | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | | */ |
27 | | #include "config.h" |
28 | | |
29 | | #include <errno.h> |
30 | | #include <stdint.h> |
31 | | |
32 | | #include "src/cpu.h" |
33 | | #include "src/log.h" |
34 | | |
35 | | #ifdef _WIN32 |
36 | | #include <windows.h> |
37 | | #endif |
38 | | #ifdef __APPLE__ |
39 | | #include <sys/sysctl.h> |
40 | | #include <sys/types.h> |
41 | | #endif |
42 | | #if HAVE_UNISTD_H |
43 | | #include <unistd.h> |
44 | | #endif |
45 | | |
46 | | #if HAVE_PTHREAD_GETAFFINITY_NP |
47 | | #include <pthread.h> |
48 | | #if HAVE_PTHREAD_NP_H |
49 | | #include <pthread_np.h> |
50 | | #endif |
51 | | #if defined(__FreeBSD__) |
52 | | #define cpu_set_t cpuset_t |
53 | | #endif |
54 | | #endif |
55 | | |
56 | | #if HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO |
57 | | #include <sys/auxv.h> |
58 | | #endif |
59 | | |
60 | | unsigned dav1d_cpu_flags = 0U; |
61 | | unsigned dav1d_cpu_flags_mask = ~0U; |
62 | | |
63 | 0 | COLD void dav1d_init_cpu(void) { |
64 | | #if HAVE_ASM && !__has_feature(memory_sanitizer) |
65 | | // memory sanitizer is inherently incompatible with asm |
66 | | #if ARCH_AARCH64 || ARCH_ARM |
67 | | dav1d_cpu_flags = dav1d_get_cpu_flags_arm(); |
68 | | #elif ARCH_LOONGARCH |
69 | | dav1d_cpu_flags = dav1d_get_cpu_flags_loongarch(); |
70 | | #elif ARCH_PPC64LE |
71 | | dav1d_cpu_flags = dav1d_get_cpu_flags_ppc(); |
72 | | #elif ARCH_RISCV |
73 | | dav1d_cpu_flags = dav1d_get_cpu_flags_riscv(); |
74 | | #elif ARCH_X86 |
75 | | dav1d_cpu_flags = dav1d_get_cpu_flags_x86(); |
76 | | #endif |
77 | | #endif |
78 | 0 | } |
79 | | |
80 | 0 | COLD void dav1d_set_cpu_flags_mask(const unsigned mask) { |
81 | 0 | dav1d_cpu_flags_mask = mask; |
82 | 0 | } |
83 | | |
84 | 0 | COLD int dav1d_num_logical_processors(Dav1dContext *const c) { |
85 | | #ifdef _WIN32 |
86 | | #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
87 | | GROUP_AFFINITY affinity; |
88 | | if (GetThreadGroupAffinity(GetCurrentThread(), &affinity)) { |
89 | | int num_processors = 1; |
90 | | while (affinity.Mask &= affinity.Mask - 1) |
91 | | num_processors++; |
92 | | return num_processors; |
93 | | } |
94 | | #else |
95 | | SYSTEM_INFO system_info; |
96 | | GetNativeSystemInfo(&system_info); |
97 | | return system_info.dwNumberOfProcessors; |
98 | | #endif |
99 | | #elif HAVE_PTHREAD_GETAFFINITY_NP && defined(CPU_COUNT) |
100 | | cpu_set_t affinity; |
101 | 0 | if (!pthread_getaffinity_np(pthread_self(), sizeof(affinity), &affinity)) |
102 | 0 | return CPU_COUNT(&affinity); |
103 | | #elif defined(__APPLE__) |
104 | | int num_processors; |
105 | | size_t length = sizeof(num_processors); |
106 | | if (!sysctlbyname("hw.logicalcpu", &num_processors, &length, NULL, 0)) |
107 | | return num_processors; |
108 | | #elif defined(_SC_NPROCESSORS_ONLN) |
109 | | return (int)sysconf(_SC_NPROCESSORS_ONLN); |
110 | | #endif |
111 | 0 | if (c) |
112 | 0 | dav1d_log(c, "Unable to detect thread count, defaulting to single-threaded mode\n"); |
113 | 0 | return 1; |
114 | 0 | } |
115 | | |
116 | 0 | COLD unsigned long dav1d_getauxval(unsigned long type) { |
117 | | #if HAVE_GETAUXVAL |
118 | | return getauxval(type); |
119 | | #elif HAVE_ELF_AUX_INFO |
120 | | unsigned long aux = 0; |
121 | | int ret = elf_aux_info(type, &aux, sizeof(aux)); |
122 | | if (ret != 0) |
123 | | errno = ret; |
124 | | return aux; |
125 | | #else |
126 | 0 | errno = ENOSYS; |
127 | 0 | return 0; |
128 | 0 | #endif |
129 | 0 | } |