summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOtavio Salvador <otavio@ossystems.com.br>2024-01-19 19:30:14 -0300
committerGitHub <noreply@github.com>2024-01-19 19:30:14 -0300
commit710e55d529c86d15a93c4421365ef62eb601a49b (patch)
treec6ccb8a607b8926c7328b4a64e54ae2638d5c677
parent0870f92ab9cf685d22f40f5e377f7de2e1c591dd (diff)
parentedc735de775a24ce09ce9474271a71188aeabfac (diff)
downloadmeta-freescale-710e55d529c86d15a93c4421365ef62eb601a49b.tar.gz
Merge pull request #1737 from marlene-jacquier/dev_mja
gstreamer1.0: use futex_time64 syscall if available (32-bit systems) #1725
-rw-r--r--recipes-multimedia/gstreamer/gstreamer1.0/0006-systemclock-Use-futex_time64-syscall-if-available-32.patch211
-rw-r--r--recipes-multimedia/gstreamer/gstreamer1.0_1.20.3.imx.bb1
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 @@
1From 9ca6b1196e31a4a483fdddad191221616e2c9c3d Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
3Date: Mon, 12 Dec 2022 11:34:51 +0200
4Subject: [PATCH] systemclock: Use `futex_time64` syscall if available (32-bit
5 systems) and use correct `struct timespec` definition
6
7See also https://gitlab.gnome.org/GNOME/glib/-/issues/2634
8
9Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1648
10
11Part-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
17diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c
18index 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)
180diff --git a/meson.build b/meson.build
181index 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--
2102.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 "
33SRC_URI[sha256sum] = "de094a404a3ad8f4977829ea87edf695a4da0b5c8f613ebe54ab414bac89f031" 34SRC_URI[sha256sum] = "de094a404a3ad8f4977829ea87edf695a4da0b5c8f613ebe54ab414bac89f031"
34 35