about summary refs log tree commit diff stats
path: root/src/box64context.c
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-04-11 11:05:36 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-04-11 11:05:36 +0200
commit3b9feeed120af45a2dc346592b328eb0b2e14911 (patch)
tree805803a23c6e2e91fc002b8b8f1b2d9f73a1e298 /src/box64context.c
parent6d3ca2df80b6df2e9aabb73210f9c09fd0df97a1 (diff)
downloadbox64-3b9feeed120af45a2dc346592b328eb0b2e14911.tar.gz
box64-3b9feeed120af45a2dc346592b328eb0b2e14911.zip
Improvement in internal mutex handling on signal, and [DYNAREC] multitasking changes to the JmpTable
Diffstat (limited to 'src/box64context.c')
-rwxr-xr-xsrc/box64context.c84
1 files changed, 74 insertions, 10 deletions
diff --git a/src/box64context.c b/src/box64context.c
index 1fd00750..182a079f 100755
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -68,6 +68,77 @@ void free_tlsdatasize(void* p)
 
 void x64Syscall(x64emu_t *emu);
 
+int unlockMutex()
+{
+    int ret = unlockCustommemMutex();
+    int i;
+    #define GO(A, B)                    \
+        i = checkMutex(&A);             \
+        if(i) {                         \
+            pthread_mutex_unlock(&A);   \
+            ret|=(1<<B);                \
+        }
+
+    GO(my_context->mutex_once, 5)
+    GO(my_context->mutex_once2, 6)
+    GO(my_context->mutex_trace, 7)
+    #ifdef DYNAREC
+    GO(my_context->mutex_dyndump, 8)
+    #else
+    GO(my_context->mutex_lock, 8)
+    #endif
+    GO(my_context->mutex_tls, 9)
+    GO(my_context->mutex_thread, 10)
+    #undef GO
+
+    return ret;
+}
+
+void relockMutex(int locks)
+{
+    relockCustommemMutex(locks);
+    #define GO(A, B)                    \
+        if(locks&(1<<B))                \
+            pthread_mutex_lock(&A);     \
+
+    GO(my_context->mutex_once, 5)
+    GO(my_context->mutex_once2, 6)
+    GO(my_context->mutex_trace, 7)
+    #ifdef DYNAREC
+    GO(my_context->mutex_dyndump, 8)
+    #else
+    GO(my_context->mutex_lock, 8)
+    #endif
+    GO(my_context->mutex_tls, 9)
+    GO(my_context->mutex_thread, 10)
+    #undef GO
+}
+
+static void init_mutexes(box64context_t* context)
+{
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+    pthread_mutex_init(&context->mutex_once, &attr);
+    pthread_mutex_init(&context->mutex_once2, &attr);
+    pthread_mutex_init(&context->mutex_trace, &attr);
+#ifndef DYNAREC
+    pthread_mutex_init(&context->mutex_lock, &attr);
+#else
+    pthread_mutex_init(&context->mutex_dyndump, &attr);
+#endif
+    pthread_mutex_init(&context->mutex_tls, &attr);
+    pthread_mutex_init(&context->mutex_thread, &attr);
+
+    pthread_mutexattr_destroy(&attr);
+}
+
+static void atfork_child_box64context(void)
+{
+    // (re)init mutex if it was lock before the fork
+    init_mutexes(my_context);
+}
+
 EXPORTDYN
 box64context_t *NewBox64Context(int argc)
 {
@@ -96,16 +167,9 @@ box64context_t *NewBox64Context(int argc)
     context->argc = argc;
     context->argv = (char**)calloc(context->argc+1, sizeof(char*));
 
-    pthread_mutex_init(&context->mutex_once, NULL);
-    pthread_mutex_init(&context->mutex_once2, NULL);
-    pthread_mutex_init(&context->mutex_trace, NULL);
-#ifndef DYNAREC
-    pthread_mutex_init(&context->mutex_lock, NULL);
-#else
-    pthread_mutex_init(&context->mutex_dyndump, NULL);
-#endif
-    pthread_mutex_init(&context->mutex_tls, NULL);
-    pthread_mutex_init(&context->mutex_thread, NULL);
+    init_mutexes(context);
+    pthread_atfork(NULL, NULL, atfork_child_box64context);
+
     pthread_key_create(&context->tlskey, free_tlsdatasize);