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 pthread_mutex_lock(&f->lock); 41 if (f->value == 0) { 42 f->value = 1; 43 if (f->waiting) { 44 f->waiting = 0; 45 pthread_cond_broadcast(&f->wakeup); 46 } 47 } 48 pthread_mutex_unlock(&f->lock); 49 return 0; 50} 51 52/** 53 * xshmfence_await: 54 * @f: An X fence 55 * 56 * Wait for @f to be triggered. If @f is already triggered, this 57 * function returns immediately. 58 * 59 * Return value: 0 on success and -1 on error (in which case, errno 60 * will be set as appropriate). 61 **/ 62int 63xshmfence_await(struct xshmfence *f) { 64 pthread_mutex_lock(&f->lock); 65 while (f->value == 0) { 66 f->waiting = 1; 67 pthread_cond_wait(&f->wakeup, &f->lock); 68 } 69 pthread_mutex_unlock(&f->lock); 70 return 0; 71} 72 73/** 74 * xshmfence_query: 75 * @f: An X fence 76 * 77 * Return value: 1 if @f is triggered, else returns 0. 78 **/ 79int 80xshmfence_query(struct xshmfence *f) { 81 int value; 82 83 pthread_mutex_lock(&f->lock); 84 value = f->value; 85 pthread_mutex_unlock(&f->lock); 86 return value; 87} 88 89/** 90 * xshmfence_reset: 91 * @f: An X fence 92 * 93 * Reset @f to untriggered. If @f is already untriggered, 94 * this function has no effect. 95 **/ 96void 97xshmfence_reset(struct xshmfence *f) { 98 99 pthread_mutex_lock(&f->lock); 100 f->value = 0; 101 pthread_mutex_unlock(&f->lock); 102} 103 104/** 105 * xshmfence_init: 106 * @fd: An fd for an X fence 107 * 108 * Initialize the fence when first allocated 109 **/ 110 111void 112xshmfence_init(int fd) 113{ 114 struct xshmfence *f = xshmfence_map_shm(fd); 115 pthread_mutexattr_t mutex_attr; 116 pthread_condattr_t cond_attr; 117 118 if (!f) 119 return; 120 121 pthread_mutexattr_init(&mutex_attr); 122 pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); 123 pthread_mutex_init(&f->lock, &mutex_attr); 124 125 pthread_condattr_init(&cond_attr); 126 pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); 127 pthread_cond_init(&f->wakeup, &cond_attr); 128 f->value = 0; 129 f->waiting = 0; 130 xshmfence_unmap_shm(f); 131} 132