2 * Copyright 2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and
30 * documentation are those of the authors and should not be
31 * interpreted as representing official policies, either expressed
32 * or implied, of GRNET S.A.
40 #define MFENCE() __sync_synchronize()
41 #define BARRIER() __asm__ __volatile__ ("" ::: "memory")
42 #define __pause() __asm__ __volatile__ ("pause\n");
46 #define Noone ((unsigned long)-1)
48 #define XLOCK_SANITY_CHECKS
49 #define XLOCK_CONGESTION_NOTIFY
51 #ifdef XLOCK_SANITY_CHECKS
52 #define MAX_VALID_OWNER 65536 /* we are not gonna have more ports than that */
53 #endif /* XLOCK_SANITY_CHECKS */
55 #ifdef XLOCK_CONGESTION_NOTIFY
57 #define MAX_SHIFT ((sizeof(unsigned long) * 8) -1)
58 #endif /* XLOCK_CONGESTION_NOTIFY */
63 //} __attribute__ ((aligned (16))); /* support up to 128bit longs */
65 static inline unsigned long xlock_acquire(struct xlock *lock, unsigned long who)
68 #ifdef XLOCK_CONGESTION_NOTIFY
69 unsigned long times = 1;
70 unsigned long shift = MIN_SHIFT;
71 #endif /* XLOCK_CONGESTION_NOTIFY */
74 for (; (owner = *(volatile unsigned long *)(&lock->owner) != Noone);){
75 #ifdef XLOCK_SANITY_CHECKS
76 if (owner > MAX_VALID_OWNER){
77 XSEGLOG("xlock %lx corrupted. Lock owner %lu",
78 (unsigned long) lock, owner);
79 XSEGLOG("Resetting xlock %lx to Noone",
80 (unsigned long) lock);
83 #endif /* XLOCK_SANITY_CHECKS */
84 #ifdef XLOCK_CONGESTION_NOTIFY
85 if (!(times & ((1<<shift) -1))){
86 XSEGLOG("xlock %lx spinned for %llu times"
87 "\n\t who: %lu, owner: %lu",
88 (unsigned long) lock, times,
90 if (shift < MAX_SHIFT)
95 #endif /* XLOCK_CONGESTION_NOTIFY */
99 if (__sync_bool_compare_and_swap(&lock->owner, Noone, who))
102 #ifdef XLOCK_SANITY_CHECKS
103 if (lock->owner > MAX_VALID_OWNER){
104 XSEGLOG("xlock %lx locked with INVALID lock owner %lu",
105 (unsigned long) lock, lock->owner);
107 #endif /* XLOCK_SANITY_CHECKS */
112 static inline unsigned long xlock_try_lock(struct xlock *lock, unsigned long who)
114 return __sync_bool_compare_and_swap(&lock->owner, Noone, who);
117 static inline void xlock_release(struct xlock *lock)
121 #ifdef XLOCK_SANITY_CHECKS
122 if (lock->owner > MAX_VALID_OWNER){
123 XSEGLOG("xlock %lx releasing lock with INVALID lock owner %lu",
124 (unsigned long) lock, lock->owner);
128 /* XLOCK_SANITY_CHECKS */
132 static inline unsigned long xlock_get_owner(struct xlock *lock)
134 return *(volatile unsigned long *)(&lock->owner);