about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-03-12 21:43:20 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-03-12 21:43:20 +0100
commita08f3c4c9eca36ef2415d8428434ca4af41aa84e (patch)
tree19a473f8220c366379ad7d887a4b2488e6035d22 /src
parentc0f98bb0ec8b996d7fe35b1b311ec421587a94fd (diff)
downloadbox64-a08f3c4c9eca36ef2415d8428434ca4af41aa84e.tar.gz
box64-a08f3c4c9eca36ef2415d8428434ca4af41aa84e.zip
Tried to optimize TLS fetching
Diffstat (limited to 'src')
-rwxr-xr-xsrc/elfs/elfloader.c7
-rwxr-xr-xsrc/emu/x64tls.c23
-rwxr-xr-xsrc/include/x64tls.h3
-rwxr-xr-xsrc/wrapped/wrappedldlinux.c5
4 files changed, 20 insertions, 18 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 2082322d..05ff19e1 100755
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -1463,12 +1463,7 @@ void* GetTLSPointer(box64context_t* context, elfheader_t* h)
 {
     if(!h->tlssize)
         return NULL;
-    tlsdatasize_t* ptr;
-    if ((ptr = (tlsdatasize_t*)pthread_getspecific(context->tlskey)) == NULL) {
-        ptr = (tlsdatasize_t*)fillTLSData(context);
-    }
-    if(ptr->tlssize != context->tlssize)
-        ptr = (tlsdatasize_t*)resizeTLSData(context, ptr);
+    tlsdatasize_t* ptr = getTLSData(context);
     return ptr->data+h->tlsbase;
 }
 
diff --git a/src/emu/x64tls.c b/src/emu/x64tls.c
index a059ecfb..8ce3affe 100755
--- a/src/emu/x64tls.c
+++ b/src/emu/x64tls.c
@@ -227,7 +227,7 @@ static tlsdatasize_t* setupTLSData(box64context_t* context)
     return data;
 }
 
-void* fillTLSData(box64context_t *context)
+static void* fillTLSData(box64context_t *context)
 {
         mutex_lock(&context->mutex_tls);
         tlsdatasize_t *data = setupTLSData(context);
@@ -235,7 +235,7 @@ void* fillTLSData(box64context_t *context)
         return data;
 }
 
-void* resizeTLSData(box64context_t *context, void* oldptr)
+static void* resizeTLSData(box64context_t *context, void* oldptr)
 {
         mutex_lock(&context->mutex_tls);
         tlsdatasize_t* oldata = (tlsdatasize_t*)oldptr;
@@ -272,14 +272,21 @@ void* resizeTLSData(box64context_t *context, void* oldptr)
         }
 }
 
+tlsdatasize_t* getTLSData(box64context_t *context)
+{
+    static __thread tlsdatasize_t* ptr = NULL;
+    if(!ptr)
+        if ((ptr = (tlsdatasize_t*)pthread_getspecific(context->tlskey)) == NULL) {
+            ptr = (tlsdatasize_t*)fillTLSData(context);
+        }
+    if(ptr->tlssize != context->tlssize)
+        ptr = (tlsdatasize_t*)resizeTLSData(context, ptr);
+    return ptr;
+}
+
 static void* GetSeg33Base()
 {
-    tlsdatasize_t* ptr;
-    if ((ptr = (tlsdatasize_t*)pthread_getspecific(my_context->tlskey)) == NULL) {
-        ptr = (tlsdatasize_t*)fillTLSData(my_context);
-    }
-    if(ptr->tlssize != my_context->tlssize)
-        ptr = (tlsdatasize_t*)resizeTLSData(my_context, ptr);
+    tlsdatasize_t* ptr = getTLSData(my_context);
     return ptr->data;
 }
 
diff --git a/src/include/x64tls.h b/src/include/x64tls.h
index f26827c2..9ca97efb 100755
--- a/src/include/x64tls.h
+++ b/src/include/x64tls.h
@@ -6,8 +6,7 @@ typedef struct thread_area_s thread_area_t;
 uint32_t my_set_thread_area(thread_area_t* td);
 uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size);
 
-void* fillTLSData(box64context_t *context);
-void* resizeTLSData(box64context_t *context, void* oldptr);
+tlsdatasize_t* getTLSData(box64context_t *context);
 void* GetSegmentBase(uint32_t desc);
 
 int my_arch_prctl(x64emu_t *emu, int code, void* addr);
diff --git a/src/wrapped/wrappedldlinux.c b/src/wrapped/wrappedldlinux.c
index d88c10c2..b5dc0da6 100755
--- a/src/wrapped/wrappedldlinux.c
+++ b/src/wrapped/wrappedldlinux.c
@@ -14,6 +14,7 @@
 #include "emu/x64emu_private.h"
 #include "elfloader.h"
 #include "box64context.h"
+#include "x64tls.h"
 
 typedef struct my_tls_s {
     unsigned long int   i;
@@ -23,8 +24,8 @@ typedef struct my_tls_s {
 EXPORT void* my___tls_get_addr(void* p)
 {
     my_tls_t *t = (my_tls_t*)p;
-    void* ret = (void*)((char*)GetTLSPointer(my_context, my_context->elfs[t->i])+t->o);
-    return ret;
+    tlsdatasize_t* ptr = getTLSData(my_context);
+    return ptr->data+GetTLSBase(my_context->elfs[t->i])+t->o;
 }
 
 // don't try to load the actual ld-linux (because name is variable), just use box64 itself, as it's linked to ld-linux