[vlc-commits] FreeBSD: add thread ID and atomic wait functions
Rémi Denis-Courmont
git at videolan.org
Thu Feb 20 19:48:33 CET 2020
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Feb 8 19:34:33 2020 +0200| [add2e3a61cd1bf958fadcadddac820dea25057d4] | committer: Rémi Denis-Courmont
FreeBSD: add thread ID and atomic wait functions
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=add2e3a61cd1bf958fadcadddac820dea25057d4
---
configure.ac | 1 +
src/Makefile.am | 5 +++
src/freebsd/thread.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+)
diff --git a/configure.ac b/configure.ac
index 7741ddca55..bc1874cb97 100644
--- a/configure.ac
+++ b/configure.ac
@@ -370,6 +370,7 @@ AS_IF([test "${SYS}" = "mingw32"],[
],[])
])
+AM_CONDITIONAL([HAVE_FREEBSD], [test "${SYS}" = "freebsd"])
AM_CONDITIONAL([HAVE_LINUX], [test "${SYS}" = "linux"])
AM_CONDITIONAL([HAVE_OS2], [test "${SYS}" = "os2"])
diff --git a/src/Makefile.am b/src/Makefile.am
index abcebe4fdd..bf91159fcc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -448,6 +448,11 @@ libvlccore_objc_la_SOURCES = \
noinst_LTLIBRARIES = libvlccore_objc.la
endif
+if HAVE_FREEBSD
+libvlccore_la_SOURCES += \
+ freebsd/thread.c
+endif
+
if HAVE_LINUX
libvlccore_la_SOURCES += \
linux/cpu.c \
diff --git a/src/freebsd/thread.c b/src/freebsd/thread.c
new file mode 100644
index 0000000000..f20160b200
--- /dev/null
+++ b/src/freebsd/thread.c
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * freebsd/thread.c: FreeBSD specifics for atomic wait
+ *****************************************************************************
+ * Copyright (C) 2020 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <pthread.h>
+#include <sys/thr.h>
+#include <sys/umtx.h>
+
+#include <vlc_common.h>
+
+unsigned long vlc_thread_id(void)
+{
+ static _Thread_local int tid = -1;
+
+ if (unlikely(tid == -1))
+ tid = thr_self();
+
+ return tid;
+}
+
+static int vlc_umtx_wake(void *addr, int nr)
+{
+ return _umtx_op(addr, UMTX_OP_WAKE_PRIVATE, nr, NULL, NULL);
+}
+
+static int vlc_umtx_wait(void *addr, unsigned val, const struct timespec *ts)
+{
+ struct _umtx_time to = {
+ ._timeout = *ts,
+ ._flags = UMTX_ABSTIME,
+ ._clockid = CLOCK_MONOTONIC,
+ };
+ int ret, type;
+ /* "the uaddr value [...] must be equal to the size of the structure
+ * pointed to by uaddr2, casted to uintptr_t."
+ */
+ void *uaddr = (void *)sizeof (to);
+
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &type);
+ ret = _umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, val, uaddr, &to);
+ pthread_setcanceltype(type, NULL);
+ return ret;
+}
+
+void vlc_atomic_notify_one(void *addr)
+{
+ vlc_umtx_wake(addr, 1);
+}
+
+void vlc_atomic_notify_all(void *addr)
+{
+ vlc_umtx_wake(addr, INT_MAX);
+}
+
+void vlc_atomic_wait(void *addr, unsigned val)
+{
+ int ret = vlc_umtx_wait(addr, val, NULL);
+
+ assert(ret == 0 || ret == EINTR || ret == ERESTART);
+}
+
+int vlc_atomic_timedwait(void *addr, unsigned val, vlc_tick_t deadline)
+{
+ struct timespec ts = timespec_from_vlc_tick(delay);
+ int ret = vlc_umtx_wait(addr, val, &ts);
+
+ assert(ret == 0 || ret == ETIMEDOUT || ret == EINTR || ret == ERESTART);
+ return (ret != ETIMEDOUT) ? 0 : ret;
+}
More information about the vlc-commits
mailing list