1*1fb62fb0SOlivier Houchard /* 2*1fb62fb0SOlivier Houchard * Copyright 2010-2015 Samy Al Bahra. 3*1fb62fb0SOlivier Houchard * All rights reserved. 4*1fb62fb0SOlivier Houchard * 5*1fb62fb0SOlivier Houchard * Redistribution and use in source and binary forms, with or without 6*1fb62fb0SOlivier Houchard * modification, are permitted provided that the following conditions 7*1fb62fb0SOlivier Houchard * are met: 8*1fb62fb0SOlivier Houchard * 1. Redistributions of source code must retain the above copyright 9*1fb62fb0SOlivier Houchard * notice, this list of conditions and the following disclaimer. 10*1fb62fb0SOlivier Houchard * 2. Redistributions in binary form must reproduce the above copyright 11*1fb62fb0SOlivier Houchard * notice, this list of conditions and the following disclaimer in the 12*1fb62fb0SOlivier Houchard * documentation and/or other materials provided with the distribution. 13*1fb62fb0SOlivier Houchard * 14*1fb62fb0SOlivier Houchard * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*1fb62fb0SOlivier Houchard * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*1fb62fb0SOlivier Houchard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*1fb62fb0SOlivier Houchard * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*1fb62fb0SOlivier Houchard * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*1fb62fb0SOlivier Houchard * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*1fb62fb0SOlivier Houchard * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*1fb62fb0SOlivier Houchard * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*1fb62fb0SOlivier Houchard * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*1fb62fb0SOlivier Houchard * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*1fb62fb0SOlivier Houchard * SUCH DAMAGE. 25*1fb62fb0SOlivier Houchard */ 26*1fb62fb0SOlivier Houchard 27*1fb62fb0SOlivier Houchard #ifndef CK_SPINLOCK_CAS_H 28*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_CAS_H 29*1fb62fb0SOlivier Houchard 30*1fb62fb0SOlivier Houchard #include <ck_backoff.h> 31*1fb62fb0SOlivier Houchard #include <ck_cc.h> 32*1fb62fb0SOlivier Houchard #include <ck_elide.h> 33*1fb62fb0SOlivier Houchard #include <ck_pr.h> 34*1fb62fb0SOlivier Houchard #include <ck_stdbool.h> 35*1fb62fb0SOlivier Houchard 36*1fb62fb0SOlivier Houchard #ifndef CK_F_SPINLOCK_CAS 37*1fb62fb0SOlivier Houchard #define CK_F_SPINLOCK_CAS 38*1fb62fb0SOlivier Houchard /* 39*1fb62fb0SOlivier Houchard * This is a simple CACAS (TATAS) spinlock implementation. 40*1fb62fb0SOlivier Houchard */ 41*1fb62fb0SOlivier Houchard struct ck_spinlock_cas { 42*1fb62fb0SOlivier Houchard unsigned int value; 43*1fb62fb0SOlivier Houchard }; 44*1fb62fb0SOlivier Houchard typedef struct ck_spinlock_cas ck_spinlock_cas_t; 45*1fb62fb0SOlivier Houchard 46*1fb62fb0SOlivier Houchard #define CK_SPINLOCK_CAS_INITIALIZER {false} 47*1fb62fb0SOlivier Houchard 48*1fb62fb0SOlivier Houchard CK_CC_INLINE static void 49*1fb62fb0SOlivier Houchard ck_spinlock_cas_init(struct ck_spinlock_cas *lock) 50*1fb62fb0SOlivier Houchard { 51*1fb62fb0SOlivier Houchard 52*1fb62fb0SOlivier Houchard lock->value = false; 53*1fb62fb0SOlivier Houchard ck_pr_barrier(); 54*1fb62fb0SOlivier Houchard return; 55*1fb62fb0SOlivier Houchard } 56*1fb62fb0SOlivier Houchard 57*1fb62fb0SOlivier Houchard CK_CC_INLINE static bool 58*1fb62fb0SOlivier Houchard ck_spinlock_cas_trylock(struct ck_spinlock_cas *lock) 59*1fb62fb0SOlivier Houchard { 60*1fb62fb0SOlivier Houchard unsigned int value; 61*1fb62fb0SOlivier Houchard 62*1fb62fb0SOlivier Houchard value = ck_pr_fas_uint(&lock->value, true); 63*1fb62fb0SOlivier Houchard ck_pr_fence_lock(); 64*1fb62fb0SOlivier Houchard return !value; 65*1fb62fb0SOlivier Houchard } 66*1fb62fb0SOlivier Houchard 67*1fb62fb0SOlivier Houchard CK_CC_INLINE static bool 68*1fb62fb0SOlivier Houchard ck_spinlock_cas_locked(struct ck_spinlock_cas *lock) 69*1fb62fb0SOlivier Houchard { 70*1fb62fb0SOlivier Houchard bool r = ck_pr_load_uint(&lock->value); 71*1fb62fb0SOlivier Houchard 72*1fb62fb0SOlivier Houchard ck_pr_fence_acquire(); 73*1fb62fb0SOlivier Houchard return r; 74*1fb62fb0SOlivier Houchard } 75*1fb62fb0SOlivier Houchard 76*1fb62fb0SOlivier Houchard CK_CC_INLINE static void 77*1fb62fb0SOlivier Houchard ck_spinlock_cas_lock(struct ck_spinlock_cas *lock) 78*1fb62fb0SOlivier Houchard { 79*1fb62fb0SOlivier Houchard 80*1fb62fb0SOlivier Houchard while (ck_pr_cas_uint(&lock->value, false, true) == false) { 81*1fb62fb0SOlivier Houchard while (ck_pr_load_uint(&lock->value) == true) 82*1fb62fb0SOlivier Houchard ck_pr_stall(); 83*1fb62fb0SOlivier Houchard } 84*1fb62fb0SOlivier Houchard 85*1fb62fb0SOlivier Houchard ck_pr_fence_lock(); 86*1fb62fb0SOlivier Houchard return; 87*1fb62fb0SOlivier Houchard } 88*1fb62fb0SOlivier Houchard 89*1fb62fb0SOlivier Houchard CK_CC_INLINE static void 90*1fb62fb0SOlivier Houchard ck_spinlock_cas_lock_eb(struct ck_spinlock_cas *lock) 91*1fb62fb0SOlivier Houchard { 92*1fb62fb0SOlivier Houchard ck_backoff_t backoff = CK_BACKOFF_INITIALIZER; 93*1fb62fb0SOlivier Houchard 94*1fb62fb0SOlivier Houchard while (ck_pr_cas_uint(&lock->value, false, true) == false) 95*1fb62fb0SOlivier Houchard ck_backoff_eb(&backoff); 96*1fb62fb0SOlivier Houchard 97*1fb62fb0SOlivier Houchard ck_pr_fence_lock(); 98*1fb62fb0SOlivier Houchard return; 99*1fb62fb0SOlivier Houchard } 100*1fb62fb0SOlivier Houchard 101*1fb62fb0SOlivier Houchard CK_CC_INLINE static void 102*1fb62fb0SOlivier Houchard ck_spinlock_cas_unlock(struct ck_spinlock_cas *lock) 103*1fb62fb0SOlivier Houchard { 104*1fb62fb0SOlivier Houchard 105*1fb62fb0SOlivier Houchard /* Set lock state to unlocked. */ 106*1fb62fb0SOlivier Houchard ck_pr_fence_unlock(); 107*1fb62fb0SOlivier Houchard ck_pr_store_uint(&lock->value, false); 108*1fb62fb0SOlivier Houchard return; 109*1fb62fb0SOlivier Houchard } 110*1fb62fb0SOlivier Houchard 111*1fb62fb0SOlivier Houchard CK_ELIDE_PROTOTYPE(ck_spinlock_cas, ck_spinlock_cas_t, 112*1fb62fb0SOlivier Houchard ck_spinlock_cas_locked, ck_spinlock_cas_lock, 113*1fb62fb0SOlivier Houchard ck_spinlock_cas_locked, ck_spinlock_cas_unlock) 114*1fb62fb0SOlivier Houchard 115*1fb62fb0SOlivier Houchard CK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_cas, ck_spinlock_cas_t, 116*1fb62fb0SOlivier Houchard ck_spinlock_cas_locked, ck_spinlock_cas_trylock) 117*1fb62fb0SOlivier Houchard 118*1fb62fb0SOlivier Houchard #endif /* CK_F_SPINLOCK_CAS */ 119*1fb62fb0SOlivier Houchard #endif /* CK_SPINLOCK_CAS_H */ 120