[vlc-devel] [PATCH] FreeBSD: add thread ID and atomic wait functions

Rémi Denis-Courmont remi at remlab.net
Mon Feb 17 21:54:22 CET 2020


---
 configure.ac         |  1 +
 src/Makefile.am      |  5 +++
 src/freebsd/thread.c | 94 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 100 insertions(+)
 create mode 100644 src/freebsd/thread.c

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;
+}
-- 
2.25.0



More information about the vlc-devel mailing list