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 000000000..f3e7975c0 --- /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 2c419601b..850a5385c 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 | ||
