about summary refs log tree commit diff stats
path: root/src/libtools
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-12-18 17:18:26 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-12-18 17:18:26 +0100
commitb0b34e3a2ad0290cda6c301f08913fca536f0b6c (patch)
tree7bc7d0cb74b8ae7decb3b2981e3464cc13268c01 /src/libtools
parent631da8a53231fb725fa9ed4db254c60b53621024 (diff)
downloadbox64-b0b34e3a2ad0290cda6c301f08913fca536f0b6c.tar.gz
box64-b0b34e3a2ad0290cda6c301f08913fca536f0b6c.zip
Improved handling of stack size and addresses attribute for threads ([BOX32] too)
Diffstat (limited to 'src/libtools')
-rw-r--r--src/libtools/threads.c57
-rwxr-xr-xsrc/libtools/threads32.c73
2 files changed, 80 insertions, 50 deletions
diff --git a/src/libtools/threads.c b/src/libtools/threads.c
index a05b81e6..e14f71db 100644
--- a/src/libtools/threads.c
+++ b/src/libtools/threads.c
@@ -81,8 +81,10 @@ void CleanStackSize(box64context_t* context)
 	mutex_unlock(&context->mutex_thread);
 }
 
-void FreeStackSize(kh_threadstack_t* map, uintptr_t attr)
+void FreeStackSize(uintptr_t attr)
 {
+	kh_threadstack_t* map = my_context->stacksizes;
+	if(!map) return;
 	mutex_lock(&my_context->mutex_thread);
 	khint_t k = kh_get(threadstack, map, attr);
 	if(k!=kh_end(map)) {
@@ -92,26 +94,30 @@ void FreeStackSize(kh_threadstack_t* map, uintptr_t attr)
 	mutex_unlock(&my_context->mutex_thread);
 }
 
-void AddStackSize(kh_threadstack_t* map, uintptr_t attr, void* stack, size_t stacksize)
+void AddStackSize(uintptr_t attr, void* stack, size_t stacksize)
 {
+	if(!my_context->stacksizes)
+		my_context->stacksizes = kh_init(threadstack);
+	kh_threadstack_t* map = my_context->stacksizes;
 	khint_t k;
 	int ret;
 	mutex_lock(&my_context->mutex_thread);
 	k = kh_put(threadstack, map, attr, &ret);
-	threadstack_t* ts = kh_value(map, k) = (threadstack_t*)box_calloc(1, sizeof(threadstack_t));
+	if(ret) kh_value(map, k) = (threadstack_t*)box_calloc(1, sizeof(threadstack_t));
+	threadstack_t* ts = kh_value(map, k);
 	ts->stack = stack;
 	ts->stacksize = stacksize;
 	mutex_unlock(&my_context->mutex_thread);
 }
 
 // return stack from attr (or from current emu if attr is not found..., wich is wrong but approximate enough?)
-int GetStackSize(x64emu_t* emu, uintptr_t attr, void** stack, size_t* stacksize)
+int GetStackSize(uintptr_t attr, void** stack, size_t* stacksize)
 {
-	if(emu->context->stacksizes && attr) {
+	if(my_context->stacksizes && attr) {
 		mutex_lock(&my_context->mutex_thread);
-		khint_t k = kh_get(threadstack, emu->context->stacksizes, attr);
-		if(k!=kh_end(emu->context->stacksizes)) {
-			threadstack_t* ts = kh_value(emu->context->stacksizes, k);
+		khint_t k = kh_get(threadstack, my_context->stacksizes, attr);
+		if(k!=kh_end(my_context->stacksizes)) {
+			threadstack_t* ts = kh_value(my_context->stacksizes, k);
 			*stack = ts->stack;
 			*stacksize = ts->stacksize;
 			mutex_unlock(&my_context->mutex_thread);
@@ -119,9 +125,6 @@ int GetStackSize(x64emu_t* emu, uintptr_t attr, void** stack, size_t* stacksize)
 		}
 		mutex_unlock(&my_context->mutex_thread);
 	}
-	// should a Warning be emitted?
-	*stack = emu->init_stack;
-	*stacksize = emu->size_stack;
 	return 0;
 }
 
@@ -274,7 +277,7 @@ static void* pthread_routine(void* p)
 EXPORT int my_pthread_attr_destroy(x64emu_t* emu, void* attr)
 {
 	if(emu->context->stacksizes)
-		FreeStackSize(emu->context->stacksizes, (uintptr_t)attr);
+		FreeStackSize((uintptr_t)attr);
 	PTHREAD_ATTR_ALIGN(attr);
 	int ret = pthread_attr_destroy(PTHREAD_ATTR(attr));
 	// no unaligned, it's destroyed
@@ -285,7 +288,7 @@ EXPORT int my_pthread_attr_getstack(x64emu_t* emu, void* attr, void** stackaddr,
 {
 	PTHREAD_ATTR_ALIGN(attr);
 	int ret = 0;
-	if(!GetStackSize(emu, (uintptr_t)attr, stackaddr, stacksize))
+	if(!GetStackSize((uintptr_t)attr, stackaddr, stacksize))
 		ret = pthread_attr_getstack(PTHREAD_ATTR(attr), stackaddr, stacksize);
 //printf_log(LOG_INFO, "pthread_attr_getstack gives (%d) %p 0x%zx\n", ret, *stackaddr, *stacksize);
 	return ret;
@@ -293,10 +296,7 @@ EXPORT int my_pthread_attr_getstack(x64emu_t* emu, void* attr, void** stackaddr,
 
 EXPORT int my_pthread_attr_setstack(x64emu_t* emu, void* attr, void* stackaddr, size_t stacksize)
 {
-	if(!my_context->stacksizes) {
-		my_context->stacksizes = kh_init(threadstack);
-	}
-	AddStackSize(my_context->stacksizes, (uintptr_t)attr, stackaddr, stacksize);
+	AddStackSize((uintptr_t)attr, stackaddr, stacksize);
 	//Don't call actual setstack...
 	//return pthread_attr_setstack(attr, stackaddr, stacksize);
 	PTHREAD_ATTR_ALIGN(attr);
@@ -362,7 +362,7 @@ EXPORT int my_pthread_attr_getstackaddr(x64emu_t* emu, pthread_attr_t* attr, voi
 	size_t size;
 	PTHREAD_ATTR_ALIGN(attr);
 	int ret = 0;
-	if(!GetStackSize(emu, (uintptr_t)attr, addr, &size ))
+	if(!GetStackSize((uintptr_t)attr, addr, &size ))
 		ret = pthread_attr_getstack(PTHREAD_ATTR(attr), addr, &size);
 //printf_log(LOG_INFO, "pthread_attr_getstackaddr gives %p\n", *addr);
 	return ret;
@@ -373,7 +373,7 @@ EXPORT int my_pthread_attr_getstacksize(x64emu_t* emu, pthread_attr_t* attr, siz
 	void* addr;
 	PTHREAD_ATTR_ALIGN(attr);
 	int ret = 0;
-	if(!GetStackSize(emu, (uintptr_t)attr, &addr, size ))
+	if(!GetStackSize((uintptr_t)attr, &addr, size ))
 		ret = pthread_attr_getstack(PTHREAD_ATTR(attr), &addr, size);
 	if(!*size)
 		*size = 2*1024*1024;
@@ -455,11 +455,10 @@ EXPORT int my_pthread_attr_setscope(x64emu_t* emu, pthread_attr_t* attr, int sco
 EXPORT int my_pthread_attr_setstackaddr(x64emu_t* emu, pthread_attr_t* attr, void* addr)
 {
 	size_t size = 2*1024*1024;
-	my_pthread_attr_getstacksize(emu, attr, &size);
-	PTHREAD_ATTR_ALIGN(attr);
-	int ret = pthread_attr_setstack(PTHREAD_ATTR(attr), addr, size);
-	PTHREAD_ATTR_UNALIGN(attr);
-	return ret;
+	void* pp = NULL;
+	GetStackSize((uintptr_t)attr, &pp, &size);
+	AddStackSize((uintptr_t)attr, addr, size);
+	return 0;
 	//return pthread_attr_setstackaddr(getAlignedAttr(attr), addr);
 }
 #ifndef ANDROID
@@ -484,7 +483,7 @@ EXPORT int my_pthread_getattr_np(x64emu_t* emu, pthread_t thread_id, pthread_att
 			pthread_attr_destroy(&attr);
 			// should stack be adjusted?
 		}
-		AddStackSize(emu->context->stacksizes, (uintptr_t)attr, stack, sz);
+		AddStackSize((uintptr_t)attr, stack, sz);
 	}
 	return ret;
 }
@@ -521,7 +520,7 @@ EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_rou
 		if(pthread_attr_getstacksize(PTHREAD_ATTR(attr), &stsize)==0)
 			stacksize = stsize;
 	}
-	if(GetStackSize(emu, (uintptr_t)attr, &attr_stack, &attr_stacksize))
+	if(GetStackSize((uintptr_t)attr, &attr_stack, &attr_stacksize))
 	{
 		stack = attr_stack;
 		stacksize = attr_stacksize;
@@ -662,10 +661,10 @@ static void* findcleanup_routineFct(void* fct)
 
 // key_dtor
 #define GO(A)   \
-static uintptr_t my_key_dtor_fct_##A = 0;  \
-static void my_key_dtor_##A(void* a)    			\
+static uintptr_t my_key_dtor_fct_##A = 0;  		\
+static void my_key_dtor_##A(void* a)    		\
 {                                       		\
-    RunFunction(my_key_dtor_fct_##A, 1, a);\
+    RunFunction(my_key_dtor_fct_##A, 1, a);		\
 }
 SUPER()
 #undef GO
diff --git a/src/libtools/threads32.c b/src/libtools/threads32.c
index cab37ee2..2378b3a6 100755
--- a/src/libtools/threads32.c
+++ b/src/libtools/threads32.c
@@ -94,9 +94,9 @@ KHASH_MAP_INIT_INT(cancelthread, __pthread_unwind_buf_t*)
 #endif
 
 void CleanStackSize(box64context_t* context);
-void FreeStackSize(kh_threadstack_t* map, uintptr_t attr);
-void AddStackSize(kh_threadstack_t* map, uintptr_t attr, void* stack, size_t stacksize);
-int GetStackSize(x64emu_t* emu, uintptr_t attr, void** stack, size_t* stacksize);
+void FreeStackSize(uintptr_t attr);
+void AddStackSize(uintptr_t attr, void* stack, size_t stacksize);
+int GetStackSize(uintptr_t attr, void** stack, size_t* stacksize);
 
 void my32_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val);
 
@@ -153,8 +153,8 @@ static void* pthread_routine(void* p)
 
 EXPORT int my32_pthread_attr_destroy(x64emu_t* emu, void* attr)
 {
-	if(emu->context->stacksizes)
-		FreeStackSize(emu->context->stacksizes, (uintptr_t)attr);
+	if(my_context->stacksizes)
+		FreeStackSize((uintptr_t)attr);
 	int ret = pthread_attr_destroy(get_attr(attr));
 	del_attr(attr);
 	return ret;
@@ -164,16 +164,13 @@ EXPORT int my32_pthread_attr_getstack(x64emu_t* emu, void* attr, void** stackadd
 {
 	int ret = pthread_attr_getstack(get_attr(attr), stackaddr, stacksize);
 	if (ret==0)
-		GetStackSize(emu, (uintptr_t)attr, stackaddr, stacksize);
+		GetStackSize((uintptr_t)attr, stackaddr, stacksize);
 	return ret;
 }
 
 EXPORT int my32_pthread_attr_setstack(x64emu_t* emu, void* attr, void* stackaddr, size_t stacksize)
 {
-	if(!emu->context->stacksizes) {
-		emu->context->stacksizes = kh_init(threadstack);
-	}
-	AddStackSize(emu->context->stacksizes, (uintptr_t)attr, stackaddr, stacksize);
+	AddStackSize((uintptr_t)attr, stackaddr, stacksize);
 	//Don't call actual setstack...
 	//return pthread_attr_setstack(attr, stackaddr, stacksize);
 	return pthread_attr_setstacksize(get_attr(attr), stacksize);
@@ -185,7 +182,7 @@ EXPORT int my32_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_r
 	void* attr_stack;
 	size_t attr_stacksize;
 	int own;
-	void* stack;
+	void* stack = NULL;
 
 	if(attr) {
 		size_t stsize;
@@ -194,14 +191,19 @@ EXPORT int my32_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_r
 		if(stacksize<512*1024)	// emu and all needs some stack space, don't go too low
 			pthread_attr_setstacksize(get_attr(attr), 512*1024);
 	}
-	if(GetStackSize(emu, (uintptr_t)attr, &attr_stack, &attr_stacksize))
+	if(GetStackSize((uintptr_t)attr, &attr_stack, &attr_stacksize))
 	{
 		stack = attr_stack;
 		stacksize = attr_stacksize;
 		own = 0;
-	} else {
+		if((uintptr_t)stack>=0x100000000LL) {
+			printf_log(LOG_INFO, "Address of Stack for thread too high (%p), allocationg a new one\n", stack);
+			stack = NULL;
+		}
+	}
+	if(!stack) {
 		//stack = malloc(stacksize);
-		stack = mmap64(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN|MAP_32BIT, -1, 0);
+		stack = mmap64(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_32BIT, -1, 0);
 		own = 1;
 	}
 
@@ -224,7 +226,6 @@ EXPORT int my32_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_r
 	#ifdef DYNAREC
 	if(box64_dynarec) {
 		// pre-creation of the JIT code for the entry point of the thread
-		dynablock_t *current = NULL;
 		DBGetBlock(emu, (uintptr_t)start_routine, 1, 1);
 	}
 	#endif
@@ -237,7 +238,8 @@ EXPORT int my32_pthread_detach(x64emu_t* emu, pthread_t p)
 {
 	if(pthread_equal(p ,pthread_self())) {
 		emuthread_t *et = (emuthread_t*)thread_get_et();
-		et->join = 0;
+		if(et)
+			et->join = 0;
 	}
 	return pthread_detach(p);
 }
@@ -646,7 +648,26 @@ EXPORT int my32_pthread_attr_init(x64emu_t* emu, void* attr)
 
 EXPORT int my32_pthread_getattr_np(x64emu_t* emu, uintptr_t th, void* attr)
 {
-	return pthread_getattr_np(th, get_attr(attr));
+	(void)emu;
+	int ret = pthread_getattr_np(th, get_attr(attr));
+	if(!ret && th==pthread_self()) {
+		if(!emu->context->stacksizes) {
+			emu->context->stacksizes = kh_init(threadstack);
+		}
+		void* stack = emu->init_stack;
+		size_t sz = emu->size_stack;
+//printf_log(LOG_INFO, "pthread_getattr_np called for self, stack=%p, sz=%lx\n", stack, sz);
+		if (!sz) {
+			// get default stack size
+			pthread_attr_t attr;
+			pthread_getattr_default_np(&attr);
+			pthread_attr_getstacksize(&attr, &sz);
+			pthread_attr_destroy(&attr);
+			// should stack be adjusted?
+		}
+		AddStackSize((uintptr_t)attr, stack, sz);
+	}
+	return ret;
 }
 
 EXPORT int my32_pthread_attr_getdetachstate(x64emu_t* emu, void* attr, void* p)
@@ -723,11 +744,21 @@ EXPORT int my32_pthread_attr_setstackaddr(x64emu_t* emu, void* attr, void* p)
 {
 	size_t size = 2*1024*1024;
 	void* pp;
-	pthread_attr_getstack(get_attr(attr), &pp, &size);
-	return pthread_attr_setstack(get_attr(attr), p, size);
+	GetStackSize((uintptr_t)attr, &pp, &size);
+	AddStackSize((uintptr_t)attr, p, size);
+
+	return 0;
 }
 EXPORT int my32_pthread_attr_setstacksize(x64emu_t* emu, void* attr, size_t p)
 {
+	if(p<0xc000 || (p&4095)) {
+		errno = EINVAL;
+		return -1;
+	}
+	size_t size;
+	void* pp = NULL;
+	GetStackSize((uintptr_t)attr, &pp, &size);
+	AddStackSize((uintptr_t)attr, pp, p);
 	// PTHREAD_STACK_MIN on x86 might be lower than the current platform...
 	if(p>=0xc000 && p<PTHREAD_STACK_MIN && !(p&4095))
 		p = PTHREAD_STACK_MIN;
@@ -835,7 +866,7 @@ EXPORT int my32_pthread_kill_old(x64emu_t* emu, void* thread, int sig)
 
 pthread_mutex_t* createNewMutex()
 {
-	pthread_mutex_t* ret = (pthread_mutex_t*)box_calloc(1, sizeof(pthread_mutex_t));
+	pthread_mutex_t* ret = (pthread_mutex_t*)box32_calloc(1, sizeof(pthread_mutex_t));
 	return ret;
 }
 // init = 0: just get the mutex
@@ -892,7 +923,7 @@ EXPORT int my32_pthread_mutex_destroy(pthread_mutex_t *m)
 	}
 	pthread_mutex_t *n = from_ptrv(fake->real_mutex);
 	int ret = pthread_mutex_destroy(n);
-	box_free(n);
+	box32_free(n);
 	fake->__kind = fake->i386__kind = -1;
 	return ret;
 }