xshmfence_futex.c revision ed6f5d66
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/** 30 * xshmfence_trigger: 31 * @f: An X fence 32 * 33 * Set @f to triggered, waking all waiters. 34 * 35 * Return value: 0 on success and -1 on error (in which case, errno 36 * will be set as appropriate). 37 **/ 38int 39xshmfence_trigger(struct xshmfence *f) 40{ 41 if (__sync_val_compare_and_swap(&f->v, 0, 1) == -1) { 42 atomic_store(&f->v, 1); 43 if (futex_wake(&f->v) < 0) 44 return -1; 45 } 46 return 0; 47} 48 49/** 50 * xshmfence_await: 51 * @f: An X fence 52 * 53 * Wait for @f to be triggered. If @f is already triggered, this 54 * function returns immediately. 55 * 56 * Return value: 0 on success and -1 on error (in which case, errno 57 * will be set as appropriate). 58 **/ 59int 60xshmfence_await(struct xshmfence *f) 61{ 62 while (__sync_val_compare_and_swap(&f->v, 0, -1) != 1) { 63 if (futex_wait(&f->v, -1)) { 64 if (errno != EWOULDBLOCK) 65 return -1; 66 } 67 } 68 return 0; 69} 70 71/** 72 * xshmfence_query: 73 * @f: An X fence 74 * 75 * Return value: 1 if @f is triggered, else returns 0. 76 **/ 77int 78xshmfence_query(struct xshmfence *f) 79{ 80 return atomic_fetch(&f->v) == 1; 81} 82 83/** 84 * xshmfence_reset: 85 * @f: An X fence 86 * 87 * Reset @f to untriggered. If @f is already untriggered, 88 * this function has no effect. 89 **/ 90void 91xshmfence_reset(struct xshmfence *f) 92{ 93 __sync_bool_compare_and_swap(&f->v, 1, 0); 94} 95