afsmonitor: avoid double free on exit
[openafs.git] / src / mcas / portable_defns.h
index fb1c246..16d9202 100644 (file)
@@ -1,12 +1,48 @@
+/*
+Copyright (c) 2003, Keir Fraser All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+    * notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+    * copyright notice, this list of conditions and the following
+    * disclaimer in the documentation and/or other materials provided
+    * with the distribution.  Neither the name of the Keir Fraser
+    * nor the names of its contributors may be used to endorse or
+    * promote products derived from this software without specific
+    * prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifndef __PORTABLE_DEFNS_H__
 #define __PORTABLE_DEFNS_H__
 
-#define MAX_THREADS 128 /* Nobody will ever have more! */
+#define MAX_THREADS 256 /* Nobody will ever have more! */
 
 #if defined(SPARC)
 #include "sparc_defns.h"
+#elif defined(SOLARIS_X86_686)
+#include "solaris_x86_defns.h"
+#elif defined(SOLARIS_X86_AMD64)
+#include "solaris_amd64_defns.h"
 #elif defined(INTEL)
 #include "intel_defns.h"
+#elif defined(X86_64)
+#include "amd64_defns.h"
 #elif defined(PPC)
 #include "ppc_defns.h"
 #elif defined(IA64)
 
 typedef unsigned long int_addr_t;
 
-typedef int bool_t;
 #define FALSE 0
 #define TRUE  1
 
 #define ADD_TO(_v,_x)                                                   \
 do {                                                                    \
-    int __val = (_v), __newval;                                         \
+    unsigned long __val = (_v), __newval;                               \
     while ( (__newval = CASIO(&(_v),__val,__val+(_x))) != __val )       \
         __val = __newval;                                               \
 } while ( 0 )
 
+/* new 'returning' versions allow use of old value at the successful
+ * CAS update (Matt).  This allows an atomic inc to know if it was, for
+ * example, the operation which uniquely incremented _v from 0 to 1, and
+ * all equivalent threshold assertions */
+
+#define ADD_TO_RETURNING_OLD(_v,_x,_o)                                  \
+do {                                                                    \
+    unsigned long __val = (_v), __newval;                               \
+    while ( (__newval = CASIO(&(_v),__val,__val+(_x))) != __val )       \
+        __val = __newval;                                               \
+       _o = __val;                                                                                                                     \
+} while ( 0 )
+
+#define SUB_FROM(_v,_x)                                                 \
+do {                                                                    \
+    unsigned long __val = (_v), __newval;                               \
+    while ( (__newval = CASIO(&(_v),__val,__val-(_x))) != __val )       \
+        __val = __newval;                                               \
+} while ( 0 )
+
+#define SUB_FROM_RETURNING_OLD(_v,_x,_o)                                \
+do {                                                                    \
+    unsigned long __val = (_v), __newval;                               \
+    while ( (__newval = CASIO(&(_v),__val,__val-(_x))) != __val )       \
+        __val = __newval;                                               \
+       _o = __val;                                                                                                                     \
+} while ( 0 )
+
 /*
  * Allow us to efficiently align and pad structures so that shared fields
  * don't cause contention on thread-local or read-only fields.
@@ -99,6 +162,8 @@ do {                                                            \
 
 #endif
 
+#if !defined(INTEL) && !defined(SOLARIS_X86_686) && !defined(SOLARIS_X86_AMD64) && !defined(X86_64)
+
 /*
  * Strong LL/SC operations
  */
@@ -120,8 +185,10 @@ static _u32 strong_ll(_u64 *ptr, int p)
 
     return (_u32) (val_read >> 32);
 }
+#endif /* !INTEL */
 
-static int strong_vl(_u64 *ptr, int p) 
+
+static int strong_vl(_u64 *ptr, int p)
 {
     _u64 val_read;
     _u64 flag;
@@ -132,7 +199,8 @@ static int strong_vl(_u64 *ptr, int p)
     return (val_read & flag);
 }
 
-static int strong_sc(_u64 *ptr, int p, _u32 n) 
+#if !defined(INTEL) && !defined(X86_64)
+static int strong_sc(_u64 *ptr, int p, _u32 n)
 {
     _u64 val_read;
     _u64 new_val;
@@ -155,8 +223,10 @@ static int strong_sc(_u64 *ptr, int p, _u32 n)
 
     return 0;
 }
+#endif /* !INTEL */
+
 
-static void s_store(_u64 *ptr, _u32 n) 
+static void s_store(_u64 *ptr, _u32 n)
 {
     _u64 new_val;
 
@@ -164,7 +234,7 @@ static void s_store(_u64 *ptr, _u32 n)
     *ptr = new_val;
 }
 
-static _u32 s_load(_u64 *ptr) 
+static _u32 s_load(_u64 *ptr)
 {
     _u64 val_read;
 
@@ -272,7 +342,7 @@ static void rd_lock(mrsw_lock_t *lock, mrsw_qnode_t *qn)
     WMB_NEAR_CAS();
 
     pred = FASPO(&lock->tail, qn);
-    
+
     if ( pred == NULL )
     {
         ADD_TO(lock->reader_count, 1);
@@ -328,7 +398,7 @@ static void rd_unlock(mrsw_lock_t *lock, mrsw_qnode_t *qn)
     /* Bounded to maximum # readers if no native atomic_decrement */
     c = lock->reader_count;
     while ( (oc = CASIO(&lock->reader_count, c, c-1)) != c ) c = oc;
-   
+
     if ( c == 1 )
     {
         WEAK_DEP_ORDER_MB();
@@ -355,7 +425,7 @@ static void wr_lock(mrsw_lock_t *lock, mrsw_qnode_t *qn)
     qn->state = ST_NOSUCC | ST_BLOCKED;
 
     WMB_NEAR_CAS();
-    
+
     pred = FASPO(&lock->tail, qn);
 
     if ( pred == NULL )