Added support for SunCC on Solaris/SPARC.
authorSander Pronk <pronk@cbr.su.se>
Wed, 8 Jun 2011 13:57:34 +0000 (15:57 +0200)
committerSander Pronk <pronk@cbr.su.se>
Wed, 8 Jun 2011 13:57:34 +0000 (15:57 +0200)
Based on a patch provided by Sergey Klyaus.

include/gmx_cyclecounter.h
include/thread_mpi/atomic.h
include/thread_mpi/atomic/suncc-sparc.h [new file with mode: 0644]
src/gmxlib/string2.c
src/kernel/xlate.c
src/tools/gmx_membed.c

index d3a587c3fe4308d2931559a678d966b62105ce1c..620df2c016e4efc6faf8b45c0c9a60270863c30a 100644 (file)
@@ -137,6 +137,11 @@ gmx_cycles_t;
 typedef unsigned long long 
 gmx_cycles_t;
 
+#elif defined(__sun) && defined(__sparcv9)
+
+typedef unsigned long
+gmx_cycles_t;
+
 #else
 /*! \brief Integer-like datatype for cycle counter values
  * 
@@ -273,6 +278,13 @@ static __inline__ int gmx_cycles_have_counter(void)
     /* Metrowerks on macintosh */
     return 1;
 }
+#elif defined(__sun) && defined(__sparcv9)
+
+static __inline__ int gmx_cycles_have_counter(void)
+{ 
+    /* Solaris on SPARC*/
+    return 1;
+}
 #else
 static int gmx_cycles_have_counter(void)
 { 
@@ -458,6 +470,15 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void)
     
     return (((gmx_cycles_t)high2) << 32) | (gmx_cycles_t)low;  
 }
+#elif defined(__sun) && defined(__sparcv9)
+
+static __inline__ gmx_cycles_t gmx_cycles_read(void)
+{
+     gmx_cycles_t ret;
+     __asm__ __volatile__("rd %%tick, %0" : "=r" (ret));
+     return ret;
+}
+
 #else
 static gmx_cycles_t gmx_cycles_read(void)
 { 
index deb5a6036180a00c1df81db6d951c124927be611..6133286bab7317036575c8c3870e9323a534ea53 100644 (file)
@@ -134,6 +134,9 @@ extern "C"
 #include "atomic/xlc_ppc.h"
 
 
+#elif defined (__sun) && (defined(__sparcv9) || defined(__sparc))
+/* Solaris on SPARC (Sun C Compiler, Solaris Studio) */
+#include "atomic/suncc-sparc.h"
 
 
 
diff --git a/include/thread_mpi/atomic/suncc-sparc.h b/include/thread_mpi/atomic/suncc-sparc.h
new file mode 100644 (file)
index 0000000..201dc27
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+This source code file is part of thread_mpi.  
+Written by Sander Pronk, Erik Lindahl, and possibly others. 
+
+Copyright (c) 2009, Sander Pronk, Erik Lindahl.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1) Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2) 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.
+3) Neither the name of the copyright holders 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 US ''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 WE 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.
+
+If you want to redistribute modifications, please consider that
+scientific software is very special. Version control is crucial -
+bugs must be traceable. We will be happy to consider code for
+inclusion in the official distribution, but derived work should not
+be called official thread_mpi. Details are found in the README & COPYING
+files.
+*/
+
+
+/* File contributed by Sergey Klyaus */
+
+#include <atomic.h>
+
+/* this is for newer versions of gcc that have built-in intrinsics,
+   on platforms not explicitly supported with inline assembly. */
+
+#define tMPI_Atomic_memory_barrier()  do { membar_consumer(); membar_producer(); } while (0)
+
+/* Only gcc and Intel support this check, otherwise set it to true (skip doc) */
+#if (!defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined DOXYGEN)
+#define __builtin_constant_p(i) (1)
+#endif
+
+
+typedef struct tMPI_Atomic
+{
+    volatile uint_t value;   
+}
+tMPI_Atomic_t;
+
+typedef struct tMPI_Atomic_ptr
+{
+    void* volatile value;   
+}
+tMPI_Atomic_ptr_t;
+
+
+
+#define TMPI_SPINLOCK_INITIALIZER   { 0 }
+
+
+/* for now we simply assume that int and void* assignments are atomic */
+#define tMPI_Atomic_get(a)  ((int)( (a)->value) )
+#define tMPI_Atomic_set(a,i)  (((a)->value) = (i))
+
+
+#define tMPI_Atomic_ptr_get(a)  ((void*)((a)->value) )
+#define tMPI_Atomic_ptr_set(a,i)  (((a)->value) = (void*)(i))
+
+static inline int tMPI_Atomic_add_return(tMPI_Atomic_t *a, volatile int i)
+{
+    return (int) atomic_add_int_nv(&a->value, i);
+}
+
+static inline int tMPI_Atomic_fetch_add(tMPI_Atomic_t *a, volatile int i)
+{
+    return (int) atomic_add_int_nv(&a->value, i) - i;
+}
+
+
+static inline int tMPI_Atomic_cas(tMPI_Atomic_t *a, int oldval, int newval)
+{
+    return (int)atomic_cas_uint(&a->value, (uint_t)oldval, (uint_t)newval);
+}
+
+
+static inline int tMPI_Atomic_ptr_cas(tMPI_Atomic_ptr_t* a, void *oldval, 
+                                      void *newval)
+{
+    /*atomic_cas_ptr always returns value stored in a, so*/
+    return atomic_cas_ptr(&(a->value), oldval, newval) == oldval;
+}
+
+
+
+typedef struct tMPI_Spinlock
+{
+    volatile unsigned long  lock;
+} tMPI_Spinlock_t;
+
+#define TMPI_SPINLOCK_INITIALIZER   { 0 }
+
+static inline unsigned long tas(volatile unsigned long *ptr)
+{
+    unsigned long result;
+    __asm__ __volatile__("          \
+            ldstub [%1], %0         "
+                               : "=r"(result)
+                : "r"(ptr)
+                : "memory");
+    return result;
+}
+
+
+static inline void tMPI_Spinlock_init(tMPI_Spinlock_t *x)
+{
+    x->lock = 0;
+}
+
+
+static inline void tMPI_Spinlock_lock(tMPI_Spinlock_t *x)
+{
+    do
+    {
+    } while (tas(&(x->lock)) == 1);
+}
+
+
+static inline int tMPI_Spinlock_trylock(tMPI_Spinlock_t *x)
+{
+    return tas(&(x->lock));
+}
+
+
+static inline void tMPI_Spinlock_unlock(tMPI_Spinlock_t *  x)
+{
+    x->lock = 0;
+}
+static inline int tMPI_Spinlock_islocked(const tMPI_Spinlock_t *  x)
+{
+    tMPI_Atomic_memory_barrier();
+    return ( x->lock == 1 );
+}
+
+static inline void tMPI_Spinlock_wait(tMPI_Spinlock_t *   x)
+{
+    do
+    {
+    } while (x->lock == 1);
+    tMPI_Atomic_memory_barrier();
+}
+
index 8f5f20b3d4c9a87b0140084ac2ccee479072e6c0..ce6f341905e4967c01c67c2b0ecbb2ed4dadf539 100644 (file)
@@ -179,6 +179,9 @@ gmx_ctime_r(const time_t *clock,char *buf, int n)
 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
     /* Windows */
     ctime_s( tmpbuf, STRLEN, clock );
