about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-10-10 15:57:28 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-10-10 15:57:28 +0200
commit9e01876747c5947a88b87a3e64c16e0e7cb170eb (patch)
treedf00417651c6f6682face526b6a04c5151a398c4 /src
parentee909b8c08fa8b893d7103fbd1071b7a52d30402 (diff)
downloadbox64-9e01876747c5947a88b87a3e64c16e0e7cb170eb.tar.gz
box64-9e01876747c5947a88b87a3e64c16e0e7cb170eb.zip
[BOX32] Improved pthread_mutex handling
Diffstat (limited to 'src')
-rwxr-xr-xsrc/libtools/threads32.c95
1 files changed, 59 insertions, 36 deletions
diff --git a/src/libtools/threads32.c b/src/libtools/threads32.c
index 093e4749..0ba81b77 100755
--- a/src/libtools/threads32.c
+++ b/src/libtools/threads32.c
@@ -817,43 +817,57 @@ EXPORT int my32_pthread_kill_old(x64emu_t* emu, void* thread, int sig)
 // TODO: find a better way for mutex. It should be possible to use the actual mutex most of the time, especially for simple ones
 // Having the mutex table behind a mutex is far from ideal!
 
-KHASH_MAP_INIT_INT(mutex, pthread_mutex_t*)
-static kh_mutex_t* unaligned_mutex = NULL;
-static pthread_rwlock_t m_lock = {0};
+typedef struct fake_pthread_mutext_s {
+	int __lock;
+	unsigned int __count;
+  	int __owner;
+	int i386__kind;
+	int __kind;
+	ptr_t real_mutex;
+} fakse_phtread_mutex_t;
+#define KIND_SIGN	0xbad000
+pthread_mutex_t* createNewMutex()
+{
+	pthread_mutex_t* ret = (pthread_mutex_t*)box_calloc(1, sizeof(pthread_mutex_t));
+	return ret;
+}
+// init = 0: just get the mutex
+// init = 1: get the mutex and init it with optione attr (attr will disallow native mutex)
 pthread_mutex_t* getAlignedMutex(pthread_mutex_t* m)
 {
-	pthread_mutex_t* ret = NULL;
-	pthread_rwlock_rdlock(&m_lock);
-	khint_t k = kh_get(mutex, unaligned_mutex, (uintptr_t)m);
-	if(k!=kh_end(unaligned_mutex)) {
-		ret = kh_value(unaligned_mutex, k);
-	} else {
-		int r;
-		pthread_rwlock_unlock(&m_lock);
-		pthread_rwlock_wrlock(&m_lock);
-		k = kh_put(mutex, unaligned_mutex, (uintptr_t)m, &r);
-		ret = kh_value(unaligned_mutex, k) = (pthread_mutex_t*)box_calloc(1, sizeof(pthread_mutex_t));
-		memcpy(ret, m, 24);
+	fakse_phtread_mutex_t* fake = (fakse_phtread_mutex_t*)m;
+	if(fake->__kind==0) {
+		return m;	// type 0 can fit...
 	}
-	pthread_rwlock_unlock(&m_lock);
-	return ret;
+	if(fake->__kind==KIND_SIGN)
+		return from_ptrv(fake->real_mutex);
+	// this should not appens!
+	printf_log(LOG_NONE, "BOX32: Warning, fallback on alligned mutex %p\n", m);
+	fake->real_mutex = to_ptrv(createNewMutex());
+	return from_ptrv(fake->real_mutex);
 }
 EXPORT int my32_pthread_mutex_destroy(pthread_mutex_t *m)
 {
-	pthread_rwlock_wrlock(&m_lock);
-	khint_t k = kh_get(mutex, unaligned_mutex, (uintptr_t)m);
-	if(k!=kh_end(unaligned_mutex)) {
-		pthread_mutex_t *n = kh_value(unaligned_mutex, k);
-		kh_del(mutex, unaligned_mutex, k);
-		pthread_rwlock_unlock(&m_lock);
-		int ret = pthread_mutex_destroy(n);
-		box_free(n);
+	fakse_phtread_mutex_t* fake = (fakse_phtread_mutex_t*)m;
+	if(fake->__kind==0) {
+		//TODO: check if that save/restore is actually needed
+		uint8_t saved[sizeof(pthread_mutex_t)];
+		memcpy(saved, fake+1, sizeof(pthread_mutex_t)-24);
+		int ret = pthread_mutex_destroy(m);
+		memcpy(fake+1, saved, sizeof(pthread_mutex_t)-24);
 		return ret;
 	}
-	pthread_rwlock_unlock(&m_lock);
-	return pthread_mutex_destroy(m);
+	if(fake->__kind!=KIND_SIGN) {
+		printf_log(LOG_NONE, "BOX32: Warning, fallback on alligned mutex %p\n", m);
+		errno = EINVAL;
+		return -1;
+	}
+	pthread_mutex_t *n = from_ptrv(fake->real_mutex);
+	int ret = pthread_mutex_destroy(n);
+	box_free(n);
+	fake->__kind = fake->i386__kind = -1;
+	return ret;
 }
-#define getAlignedMutexWithInit(A, B)	getAlignedMutex(A)
 
 EXPORT int my32_pthread_mutexattr_init(x64emu_t* emu, pthread_mutexattr_t* att)
 {
@@ -868,7 +882,23 @@ EXPORT int my32___pthread_mutex_destroy(pthread_mutex_t *m) __attribute__((alias
 
 EXPORT int my32_pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *att)
 {
-	return pthread_mutex_init(getAlignedMutexWithInit(m, 0), att);
+	fakse_phtread_mutex_t* fake = (fakse_phtread_mutex_t*)m;
+	if(fake->__kind==0 && !att) {
+		fake->__lock = 0;
+		fake->__count = 0;
+		fake->i386__kind = 0;
+		fake->__owner = 0;
+		return 0;
+	}
+	if(fake->__kind==KIND_SIGN)
+		return pthread_mutex_init(from_ptrv(fake->real_mutex), att);
+	fake->__lock = 0;
+	fake->__count = 0;
+	fake->__kind = KIND_SIGN;
+	fake->real_mutex = to_ptrv(createNewMutex());
+	int ret = pthread_mutex_init(from_ptrv(fake->real_mutex), att);
+	fake->i386__kind = ((struct __pthread_mutex_s*)from_ptrv(fake->real_mutex))->__kind;
+	return ret;
 }
 EXPORT int my32___pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *att) __attribute__((alias("my32_pthread_mutex_init")));
 
@@ -918,7 +948,6 @@ void init_pthread_helper_32()
 	}
 
 	mapcond = kh_init(mapcond);
-	unaligned_mutex = kh_init(mutex);
 }
 
 void clean_current_emuthread_32()
@@ -943,12 +972,6 @@ void fini_pthread_helper_32(box64context_t* context)
 	);
 	kh_destroy(mapcond, mapcond);
 	mapcond = NULL;
-	pthread_mutex_t *m;
-	kh_foreach_value(unaligned_mutex, m, 
-		pthread_mutex_destroy(m);
-		box_free(m);
-	);
-	kh_destroy(mutex, unaligned_mutex);
 
 	clean_current_emuthread_32();
 }