1ed6f5d66Smrg/* 2ed6f5d66Smrg * Copyright © 2013 Keith Packard 3ed6f5d66Smrg * 4ed6f5d66Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5ed6f5d66Smrg * documentation for any purpose is hereby granted without fee, provided that 6ed6f5d66Smrg * the above copyright notice appear in all copies and that both that copyright 7ed6f5d66Smrg * notice and this permission notice appear in supporting documentation, and 8ed6f5d66Smrg * that the name of the copyright holders not be used in advertising or 9ed6f5d66Smrg * publicity pertaining to distribution of the software without specific, 10ed6f5d66Smrg * written prior permission. The copyright holders make no representations 11ed6f5d66Smrg * about the suitability of this software for any purpose. It is provided "as 12ed6f5d66Smrg * is" without express or implied warranty. 13ed6f5d66Smrg * 14ed6f5d66Smrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15ed6f5d66Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16ed6f5d66Smrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17ed6f5d66Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18ed6f5d66Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19ed6f5d66Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20ed6f5d66Smrg * OF THIS SOFTWARE. 21ed6f5d66Smrg */ 22ed6f5d66Smrg 23ed6f5d66Smrg#if HAVE_CONFIG_H 24ed6f5d66Smrg#include "config.h" 25ed6f5d66Smrg#endif 26ed6f5d66Smrg 27ed6f5d66Smrg#include "xshmfenceint.h" 28ed6f5d66Smrg 29ed6f5d66Smrg/** 30ed6f5d66Smrg * xshmfence_trigger: 31ed6f5d66Smrg * @f: An X fence 32ed6f5d66Smrg * 33ed6f5d66Smrg * Set @f to triggered, waking all waiters. 34ed6f5d66Smrg * 35ed6f5d66Smrg * Return value: 0 on success and -1 on error (in which case, errno 36ed6f5d66Smrg * will be set as appropriate). 37ed6f5d66Smrg **/ 38ed6f5d66Smrgint 39ed6f5d66Smrgxshmfence_trigger(struct xshmfence *f) 40ed6f5d66Smrg{ 41ed6f5d66Smrg if (__sync_val_compare_and_swap(&f->v, 0, 1) == -1) { 42ed6f5d66Smrg atomic_store(&f->v, 1); 43ed6f5d66Smrg if (futex_wake(&f->v) < 0) 44ed6f5d66Smrg return -1; 45ed6f5d66Smrg } 46ed6f5d66Smrg return 0; 47ed6f5d66Smrg} 48ed6f5d66Smrg 49ed6f5d66Smrg/** 50ed6f5d66Smrg * xshmfence_await: 51ed6f5d66Smrg * @f: An X fence 52ed6f5d66Smrg * 53ed6f5d66Smrg * Wait for @f to be triggered. If @f is already triggered, this 54ed6f5d66Smrg * function returns immediately. 55ed6f5d66Smrg * 56ed6f5d66Smrg * Return value: 0 on success and -1 on error (in which case, errno 57ed6f5d66Smrg * will be set as appropriate). 58ed6f5d66Smrg **/ 59ed6f5d66Smrgint 60ed6f5d66Smrgxshmfence_await(struct xshmfence *f) 61ed6f5d66Smrg{ 62ed6f5d66Smrg while (__sync_val_compare_and_swap(&f->v, 0, -1) != 1) { 63ed6f5d66Smrg if (futex_wait(&f->v, -1)) { 64ed6f5d66Smrg if (errno != EWOULDBLOCK) 65ed6f5d66Smrg return -1; 66ed6f5d66Smrg } 67ed6f5d66Smrg } 68ed6f5d66Smrg return 0; 69ed6f5d66Smrg} 70ed6f5d66Smrg 71ed6f5d66Smrg/** 72ed6f5d66Smrg * xshmfence_query: 73ed6f5d66Smrg * @f: An X fence 74ed6f5d66Smrg * 75ed6f5d66Smrg * Return value: 1 if @f is triggered, else returns 0. 76ed6f5d66Smrg **/ 77ed6f5d66Smrgint 78ed6f5d66Smrgxshmfence_query(struct xshmfence *f) 79ed6f5d66Smrg{ 80ed6f5d66Smrg return atomic_fetch(&f->v) == 1; 81ed6f5d66Smrg} 82ed6f5d66Smrg 83ed6f5d66Smrg/** 84ed6f5d66Smrg * xshmfence_reset: 85ed6f5d66Smrg * @f: An X fence 86ed6f5d66Smrg * 87ed6f5d66Smrg * Reset @f to untriggered. If @f is already untriggered, 88ed6f5d66Smrg * this function has no effect. 89ed6f5d66Smrg **/ 90ed6f5d66Smrgvoid 91ed6f5d66Smrgxshmfence_reset(struct xshmfence *f) 92ed6f5d66Smrg{ 93ed6f5d66Smrg __sync_bool_compare_and_swap(&f->v, 1, 0); 94ed6f5d66Smrg} 95