Cleanup cmitls 57/4957/6
authorEvan Ramos <evan@hpccharm.com>
Mon, 18 Feb 2019 19:22:54 +0000 (13:22 -0600)
committerEvan Ramos <evan@hpccharm.com>
Thu, 28 Feb 2019 23:07:33 +0000 (17:07 -0600)
Change-Id: Ibf37d137a42cc5a262da4324490aeb2dab418ede

src/scripts/configure.ac
src/util/cmitls.C
src/util/cmitls.h

index 4dcff95..e545a31 100644 (file)
@@ -1431,36 +1431,28 @@ AC_DEFINE_UNQUOTED([CMK_HAS_EXECUTABLE_START], $pass, [whether has __executable_
 if test $in64bit = 1
 then
 cat > $t <<EOT
-#include <elf.h>
-#include <stdlib.h>
-#include <malloc.h>
-
 void switchTLS() {
-  Elf64_Addr m1, m2;
+  void * m1, * m2;
   asm volatile ("movq %%fs:0x0, %0\n\t"
                 "movq %1, %%fs:0x0\n\t"
-                : "=r"(m1)
+                : "=&r"(m1)
                 : "r"(m2));
 }
 EOT
 test_cxx "whether switching TLS register (64-bit) is supported" "yes" "no" ""
-AC_DEFINE_UNQUOTED(CMK_TLS_SWITCHING64, $strictpass, [Allows switching TLS 64-bit.])
+AC_DEFINE_UNQUOTED(CMK_TLS_SWITCHING_X86_64, $strictpass, [Allows switching TLS on x86_64.])
 else
 cat > $t <<EOT
-#include <elf.h>
-#include <stdlib.h>
-#include <malloc.h>
-
 void switchTLS() {
-  Elf32_Addr m1, m2;
+  void * m1, * m2;
   asm volatile ("movl %%gs:0x0, %0\n\t"
                 "movl %1, %%gs:0x0\n\t"
-                : "=r"(m1)
+                : "=&r"(m1)
                 : "r"(m2));
 }
 EOT
 test_cxx "whether switching TLS register (32-bit) is supported" "yes" "no" ""
-AC_DEFINE_UNQUOTED(CMK_TLS_SWITCHING32, $strictpass, [Allows switching TLS in 32-bit.])
+AC_DEFINE_UNQUOTED(CMK_TLS_SWITCHING_X86, $strictpass, [Allows switching TLS on x86.])
 fi
 
 ### test for dl_iterate_phdr ###
index eed5838..f6a84c3 100644 (file)
@@ -5,8 +5,9 @@
 #include "cmitls.h"
 #include "memory-isomalloc.h"
 
-#if CMK_HAS_TLS_VARIABLES && CMK_HAS_ELF_H \
-    && ((CMK_DLL_USE_DLOPEN && CMK_HAS_RTLD_DEFAULT) || CMK_HAS_DL_ITERATE_PHDR)
+#if CMK_HAS_TLS_VARIABLES
+
+CMI_EXTERNC_VARIABLE int quietModeRequested;
 
 /* These macros are needed for:
  * dlfcn.h: RTLD_DEFAULT
 # define __USE_GNU
 #endif
 
-#if CMK_HAS_DL_ITERATE_PHDR
-# include <link.h>
-#else
-# include <dlfcn.h>
-#endif
+
+// ----- TLS segment pointer access -----
 
 /*
  * For a description of the system TLS implementations this file works with, see:
  */
 
 extern "C" {
-void* getTLS(void) CMI_NOOPTIMIZE;
-void setTLS(void* newptr) CMI_NOOPTIMIZE;
-void* swapTLS(void* newptr) CMI_NOOPTIMIZE;
+void* getTLS();
+void setTLS(void*);
+void* swapTLS(void*);
 }
 
-CMI_EXTERNC_VARIABLE int quietModeRequested;
+#if CMK_TLS_SWITCHING_X86_64
+# define CMK_TLS_X86_MOV "movq"
+# define CMK_TLS_X86_REG "fs"
+#elif CMK_TLS_SWITCHING_X86
+# define CMK_TLS_X86_MOV "movl"
+# define CMK_TLS_X86_REG "gs"
+#else
+# define CMK_TLS_SWITCHING_UNAVAILABLE
+#endif
 
-#if !CMK_HAS_DL_ITERATE_PHDR
-static void* CmiTLSExecutableStart;
+void* getTLS()
+{
+#ifdef CMK_TLS_X86_MOV
+  void* ptr;
+  asm volatile (CMK_TLS_X86_MOV " %%" CMK_TLS_X86_REG ":0x0, %0\n"
+                : "=&r"(ptr));
+  return ptr;
+#else
+  return nullptr;
 #endif
+}
 
-void CmiTLSInit(void)
+void setTLS(void* newptr)
 {
-  if (CmiMyRank() == 0)
+#ifdef CMK_TLS_X86_MOV
+  asm volatile (CMK_TLS_X86_MOV " %0, %%" CMK_TLS_X86_REG ":0x0\n\t"
+                :
+                : "r"(newptr));
+#endif
+}
+
+void* swapTLS(void* newptr)
+{
+  void* oldptr = getTLS();
+  setTLS(newptr);
+  return oldptr;
+}
+
+
+// ----- TLS segment size determination -----
+
+#if CMK_HAS_DL_ITERATE_PHDR
+
+# include <link.h>
+
+static inline void CmiTLSStatsInit(void)
+{
+}
+
+static int count_tls_sizes(struct dl_phdr_info* info, size_t size, void* data)
+{
+  size_t i;
+  tlsseg_t* t = (tlsseg_t*)data;
+
+  for (i = 0; i < info->dlpi_phnum; i++)
   {
-    if (!quietModeRequested && CmiMyPe() == 0)
+    const ElfW(Phdr) * hdr = &info->dlpi_phdr[i];
+    if (hdr->p_type == PT_TLS)
     {
-      CmiPrintf("Charm++> -tlsglobals enabled for privatization of thread-local variables.\n");
-#if !CMK_HAS_DL_ITERATE_PHDR
-      CmiPrintf("Charm++> Warning: Unable to examine TLS segments of shared objects.\n");
-#endif
+      t->size += hdr->p_memsz;
+      if (t->align < hdr->p_align)
+        t->align = hdr->p_align;
     }
-
-#if !CMK_HAS_DL_ITERATE_PHDR
-    /* Use dynamic linking in case Charm++ shared objects are used by a binary lacking
-     * conv-static.o, such as in the case of Charm4py. */
-    void** pCmiExecutableStart = (void**)dlsym(RTLD_DEFAULT, "CmiExecutableStart");
-    if (pCmiExecutableStart != NULL)
-      CmiTLSExecutableStart = *pCmiExecutableStart;
-    else
-      CmiPrintf("Charm++> Error: \"CmiExecutableStart\" symbol not found. -tlsglobals disabled.\n");
-#endif
   }
+
+  return 0;
+}
+
+static void populateTLSSegStats(tlsseg_t * t)
+{
+  t->size = 0;
+  t->align = 0;
+  dl_iterate_phdr(count_tls_sizes, t); /* count all PT_TLS sections */
 }
 
-#if !CMK_HAS_DL_ITERATE_PHDR
-static Addr getCodeSegAddr(void) {
+#elif CMK_HAS_ELF_H && CMK_DLL_USE_DLOPEN && CMK_HAS_RTLD_DEFAULT
+
+# include <dlfcn.h>
+# define CMK_TLS_NO_SHARED
+
+static void* CmiTLSExecutableStart;
+
+static inline Addr getCodeSegAddr()
+{
   return (Addr) CmiTLSExecutableStart;
 }
 
-static Ehdr* getELFHeader(void) {
+static inline Ehdr* getELFHeader()
+{
   return (Ehdr*) getCodeSegAddr();
 }
 
-static Phdr* getProgramHeader(Ehdr* ehdr) {
+static inline Phdr* getProgramHeader(Ehdr* ehdr)
+{
   return (Phdr*)((char *)ehdr + ehdr->e_phoff);
 }
 
-Phdr* getTLSPhdrEntry(void) {
+Phdr* getTLSPhdrEntry()
+{
   int phnum, i;
   Ehdr* elfHeader;
   Phdr* progHeader;
@@ -92,13 +145,15 @@ Phdr* getTLSPhdrEntry(void) {
 
   phnum = elfHeader->e_phnum;
   progHeader = getProgramHeader(elfHeader);
-  for (i = 0; i < phnum; i++) {
-    if (progHeader[i].p_type == PT_TLS) {
+  for (i = 0; i < phnum; i++)
+  {
+    if (progHeader[i].p_type == PT_TLS)
+    {
 #if CMK_ERROR_CHECKING
       /* sanity check */
       /* align is power of 2 */
       int align = progHeader[i].p_align;
-      CmiAssert(align > 0 && ( (align & (align-1)) == 0));
+      CmiAssert(align > 0 && (align & (align-1)) == 0);
       /* total size is not less than the size of .tdata (initializer data) */
       CmiAssert(progHeader[i].p_memsz >= progHeader[i].p_filesz);
 #endif
@@ -107,126 +162,96 @@ Phdr* getTLSPhdrEntry(void) {
   }
   return NULL;
 }
-#else
-static int count_tls_sizes(struct dl_phdr_info* info, size_t size, void* data)
+
+static void CmiTLSStatsInit()
 {
-  size_t i;
-  tlsseg_t* t = (tlsseg_t*)data;
+  /* Use dynamic linking in case Charm++ shared objects are used by a binary lacking
+   * conv-static.o, such as in the case of Charm4py. */
+  void** pCmiExecutableStart = (void**)dlsym(RTLD_DEFAULT, "CmiExecutableStart");
+  if (pCmiExecutableStart != NULL)
+    CmiTLSExecutableStart = *pCmiExecutableStart;
+  else
+    CmiPrintf("Charm++> Error: \"CmiExecutableStart\" symbol not found. -tlsglobals disabled.\n");
+}
 
-  for (i = 0; i < info->dlpi_phnum; i++)
+static void populateTLSSegStats(tlsseg_t * t)
+{
+  Phdr* phdr = getTLSPhdrEntry();
+  if (phdr != NULL)
   {
-    const Phdr* hdr = &info->dlpi_phdr[i];
-    if (hdr->p_type == PT_TLS)
-    {
-      t->size += hdr->p_memsz;
-      if (t->align < hdr->p_align)
-        t->align = hdr->p_align;
-    }
+    t->align = phdr->p_align;
+    t->size = phdr->p_memsz;
+  }
+  else
+  {
+    t->size = 0;
+    t->align = 0;
   }
+}
 
-  return 0;
+#else
+
+static inline void CmiTLSStatsInit()
+{
 }
-#endif
 
-void allocNewTLSSeg(tlsseg_t* t, CthThread th) {
-#if CMK_HAS_DL_ITERATE_PHDR
+static void populateTLSSegStats(tlsseg_t * t)
+{
   t->size = 0;
-  t->align = 0;
-  dl_iterate_phdr(count_tls_sizes, t); /* count all PT_TLS sections */
+}
+
+#endif
+
+
+// ----- CmiTLS implementation -----
+
+void CmiTLSInit()
+{
+#ifdef CMK_TLS_SWITCHING_UNAVAILABLE
+  CmiAbort("TLS globals are not supported.");
 #else
-  Phdr* phdr = getTLSPhdrEntry();
-  if (phdr != NULL) {
-    t->align = phdr->p_align;
-    t->size = phdr->p_memsz;
-  } else {
-    t->size = 0;
-    t->align = 0;
+  if (CmiMyRank() == 0)
+  {
+    if (!quietModeRequested && CmiMyPe() == 0)
+    {
+      CmiPrintf("Charm++> -tlsglobals enabled for privatization of thread-local variables.\n");
+#ifdef CMK_TLS_NO_SHARED
+      CmiPrintf("Charm++> Warning: Unable to examine TLS segments of shared objects.\n");
+#endif
+    }
+
+    CmiTLSStatsInit();
   }
 #endif
+}
+
+void allocNewTLSSeg(tlsseg_t* t, CthThread th)
+{
+  populateTLSSegStats(t);
 
-  if (t->size > 0) {
+  if (t->size > 0)
+  {
     t->size = CMIALIGN(t->size, t->align);
     t->memseg = (Addr)CmiIsomallocMallocAlignForThread(th, t->align, t->size);
     memcpy((void*)t->memseg, (char *)getTLS() - t->size, t->size);
     t->memseg = (Addr)( ((char *)(t->memseg)) + t->size );
     /* printf("[%d] 2 ALIGN %d MEM %p SIZE %d\n", CmiMyPe(), t->align, t->memseg, t->size); */
-  } else {
+  }
+  else
+  {
     /* since we don't have a PT_TLS section to copy, keep whatever the system gave us */
     t->memseg = (Addr)getTLS();
   }
 }
 
-extern "C" {
-void switchTLS(tlsseg_t* , tlsseg_t* ) CMI_NOOPTIMIZE;
-void currentTLS(tlsseg_t*) CMI_NOOPTIMIZE;
-}
-
-void currentTLS(tlsseg_t* cur) {
-  cur->memseg = (Addr)getTLS();
-}
-
-void* getTLS(void) {
-  void* ptr;
-#if CMK_TLS_SWITCHING64
-  asm volatile ("movq %%fs:0x0, %0\n\t"
-                : "=r"(ptr));
-#elif CMK_TLS_SWITCHING32
-  asm volatile ("movl %%gs:0x0, %0\n\t"
-                : "=r"(ptr));
-#else
-  fprintf(stderr, "TLS globals are not supported.");
-  abort();
-#endif
-  return ptr;
-}
-
-void switchTLS(tlsseg_t* cur, tlsseg_t* next) {
+void switchTLS(tlsseg_t* cur, tlsseg_t* next)
+{
   cur->memseg = (Addr)swapTLS((void*)next->memseg);
 }
 
-void* swapTLS(void* newptr) {
-  void* oldptr;
-#if CMK_TLS_SWITCHING64
-#if 0
-  asm volatile ("movq %%fs:0x0, %0\n\t"
-                : "=r"(oldptr));
-  if (oldptr == newptr) /* same */
-    return oldptr;
-  asm volatile ("movq %0, %%fs:0x0\n\t"
-                :
-                : "r"(newptr));
-#else
-  asm volatile ("movq %%fs:0x0, %0\n\t"
-                "movq %1, %%fs:0x0\n\t"
-                : "=&r"(oldptr)
-                : "r"(newptr));
-#endif
-#elif CMK_TLS_SWITCHING32
-  asm volatile ("movl %%gs:0x0, %0\n\t"
-                "movl %1, %%gs:0x0\n\t"
-                : "=&r"(oldptr)
-                : "r"(newptr));
-#else
-  fprintf(stderr, "TLS globals are not supported.");
-  abort();
-#endif
-  return oldptr;
-}
-
-/* for calling from a debugger */
-void setTLS(void* newptr) {
-#if CMK_TLS_SWITCHING64
-  asm volatile ("movq %0, %%fs:0x0\n\t"
-                :
-                : "r"(newptr));
-#elif CMK_TLS_SWITCHING32
-  asm volatile ("movl %0, %%gs:0x0\n\t"
-                :
-                : "r"(newptr));
-#else
-  fprintf(stderr, "TLS globals are not supported.");
-  abort();
-#endif
+void currentTLS(tlsseg_t* cur)
+{
+  cur->memseg = (Addr)getTLS();
 }
 
 #endif
index 3e28827..ac57767 100644 (file)
@@ -3,7 +3,9 @@
 
 #include "conv-config.h"
 
-#if CMK_HAS_TLS_VARIABLES && CMK_HAS_ELF_H \
+#if CMK_HAS_TLS_VARIABLES
+
+#if CMK_HAS_ELF_H \
     && ((CMK_DLL_USE_DLOPEN && CMK_HAS_RTLD_DEFAULT) || CMK_HAS_DL_ITERATE_PHDR)
 
 #include <elf.h>
@@ -29,19 +31,20 @@ typedef Elf64_Ehdr Ehdr;
 typedef Elf64_Phdr Phdr;
 #endif
 
+#else
+
+typedef void * Addr;
+
+#endif
+
+#endif
+
 typedef struct tlsseg {
   Addr memseg;
   size_t size;
   size_t align;
 } tlsseg_t;
 
-
-#else
-
-typedef int  tlsseg_t;            /* place holder */
-
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif