diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-12-18 17:18:26 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-12-18 17:18:26 +0100 |
| commit | b0b34e3a2ad0290cda6c301f08913fca536f0b6c (patch) | |
| tree | 7bc7d0cb74b8ae7decb3b2981e3464cc13268c01 /src/libtools | |
| parent | 631da8a53231fb725fa9ed4db254c60b53621024 (diff) | |
| download | box64-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.c | 57 | ||||
| -rwxr-xr-x | src/libtools/threads32.c | 73 |
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; } |