diff options
author | Marlene JACQUIER <mjacquier@centralp.fr> | 2024-01-19 14:11:14 +0000 |
---|---|---|
committer | mjacquier <mjacquier@centralp.fr> | 2024-01-19 15:44:18 +0100 |
commit | edc735de775a24ce09ce9474271a71188aeabfac (patch) | |
tree | c6ccb8a607b8926c7328b4a64e54ae2638d5c677 | |
parent | 0870f92ab9cf685d22f40f5e377f7de2e1c591dd (diff) | |
download | meta-freescale-edc735de775a24ce09ce9474271a71188aeabfac.tar.gz |
gstreamer1.0: use futex_time64 syscall if available (32-bit systems)
Patch backported from 1.20.5
-rw-r--r-- | recipes-multimedia/gstreamer/gstreamer1.0/0006-systemclock-Use-futex_time64-syscall-if-available-32.patch | 211 | ||||
-rw-r--r-- | recipes-multimedia/gstreamer/gstreamer1.0_1.20.3.imx.bb | 1 |
2 files changed, 212 insertions, 0 deletions
diff --git a/recipes-multimedia/gstreamer/gstreamer1.0/0006-systemclock-Use-futex_time64-syscall-if-available-32.patch b/recipes-multimedia/gstreamer/gstreamer1.0/0006-systemclock-Use-futex_time64-syscall-if-available-32.patch new file mode 100644 index 00000000..f3e7975c --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0/0006-systemclock-Use-futex_time64-syscall-if-available-32.patch | |||
@@ -0,0 +1,211 @@ | |||
1 | From 9ca6b1196e31a4a483fdddad191221616e2c9c3d Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com> | ||
3 | Date: Mon, 12 Dec 2022 11:34:51 +0200 | ||
4 | Subject: [PATCH] systemclock: Use `futex_time64` syscall if available (32-bit | ||
5 | systems) and use correct `struct timespec` definition | ||
6 | |||
7 | See also https://gitlab.gnome.org/GNOME/glib/-/issues/2634 | ||
8 | |||
9 | Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1648 | ||
10 | |||
11 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3561> | ||
12 | --- | ||
13 | gst/gstsystemclock.c | 125 ++++++++++++++++++--- | ||
14 | meson.build | 11 +- | ||
15 | 2 files changed, 121 insertions(+), 15 deletions(-) | ||
16 | |||
17 | diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c | ||
18 | index 6d0b6ec47b..7d8efb171e 100644 | ||
19 | --- a/gst/gstsystemclock.c | ||
20 | +++ b/gst/gstsystemclock.c | ||
21 | @@ -70,11 +70,15 @@ | ||
22 | #define GST_SYSTEM_CLOCK_WAIT(clock) g_cond_wait(GST_SYSTEM_CLOCK_GET_COND(clock),GST_SYSTEM_CLOCK_GET_LOCK(clock)) | ||
23 | #define GST_SYSTEM_CLOCK_BROADCAST(clock) g_cond_broadcast(GST_SYSTEM_CLOCK_GET_COND(clock)) | ||
24 | |||
25 | -#if defined(HAVE_FUTEX) | ||
26 | +#if defined(HAVE_FUTEX) || defined(HAVE_FUTEX_TIME64) | ||
27 | #include <unistd.h> | ||
28 | #include <linux/futex.h> | ||
29 | #include <sys/syscall.h> | ||
30 | |||
31 | +#if !defined(__NR_futex) && !defined(__NR_futex_time64) | ||
32 | +#error "Neither __NR_futex nor __NR_futex_time64 are defined but were found by meson" | ||
33 | +#endif | ||
34 | + | ||
35 | #ifndef FUTEX_WAIT_BITSET_PRIVATE | ||
36 | #define FUTEX_WAIT_BITSET_PRIVATE FUTEX_WAIT_BITSET | ||
37 | #endif | ||
38 | @@ -123,14 +127,35 @@ gst_futex_cond_broadcast (guint * cond_val) | ||
39 | { | ||
40 | g_atomic_int_inc (cond_val); | ||
41 | |||
42 | +#if defined(__NR_futex_time64) | ||
43 | + { | ||
44 | + int res; | ||
45 | + res = syscall (__NR_futex_time64, cond_val, (gsize) FUTEX_WAKE_PRIVATE, | ||
46 | + (gsize) INT_MAX, NULL); | ||
47 | + | ||
48 | + /* If the syscall does not exist (`ENOSYS`), we retry again below with the | ||
49 | + * normal `futex` syscall. This can happen if newer kernel headers are | ||
50 | + * used than the kernel that is actually running. | ||
51 | + */ | ||
52 | +#ifdef __NR_futex | ||
53 | + if (res >= 0 || errno != ENOSYS) { | ||
54 | +#else | ||
55 | + { | ||
56 | +#endif | ||
57 | + return; | ||
58 | + } | ||
59 | + } | ||
60 | +#endif | ||
61 | + | ||
62 | +#if defined(__NR_futex) | ||
63 | syscall (__NR_futex, cond_val, (gsize) FUTEX_WAKE_PRIVATE, (gsize) INT_MAX, | ||
64 | NULL); | ||
65 | +#endif | ||
66 | } | ||
67 | |||
68 | static gboolean | ||
69 | gst_futex_cond_wait_until (guint * cond_val, GMutex * mutex, gint64 end_time) | ||
70 | { | ||
71 | - struct timespec end; | ||
72 | guint sampled; | ||
73 | int res; | ||
74 | gboolean success; | ||
75 | @@ -138,20 +163,92 @@ gst_futex_cond_wait_until (guint * cond_val, GMutex * mutex, gint64 end_time) | ||
76 | if (end_time < 0) | ||
77 | return FALSE; | ||
78 | |||
79 | - end.tv_sec = end_time / 1000000000; | ||
80 | - end.tv_nsec = end_time % 1000000000; | ||
81 | - | ||
82 | sampled = *cond_val; | ||
83 | g_mutex_unlock (mutex); | ||
84 | - /* we use FUTEX_WAIT_BITSET_PRIVATE rather than FUTEX_WAIT_PRIVATE to be | ||
85 | - * able to use absolute time */ | ||
86 | - res = | ||
87 | - syscall (__NR_futex, cond_val, (gsize) FUTEX_WAIT_BITSET_PRIVATE, | ||
88 | - (gsize) sampled, &end, NULL, FUTEX_BITSET_MATCH_ANY); | ||
89 | - success = (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE; | ||
90 | - g_mutex_lock (mutex); | ||
91 | - | ||
92 | - return success; | ||
93 | + | ||
94 | + /* `struct timespec` as defined by the libc headers does not necessarily | ||
95 | + * have any relation to the one used by the kernel for the `futex` syscall. | ||
96 | + * | ||
97 | + * Specifically, the libc headers might use 64-bit `time_t` while the kernel | ||
98 | + * headers use 32-bit `__kernel_old_time_t` on certain systems. | ||
99 | + * | ||
100 | + * To get around this problem we | ||
101 | + * a) check if `futex_time64` is available, which only exists on 32-bit | ||
102 | + * platforms and always uses 64-bit `time_t`. | ||
103 | + * b) otherwise (or if that returns `ENOSYS`), we call the normal `futex` | ||
104 | + * syscall with the `struct timespec_t` used by the kernel, which uses | ||
105 | + * `__kernel_long_t` for both its fields. We use that instead of | ||
106 | + * `__kernel_old_time_t` because it is equivalent and available in the | ||
107 | + * kernel headers for a longer time. | ||
108 | + * | ||
109 | + * Also some 32-bit systems do not define `__NR_futex` at all and only | ||
110 | + * define `__NR_futex_time64`. | ||
111 | + */ | ||
112 | + | ||
113 | +#ifdef __NR_futex_time64 | ||
114 | + { | ||
115 | + struct | ||
116 | + { | ||
117 | + gint64 tv_sec; | ||
118 | + gint64 tv_nsec; | ||
119 | + } end; | ||
120 | + | ||
121 | + end.tv_sec = end_time / 1000000000; | ||
122 | + end.tv_nsec = end_time % 1000000000; | ||
123 | + | ||
124 | + /* we use FUTEX_WAIT_BITSET_PRIVATE rather than FUTEX_WAIT_PRIVATE to be | ||
125 | + * able to use absolute time */ | ||
126 | + res = | ||
127 | + syscall (__NR_futex_time64, cond_val, (gsize) FUTEX_WAIT_BITSET_PRIVATE, | ||
128 | + (gsize) sampled, &end, NULL, FUTEX_BITSET_MATCH_ANY); | ||
129 | + | ||
130 | + /* If the syscall does not exist (`ENOSYS`), we retry again below with the | ||
131 | + * normal `futex` syscall. This can happen if newer kernel headers are | ||
132 | + * used than the kernel that is actually running. | ||
133 | + */ | ||
134 | +#ifdef __NR_futex | ||
135 | + if (res >= 0 || errno != ENOSYS) { | ||
136 | +#else | ||
137 | + { | ||
138 | +#endif | ||
139 | + success = (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE; | ||
140 | + g_mutex_lock (mutex); | ||
141 | + | ||
142 | + return success; | ||
143 | + } | ||
144 | + } | ||
145 | +#endif | ||
146 | + | ||
147 | +#ifdef __NR_futex | ||
148 | + { | ||
149 | + struct | ||
150 | + { | ||
151 | + __kernel_long_t tv_sec; | ||
152 | + __kernel_long_t tv_nsec; | ||
153 | + } end; | ||
154 | + | ||
155 | + /* Make sure to only ever call this if the end time actually fits into the | ||
156 | + * target type */ | ||
157 | + g_assert (sizeof (__kernel_long_t) >= 8 | ||
158 | + || end_time / 1000000000 <= G_MAXINT32); | ||
159 | + | ||
160 | + end.tv_sec = end_time / 1000000000; | ||
161 | + end.tv_nsec = end_time % 1000000000; | ||
162 | + | ||
163 | + /* we use FUTEX_WAIT_BITSET_PRIVATE rather than FUTEX_WAIT_PRIVATE to be | ||
164 | + * able to use absolute time */ | ||
165 | + res = | ||
166 | + syscall (__NR_futex, cond_val, (gsize) FUTEX_WAIT_BITSET_PRIVATE, | ||
167 | + (gsize) sampled, &end, NULL, FUTEX_BITSET_MATCH_ANY); | ||
168 | + success = (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE; | ||
169 | + g_mutex_lock (mutex); | ||
170 | + | ||
171 | + return success; | ||
172 | + } | ||
173 | +#endif | ||
174 | + | ||
175 | + /* We can't end up here because of the checks above */ | ||
176 | + g_assert_not_reached (); | ||
177 | } | ||
178 | |||
179 | #elif defined (G_OS_UNIX) | ||
180 | diff --git a/meson.build b/meson.build | ||
181 | index 0641f7678b..7331c66150 100644 | ||
182 | --- a/meson.build | ||
183 | +++ b/meson.build | ||
184 | @@ -294,7 +294,7 @@ if cc.has_header_symbol('pthread.h', 'pthread_cond_timedwait_relative_np') | ||
185 | endif | ||
186 | |||
187 | # Check for futex(2) | ||
188 | -if cc.links('''#include <linux/futex.h> | ||
189 | +if cc.compiles('''#include <linux/futex.h> | ||
190 | #include <sys/syscall.h> | ||
191 | #include <unistd.h> | ||
192 | int main (int argc, char ** argv) { | ||
193 | @@ -303,6 +303,15 @@ if cc.links('''#include <linux/futex.h> | ||
194 | }''', name : 'futex(2) system call') | ||
195 | cdata.set('HAVE_FUTEX', 1) | ||
196 | endif | ||
197 | +if cc.compiles('''#include <linux/futex.h> | ||
198 | + #include <sys/syscall.h> | ||
199 | + #include <unistd.h> | ||
200 | + int main (int argc, char ** argv) { | ||
201 | + syscall (__NR_futex_time64, NULL, FUTEX_WAKE, FUTEX_WAIT); | ||
202 | + return 0; | ||
203 | + }''', name : 'futex(2) system call') | ||
204 | + cdata.set('HAVE_FUTEX_TIME64', 1) | ||
205 | +endif | ||
206 | |||
207 | # Check for posix timers and monotonic clock | ||
208 | time_prefix = '#include <time.h>\n' | ||
209 | -- | ||
210 | 2.25.1 | ||
211 | |||
diff --git a/recipes-multimedia/gstreamer/gstreamer1.0_1.20.3.imx.bb b/recipes-multimedia/gstreamer/gstreamer1.0_1.20.3.imx.bb index 2c419601..850a5385 100644 --- a/recipes-multimedia/gstreamer/gstreamer1.0_1.20.3.imx.bb +++ b/recipes-multimedia/gstreamer/gstreamer1.0_1.20.3.imx.bb | |||
@@ -29,6 +29,7 @@ SRC_URI = "https://gstreamer.freedesktop.org/src/gstreamer/gstreamer-${PV}.tar.x | |||
29 | file://0003-tests-use-a-dictionaries-for-environment.patch;striplevel=3 \ | 29 | file://0003-tests-use-a-dictionaries-for-environment.patch;striplevel=3 \ |
30 | file://0004-tests-add-helper-script-to-run-the-installed_tests.patch;striplevel=3 \ | 30 | file://0004-tests-add-helper-script-to-run-the-installed_tests.patch;striplevel=3 \ |
31 | file://0005-tests-remove-gstbin-test_watch_for_state_change-test.patch \ | 31 | file://0005-tests-remove-gstbin-test_watch_for_state_change-test.patch \ |
32 | file://0006-systemclock-Use-futex_time64-syscall-if-available-32.patch \ | ||
32 | " | 33 | " |
33 | SRC_URI[sha256sum] = "de094a404a3ad8f4977829ea87edf695a4da0b5c8f613ebe54ab414bac89f031" | 34 | SRC_URI[sha256sum] = "de094a404a3ad8f4977829ea87edf695a4da0b5c8f613ebe54ab414bac89f031" |
34 | 35 | ||