[Mesa-dev] [PATCH 07/14] anv: FreeBSD support in the allocator

Greg V greg at unrelenting.technology
Sun Dec 31 16:55:21 UTC 2017


Use umtx for futex, and SHM_ANON for memfd.

Also use temp files as memfd fallback for other OSes.

Obtained from: FreeBSD ports
---
 src/intel/vulkan/anv_allocator.c | 56 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c
index 33bd3c68c5..c31d3d17d2 100644
--- a/src/intel/vulkan/anv_allocator.c
+++ b/src/intel/vulkan/anv_allocator.c
@@ -25,7 +25,13 @@
 #include <unistd.h>
 #include <limits.h>
 #include <assert.h>
+#ifdef __linux__
 #include <linux/memfd.h>
+#elif __FreeBSD__
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/umtx.h>
+#endif
 #include <sys/mman.h>
 
 #include "anv_private.h"
@@ -50,6 +56,34 @@
 #define VG_NOACCESS_WRITE(__ptr, __val) (*(__ptr) = (__val))
 #endif
 
+#ifdef __FreeBSD__
+static inline int
+sys_futex(void *addr, int op, int32_t val)
+{
+   return _umtx_op(addr, op, (uint32_t)val, NULL, NULL) == -1 ? errno : 0;
+}
+
+static inline int
+futex_wake(uint32_t *addr, int count)
+{
+   return sys_futex(addr, UMTX_OP_WAKE, count);
+}
+
+static inline int
+futex_wait(uint32_t *addr, int32_t value, int32_t _)
+{
+   return sys_futex(addr, UMTX_OP_WAIT_UINT, value);
+}
+#endif
+
+#ifndef MAP_POPULATE
+#define MAP_POPULATE 0
+#endif
+
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC O_CLOEXEC
+#endif
+
 /* Design goals:
  *
  *  - Lock free (except when resizing underlying bos)
@@ -113,7 +147,29 @@ struct anv_mmap_cleanup {
 static inline int
 memfd_create(const char *name, unsigned int flags)
 {
+#if defined(__linux__)
    return syscall(SYS_memfd_create, name, flags);
+#elif defined(__FreeBSD__)
+   return shm_open(SHM_ANON, flags | O_RDWR | O_CREAT, 0600);
+#else /* DragonFly, NetBSD, OpenBSD, Solaris */
+   char template[] = "/tmp/shmfd-XXXXXX";
+#ifdef HAVE_MKOSTEMP
+   int fd = mkostemp(template, flags);
+#else
+   int fd = mkstemp(template);
+   if (flags & O_CLOEXEC) {
+     int flags = fcntl(fd, F_GETFD);
+     if (flags != -1) {
+       flags |= FD_CLOEXEC;
+       (void) fcntl(fd, F_SETFD, &flags);
+     }
+   }
+#endif /* HAVE_MKOSTEMP */
+   if (fd >= 0)
+     unlink(template);
+
+   return fd;
+#endif /* __linux__ */
 }
 #endif
 
-- 
2.15.1



More information about the mesa-dev mailing list