xshmfence_alloc.c revision 875bea1a
1/* 2 * Copyright © 2013 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of the copyright holders not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. The copyright holders make no representations 11 * about the suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 * OF THIS SOFTWARE. 21 */ 22 23#if HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27#include "xshmfenceint.h" 28 29#if !HAVE_MEMFD_CREATE 30#if HAVE_DECL___NR_MEMFD_CREATE 31#include <asm/unistd.h> 32static int memfd_create(const char *name, 33 unsigned int flags) 34{ 35 return syscall(__NR_memfd_create, name, flags); 36} 37#define HAVE_MEMFD_CREATE 1 38#endif 39#endif 40 41#if HAVE_MEMFD_CREATE 42 43/* Get defines for the memfd_create syscall, using the 44 * header if available, or just defining the constants otherwise 45 */ 46 47#if HAVE_MEMFD_H 48#include <sys/memfd.h> 49#else 50/* flags for memfd_create(2) (unsigned int) */ 51#define MFD_CLOEXEC 0x0001U 52#define MFD_ALLOW_SEALING 0x0002U 53#endif 54 55#endif 56 57/** 58 * xshmfence_alloc_shm: 59 * 60 * Allocates a shared memory object large enough to hold a single 61 * fence. 62 * 63 * Return value: the file descriptor of the object, or -1 on failure 64 * (in which case, errno will be set as appropriate). 65 **/ 66int 67xshmfence_alloc_shm(void) 68{ 69 char template[] = SHMDIR "/shmfd-XXXXXX"; 70 int fd; 71 72#if HAVE_MEMFD_CREATE 73 fd = memfd_create("xshmfence", MFD_CLOEXEC|MFD_ALLOW_SEALING); 74 if (fd < 0) 75#endif 76 { 77#ifdef O_TMPFILE 78 fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666); 79 if (fd < 0) 80#endif 81 { 82 fd = mkstemp(template); 83 if (fd < 0) 84 return fd; 85 unlink(template); 86 } 87 } 88 if (ftruncate(fd, sizeof (struct xshmfence)) < 0) { 89 close(fd); 90 return -1; 91 } 92 xshmfence_init(fd); 93 return fd; 94} 95 96/** 97 * xshmfence_map_shm: 98 * 99 * Map a shared memory fence referenced by @fd. 100 * 101 * Return value: the fence or NULL (in which case, errno will be set 102 * as appropriate). 103 **/ 104struct xshmfence * 105xshmfence_map_shm(int fd) 106{ 107 struct xshmfence *addr; 108 addr = mmap (NULL, sizeof (struct xshmfence) , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 109 if (addr == MAP_FAILED) { 110 close (fd); 111 return 0; 112 } 113#ifdef HAVE_SEMAPHORE 114 xshmfence_open_semaphore(addr); 115#endif 116 return addr; 117} 118 119/** 120 * xshmfence_unmap_shm: 121 * 122 * Unap a shared memory fence @f. 123 **/ 124void 125xshmfence_unmap_shm(struct xshmfence *f) 126{ 127#ifdef HAVE_SEMAPHORE 128 xshmfence_close_semaphore(f); 129#endif 130 munmap(f, sizeof (struct xshmfence)); 131} 132