Port Folly to PPC64
authorLeonardo Bianconi <leonardo.bianconi@eldorado.org.br>
Sun, 13 Sep 2015 16:47:49 +0000 (09:47 -0700)
committerfacebook-github-bot-9 <folly-bot@fb.com>
Sun, 13 Sep 2015 17:20:16 +0000 (10:20 -0700)
Summary: This patch adds PPC64 specific code in order to support this architecture and be able to be used by HHVM.
Closes #299

Reviewed By: @simpkins

Differential Revision: D2340723

Pulled By: @JoelMarcey

folly/DiscriminatedPtr.h
folly/Hash.h
folly/PackedSyncPtr.h
folly/PicoSpinLock.h
folly/Portability.h
folly/configure.ac
folly/detail/MemoryIdler.cpp
folly/small_vector.h
folly/test/Makefile.am
folly/test/small_vector_test.cpp

index 115a1121e7f16b3d16fdb00740f16e5b8bae5a6a..1054f595681c200a5c51941734eed925d40a80c1 100644 (file)
@@ -34,8 +34,8 @@
 #include <folly/Portability.h>
 #include <folly/detail/DiscriminatedPtrDetail.h>
 
-#if !FOLLY_X64
-# error "DiscriminatedPtr is x64-specific code."
+#if !FOLLY_X64 && !FOLLY_PPC64
+# error "DiscriminatedPtr is x64 and ppc64 specific code."
 #endif
 
 namespace folly {
index 07eb5571eb5a891f9d1907b399dcc64343cd2c06..194017fad14592cef56d3c703b5e37a2152b8c0a 100644 (file)
@@ -220,7 +220,8 @@ inline uint32_t fnv32(const char* s,
 inline uint32_t fnv32_buf(const void* buf,
                           size_t n,
                           uint32_t hash = FNV_32_HASH_START) {
-  const char* char_buf = reinterpret_cast<const char*>(buf);
+  // forcing signed char, since other platforms can use unsigned
+  const signed char* char_buf = reinterpret_cast<const signed char*>(buf);
 
   for (size_t i = 0; i < n; ++i) {
     hash += (hash << 1) + (hash << 4) + (hash << 7) +
@@ -249,7 +250,8 @@ inline uint64_t fnv64(const char* s,
 inline uint64_t fnv64_buf(const void* buf,
                           size_t n,
                           uint64_t hash = FNV_64_HASH_START) {
-  const char* char_buf = reinterpret_cast<const char*>(buf);
+  // forcing signed char, since other platforms can use unsigned
+  const signed char* char_buf = reinterpret_cast<const signed char*>(buf);
 
   for (size_t i = 0; i < n; ++i) {
     hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) +
@@ -271,7 +273,8 @@ inline uint64_t fnv64(const std::string& str,
 #define get16bits(d) (*((const uint16_t*) (d)))
 
 inline uint32_t hsieh_hash32_buf(const void* buf, size_t len) {
-  const char* s = reinterpret_cast<const char*>(buf);
+  // forcing signed char, since other platforms can use unsigned
+  const signed char* s = reinterpret_cast<const signed char*>(buf);
   uint32_t hash = static_cast<uint32_t>(len);
   uint32_t tmp;
   size_t rem;
index 8205c6f8031bb029fbf9614fe20367313cee0f0e..97ff844c23595f39fbc477b10b2d0aeaee5617bf 100644 (file)
@@ -19,8 +19,8 @@
 
 #include <folly/Portability.h>
 
-#if !FOLLY_X64
-# error "PackedSyncPtr is x64-specific code."
+#if !FOLLY_X64 && !FOLLY_PPC64
+# error "PackedSyncPtr is x64 and ppc64 specific code."
 #endif
 
 /*
index 2c1139cf94061268b9383f57aa6783445deffd5a..f2ca45c2acbb2015d32049ff2033cf84442e679d 100644 (file)
@@ -33,8 +33,8 @@
 #include <folly/detail/Sleeper.h>
 #include <folly/Portability.h>
 
-#if !FOLLY_X64 && !FOLLY_A64
-# error "PicoSpinLock.h is currently x64 and aarch64 only."
+#if !FOLLY_X64 && !FOLLY_A64 && !FOLLY_PPC64
+# error "PicoSpinLock.h is currently x64, aarch64 and ppc64 only."
 #endif
 
 namespace folly {
@@ -128,8 +128,34 @@ struct PicoSpinLock {
 #undef FB_DOBTS
 #elif FOLLY_A64
     ret = __atomic_fetch_or(&lock_, 1 << Bit, __ATOMIC_SEQ_CST);
+#elif FOLLY_PPC64
+#define FB_DOBTS(size)                                 \
+    asm volatile("\teieio\n"                           \
+                 "\tl" #size "arx 14,0,%[lockPtr]\n"   \
+                 "\tli 15,1\n"                         \
+                 "\tsldi 15,15,%[bit]\n"               \
+                 "\tand. 16,15,14\n"                   \
+                 "\tbne 0f\n"                          \
+                 "\tor 14,14,15\n"                     \
+                 "\tst" #size "cx. 14,0,%[lockPtr]\n"  \
+                 "\tbne 0f\n"                          \
+                 "\tori %[output],%[output],1\n"       \
+                 "\tisync\n"                           \
+                 "0:\n"                                \
+                 : [output] "+r" (ret)                 \
+                 : [lockPtr] "r"(&lock_),              \
+                   [bit] "i" (Bit)                     \
+                 : "cr0", "memory", "r14", "r15", "r16")
+
+    switch (sizeof(IntType)) {
+    case 2: FB_DOBTS(h); break;
+    case 4: FB_DOBTS(w); break;
+    case 8: FB_DOBTS(d); break;
+    }
+
+#undef FB_DOBTS
 #else
-#error "x86 aarch64 only"
+#error "x86 aarch64 ppc64 only"
 #endif
 
     return ret;
@@ -170,8 +196,30 @@ struct PicoSpinLock {
 #undef FB_DOBTR
 #elif FOLLY_A64
     __atomic_fetch_and(&lock_, ~(1 << Bit), __ATOMIC_SEQ_CST);
+#elif FOLLY_PPC64
+#define FB_DOBTR(size)                                 \
+    asm volatile("\teieio\n"                           \
+                 "0:  l" #size "arx 14,0,%[lockPtr]\n" \
+                 "\tli 15,1\n"                         \
+                 "\tsldi 15,15,%[bit]\n"               \
+                 "\txor 14,14,15\n"                    \
+                 "\tst" #size "cx. 14,0,%[lockPtr]\n"  \
+                 "\tbne 0b\n"                          \
+                 "\tisync\n"                           \
+                 :                                     \
+                 : [lockPtr] "r"(&lock_),              \
+                   [bit] "i" (Bit)                     \
+                 : "cr0", "memory", "r14", "r15")
+
+    switch (sizeof(IntType)) {
+    case 2: FB_DOBTR(h); break;
+    case 4: FB_DOBTR(w); break;
+    case 8: FB_DOBTR(d); break;
+    }
+
+#undef FB_DOBTR
 #else
-# error "x64 aarch64 only"
+# error "x64 aarch64 ppc64 only"
 #endif
   }
 };
index b990b302938c138d5b82a34d382c99c2372df119..17d07e2029e5d4bd4fb2d7bf697013a365a03517 100644 (file)
 # define FOLLY_A64 0
 #endif
 
+#if defined (__powerpc64__)
+# define FOLLY_PPC64 1
+#else
+# define FOLLY_PPC64 0
+#endif
+
 // packing is very ugly in msvc
 #ifdef _MSC_VER
 # define FOLLY_PACK_ATTR /**/
@@ -355,6 +361,8 @@ inline void asm_volatile_pause() {
   asm volatile ("pause");
 #elif FOLLY_A64
   asm volatile ("wfe");
+#elif FOLLY_PPC64
+  asm volatile("or 27,27,27");
 #endif
 }
 inline void asm_pause() {
@@ -364,6 +372,8 @@ inline void asm_pause() {
   asm ("pause");
 #elif FOLLY_A64
   asm ("wfe");
+#elif FOLLY_PPC64
+  asm ("or 31,31,31");
 #endif
 }
 
index fad024dabb39d350bc9bc64a120b95fb7e029e52..b4d59e10dc1d89916a4c526529ea78c359536231 100644 (file)
@@ -404,6 +404,8 @@ AC_SUBST([AM_LDFLAGS])
 
 AM_CONDITIONAL([HAVE_STD_THREAD], [test "$ac_cv_header_features" = "yes"])
 AM_CONDITIONAL([HAVE_X86_64], [test "$build_cpu" = "x86_64"])
+AM_CONDITIONAL([HAVE_PPC64], [test "$build_cpu" = "powerpc64le"])
+AM_CONDITIONAL([RUN_ARCH_SPECIFIC_TESTS], [test "$build_cpu" = "x86_64" || test "$build_cpu" = "powerpc64le"])
 AM_CONDITIONAL([HAVE_LINUX], [test "$build_os" == "linux-gnu"])
 AM_CONDITIONAL([HAVE_WEAK_SYMBOLS],
                [test "$folly_cv_prog_cc_weak_symbols" = "yes"])
index 07ec2fbb9b1a218a2a61e0e7db72d15e40ff81f4..f7af9ee8266c3f24b6f34c62b3c3affe4c054d34 100644 (file)
@@ -92,7 +92,7 @@ void MemoryIdler::flushLocalMallocCaches() {
 // Stack madvise isn't Linux or glibc specific, but the system calls
 // and arithmetic (and bug compatibility) are not portable.  The set of
 // platforms could be increased if it was useful.
-#if FOLLY_X64 && defined(_GNU_SOURCE) && defined(__linux__)
+#if (FOLLY_X64 || FOLLY_PPC64 ) && defined(_GNU_SOURCE) && defined(__linux__)
 
 static const size_t s_pageSize = sysconf(_SC_PAGESIZE);
 static FOLLY_TLS uintptr_t tls_stackLimit;
index df237553e3f6c1e9d1cc8ecc815c6032b1f1bee2..8f7641366581e57521d8d6310a0ec7f702eb65b8 100644 (file)
@@ -48,7 +48,7 @@
 #include <folly/Malloc.h>
 #include <folly/Portability.h>
 
-#if defined(__GNUC__) && FOLLY_X64
+#if defined(__GNUC__) && (FOLLY_X64 || FOLLY_PPC64)
 # include <folly/SmallLocks.h>
 # define FB_PACK_ATTR FOLLY_PACK_ATTR
 # define FB_PACK_PUSH FOLLY_PACK_PUSH
@@ -1058,7 +1058,7 @@ private:
     }
   } FB_PACK_ATTR;
 
-#if FOLLY_X64
+#if (FOLLY_X64 || FOLLY_PPC64)
   typedef unsigned char InlineStorageType[sizeof(value_type) * MaxInline];
 #else
   typedef typename std::aligned_storage<
index f2af913bb832de77824be0876f3e6f4eb342fc2c..81076c59536a34b8d8fb3dace6e9bbc11ed14df1 100644 (file)
@@ -30,7 +30,7 @@ spin_lock_test_SOURCES = SpinLockTest.cpp
 spin_lock_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la
 TESTS += spin_lock_test
 
-if HAVE_X86_64
+if RUN_ARCH_SPECIFIC_TESTS
 small_locks_test_SOURCES = SmallLocksTest.cpp
 small_locks_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la
 TESTS += small_locks_test
@@ -48,10 +48,12 @@ discriminated_ptr_test_SOURCES = DiscriminatedPtrTest.cpp
 discriminated_ptr_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la
 TESTS += discriminated_ptr_test
 
+if !HAVE_PPC64
 cpuid_test_SOURCES = CpuIdTest.cpp
 cpuid_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la
 TESTS += cpuid_test
 endif
+endif
 
 sorted_vector_types_test_SOURCES = sorted_vector_test.cpp
 sorted_vector_types_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la
index f31bafa71183763dd8cdebc4c8aab0f95eafa6b8..746fc27f54c99540810cd42fde872eb1f98628fd 100644 (file)
@@ -32,7 +32,7 @@
 using folly::small_vector;
 using namespace folly::small_vector_policy;
 
-#if FOLLY_X64
+#if FOLLY_X64 || FOLLY_PPC64
 
 static_assert(sizeof(small_vector<int>) == 16,
               "Object size is not what we expect for small_vector<int>");