+#elif (defined(__sun))
+    /*Solaris*/
+    ctime_r(clock, tmpbuf, n);
 #else
     ctime_r(clock,tmpbuf);
 #endif
index 88306726cdef457be886c759dd0cb0a254277e70..d6207c3ac89f70b34ae0af90c711f03e1ed46a75 100644 (file)
@@ -63,7 +63,7 @@ static void get_xlatoms(const char *fn,FILE *fp,
 {
     char filebase[STRLEN];
     char line[STRLEN];
-    char rbuf[1024],abuf[1024],repbuf[1024],dumbuf[1024];
+    char abuf[1024],rbuf[1024],repbuf[1024],dumbuf[1024];
     char *_ptr;
     int  n,na,idum;
     t_xlate_atom *xl;
index c51ffc1d3646c50c62096bedaca134b314165e53..a290ec057b7cfd1b38b6dd16872a86549323fe08 100644 (file)
@@ -153,7 +153,7 @@ typedef struct {
        int             *mol;
        int             *block;
        int     nr;
-} rm_t;
+} rmm_t;
 
 int search_string(char *s,int ng,char ***gn)
 {
@@ -560,7 +560,7 @@ void resize(t_block *ins_at, rvec *r_ins, rvec *r, pos_ins_t *pos_ins,rvec fac)
                }
 }
 
-int gen_rm_list(rm_t *rm_p,t_block *ins_at,t_block *rest_at,t_pbc *pbc, gmx_mtop_t *mtop,
+int gen_rm_list(rmm_t *rm_p,t_block *ins_at,t_block *rest_at,t_pbc *pbc, gmx_mtop_t *mtop,
                rvec *r, rvec *r_ins, mem_t *mem_p, pos_ins_t *pos_ins, real probe_rad, int low_up_rm, gmx_bool bALLOW_ASYMMETRY)
 {
        int i,j,k,l,at,at2,mol_id;
@@ -697,7 +697,7 @@ int gen_rm_list(rm_t *rm_p,t_block *ins_at,t_block *rest_at,t_pbc *pbc, gmx_mtop
        return nupper+nlower;
 }
 
-void rm_group(t_inputrec *ir, gmx_groups_t *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state *state, t_block *ins_at, pos_ins_t *pos_ins)
+void rm_group(t_inputrec *ir, gmx_groups_t *groups, gmx_mtop_t *mtop, rmm_t *rm_p, t_state *state, t_block *ins_at, pos_ins_t *pos_ins)
 {
        int i,j,k,n,rm,mol_id,at,block;
        rvec *x_tmp,*v_tmp;
@@ -873,7 +873,7 @@ int rm_bonded(t_block *ins_at, gmx_mtop_t *mtop)
        return rm_at;
 }
 
-void top_update(const char *topfile, char *ins, rm_t *rm_p, gmx_mtop_t *mtop)
+void top_update(const char *topfile, char *ins, rmm_t *rm_p, gmx_mtop_t *mtop)
 {
 #define TEMP_FILENM "temp.top"
        int     bMolecules=0;
@@ -2758,7 +2758,7 @@ int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
        t_block                 *ins_at,*rest_at;
        pos_ins_t               *pos_ins;
        mem_t                   *mem_p;
-       rm_t                    *rm_p;
+       rmm_t                   *rm_p;
        gmx_groups_t            *groups;
        gmx_bool                        bExcl=FALSE;
        t_atoms                 atoms;