• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/genericProc/programs/qthread-1.4/include/qt_atomics.h

00001 #ifndef QT_ATOMICS_H
00002 #define QT_ATOMICS_H
00003 
00004 #include <pthread.h> /* for FASTLOCK stuff */
00005 #include <qthread/common.h>
00006 #include <qthread/qthread.h>
00007 
00008 #ifdef QTHREAD_NEEDS_IA64INTRIN
00009 # ifdef HAVE_IA64INTRIN_H
00010 #  include <ia64intrin.h>
00011 # elif defined(HAVE_IA32INTRIN_H)
00012 #  include <ia32intrin.h>
00013 # endif
00014 #endif
00015 
00016 #if defined(__tile__)
00017 # include <tmc/sync.h>
00018 # define QTHREAD_FASTLOCK_INIT(x) tmc_sync_mutex_init(&(x))
00019 # define QTHREAD_FASTLOCK_INIT_PTR(x) tmc_sync_mutex_init((x))
00020 # define QTHREAD_FASTLOCK_LOCK(x) tmc_sync_mutex_lock((x))
00021 # define QTHREAD_FASTLOCK_UNLOCK(x) tmc_sync_mutex_unlock((x))
00022 # define QTHREAD_FASTLOCK_DESTROY(x)
00023 # define QTHREAD_FASTLOCK_DESTROY_PTR(x)
00024 # define QTHREAD_FASTLOCK_TYPE tmc_sync_mutex_t
00025 # define QTHREAD_FASTLOCK_INITIALIZER TMC_SYNC_MUTEX_INIT
00026 #elif defined(HAVE_PTHREAD_SPIN_INIT)
00027 # define QTHREAD_FASTLOCK_INIT(x) pthread_spin_init(&(x), PTHREAD_PROCESS_PRIVATE)
00028 # define QTHREAD_FASTLOCK_INIT_PTR(x) pthread_spin_init((x), PTHREAD_PROCESS_PRIVATE)
00029 # define QTHREAD_FASTLOCK_LOCK(x) pthread_spin_lock((x))
00030 # define QTHREAD_FASTLOCK_UNLOCK(x) pthread_spin_unlock((x))
00031 # define QTHREAD_FASTLOCK_DESTROY(x) pthread_spin_destroy(&(x))
00032 # define QTHREAD_FASTLOCK_DESTROY_PTR(x) pthread_spin_destroy((x))
00033 # define QTHREAD_FASTLOCK_TYPE pthread_spinlock_t
00034 # define QTHREAD_FASTLOCK_INITIALIZER PTHREAD_SPINLOCK_INITIALIZER
00035 #else
00036 # define QTHREAD_FASTLOCK_INIT(x) pthread_mutex_init(&(x), NULL)
00037 # define QTHREAD_FASTLOCK_INIT_PTR(x) pthread_mutex_init((x), NULL)
00038 # define QTHREAD_FASTLOCK_LOCK(x) pthread_mutex_lock((x))
00039 # define QTHREAD_FASTLOCK_UNLOCK(x) pthread_mutex_unlock((x))
00040 # define QTHREAD_FASTLOCK_DESTROY(x) pthread_mutex_destroy(&(x))
00041 # define QTHREAD_FASTLOCK_DESTROY_PTR(x) pthread_mutex_destroy((x))
00042 # define QTHREAD_FASTLOCK_TYPE pthread_mutex_t
00043 # define QTHREAD_FASTLOCK_INITIALIZER PTHREAD_MUTEX_INITIALIZER
00044 #endif
00045 
00046 #ifdef QTHREAD_MUTEX_INCREMENT
00047 # define QTHREAD_CASLOCK(var)   var; QTHREAD_FASTLOCK_TYPE var##_caslock
00048 # define QTHREAD_CASLOCK_INIT(var,i)   var = i; QTHREAD_FASTLOCK_INIT(var##_caslock)
00049 # define QTHREAD_CASLOCK_DESTROY(var)   QTHREAD_FASTLOCK_DESTROY(var##_caslock)
00050 # define QTHREAD_CASLOCK_READ(var)   (void*)qt_cas_read_ui((volatile uintptr_t*)&(var), &(var##_caslock))
00051 # define QTHREAD_CASLOCK_READ_UI(var)   qt_cas_read_ui((volatile uintptr_t*)&(var), &(var##_caslock))
00052 # define QT_CAS(var,oldv,newv) qt_cas((void*volatile*)&(var), (void*)(oldv), (void*)(newv), &(var##_caslock))
00053 static QINLINE void* qt_cas(void*volatile* const ptr, void* const oldv, void* const newv, QTHREAD_FASTLOCK_TYPE *lock)
00054 {
00055     void * ret;
00056     QTHREAD_FASTLOCK_LOCK(lock);
00057     ret = *ptr;
00058     if (*ptr == oldv) {
00059         *ptr = newv;
00060     }
00061     QTHREAD_FASTLOCK_UNLOCK(lock);
00062     return ret;
00063 }
00064 static QINLINE uintptr_t qt_cas_read_ui(volatile uintptr_t * const ptr, QTHREAD_FASTLOCK_TYPE *mutex)
00065 {
00066     uintptr_t ret;
00067     QTHREAD_FASTLOCK_LOCK(mutex);
00068     ret = *ptr;
00069     QTHREAD_FASTLOCK_UNLOCK(mutex);
00070     return ret;
00071 }
00072 #else
00073 # define QTHREAD_CASLOCK(var)   (var)
00074 # define QTHREAD_CASLOCK2(var)  (var) = NULL
00075 # define QTHREAD_CASLOCK_INIT(var,i) (var) = i
00076 # define QTHREAD_CASLOCK_DESTROY(var)
00077 # define QTHREAD_CASLOCK_READ(var) (var)
00078 # define QTHREAD_CASLOCK_READ_UI(var) (var)
00079 # define QT_CAS(var,oldv,newv) qt_cas((void*volatile*)&(var), (void*)(oldv), (void*)(newv))
00080 # ifdef QTHREAD_ATOMIC_CAS_PTR
00081 #  define qt_cas(P,O,N) (void*)__sync_val_compare_and_swap((P),(O),(N))
00082 # else
00083 static QINLINE void* qt_cas(void*volatile* const ptr, void* const oldv, void* const newv)
00084 {/*{{{*/
00085 # if defined(HAVE_GCC_INLINE_ASSEMBLY)
00086 #  if (QTHREAD_ASSEMBLY_ARCH == QTHREAD_POWERPC32)
00087     void* result;
00088     __asm__ __volatile__ ("1:\n\t"
00089             "lwarx  %0,0,%3\n\t"
00090             "cmpw   %0,%1\n\t"
00091             "bne    2f\n\t"
00092             "stwcx. %2,0,%3\n\t"
00093             "bne-   1b\n"
00094             "2:"
00095             :"=&b" (result)
00096             :"r"(oldv), "r"(newv), "r"(ptr)
00097             :"cc", "memory");
00098     return result;
00099 #  elif (QTHREAD_ASSEMBLY_ARCH == QTHREAD_POWERPC64)
00100     void* result;
00101     __asm__ __volatile__ ("1:\n\t"
00102             "ldarx  %0,0,%3\n\t"
00103             "cmpw   %0,%1\n\t"
00104             "bne    2f\n\t"
00105             "stdcx. %2,0,%3\n\t"
00106             "bne-   1b\n"
00107             "2:"
00108             :"=&b" (result)
00109             :"r"(oldv), "r"(newv), "r"(ptr)
00110             :"cc", "memory");
00111     return result;
00112 #  elif (QTHREAD_ASSEMBLY_ARCH == QTHREAD_SPARCV9_32)
00113     void *nv = newv;
00114     __asm__ __volatile__
00115         ("cas [%1], %2, %0"
00116          : "=&r" (nv)
00117          : "r" (ptr), "r"(oldv)
00118 #if !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
00119          , "0"(nv)
00120 #endif
00121          : "cc", "memory");
00122     return nv;
00123 #  elif (QTHREAD_ASSEMBLY_ARCH == QTHREAD_SPARCV9_64)
00124     void *nv = newv;
00125     __asm__ __volatile__
00126         ("casx [%1], %2, %0"
00127          : "=&r" (nv)
00128          : "r" (ptr), "r"(oldv)
00129 #if !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
00130          , "0"(nv)
00131 #endif
00132          : "cc", "memory");
00133     return nv;
00134 #  elif (QTHREAD_ASSEMBLY_ARCH == QTHREAD_IA64)
00135     void ** retval;
00136     __asm__ __volatile__ ("mov ar.ccv=%0;;": :"rO" (oldv));
00137     __asm__ __volatile__ ("cmpxchg4.acq %0=[%1],%2,ar.ccv"
00138             :"=r"(retval)
00139             :"r"(ptr), "r"(newv)
00140             :"memory");
00141     return retval;
00142 #  elif (QTHREAD_ASSEMBLY_ARCH == QTHREAD_AMD64) || (QTHREAD_ASSEMBLY_ARCH == QTHREAD_IA32)
00143     void ** retval;
00144     /* note that this is GNU/Linux syntax (aka AT&T syntax), not Intel syntax.
00145      * Thus, this instruction has the form:
00146      * [lock] cmpxchg reg, reg/mem
00147      *                src, dest
00148      *
00149      * NOTE: this is valid even on 64-bit architectures, because AMD64
00150      * instantiates cmpxchg for 8-byte registers, and IA32 never has 64-bit
00151      * pointers
00152      */
00153 #   if (QTHREAD_ASSEMBLY_ARCH == QTHREAD_AMD64) && defined(__PGI)
00154     __asm__ __volatile__ ("lock; cmpxchg %1,(%2)\n\t"
00155             "mov %%rax,(%0)"
00156             ::"r"(&retval),
00157               "r"(newv), "r" (ptr),
00158               "a"(oldv) /* load into RAX */
00159             :"cc","memory");
00160 #   else
00161     __asm__ __volatile__ ("lock; cmpxchg %1,(%2)"
00162             : "=a"(retval) /* store from RAX */
00163             : "r"(newv), "r" (ptr),
00164               "a"(oldv) /* load into RAX */
00165             :"cc","memory");
00166 #   endif
00167     return retval;
00168 #  else
00169 #   error "Don't have a qt_cas implementation for this architecture"
00170 #  endif
00171 # else
00172 #  error "CAS needs inline assembly OR __sync_val_compare_and_swap"
00173 # endif
00174 }/*}}}*/
00175 # endif /* ATOMIC_CAS_PTR */
00176 #endif /* MUTEX_INCREMENT */
00177 
00178 #endif

Generated on Fri Oct 22 2010 11:02:24 for SST by  doxygen 1.7.1