mirror of
https://github.com/ptitSeb/box86.git
synced 2024-11-30 10:21:05 +00:00
Improved callbacks, with shared and small variant
This commit is contained in:
parent
b63ec10cf7
commit
18fa4d2134
@ -37,6 +37,7 @@ box86context_t *NewBox86Context(int argc)
|
||||
context->argv = (char**)calloc(context->argc, sizeof(char*));
|
||||
|
||||
pthread_mutex_init(&context->mutex_once, NULL);
|
||||
pthread_mutex_init(&context->mutex_once2, NULL);
|
||||
|
||||
return context;
|
||||
}
|
||||
@ -93,6 +94,7 @@ void FreeBox86Context(box86context_t** context)
|
||||
FreeCallbackList(&(*context)->callbacks);
|
||||
|
||||
pthread_mutex_destroy(&(*context)->mutex_once);
|
||||
pthread_mutex_destroy(&(*context)->mutex_once2);
|
||||
|
||||
free(*context);
|
||||
*context = NULL;
|
||||
|
@ -58,6 +58,7 @@ typedef struct box86context_s {
|
||||
callbacklist_t *callbacks; // all callbacks
|
||||
|
||||
pthread_mutex_t mutex_once;
|
||||
pthread_mutex_t mutex_once2;
|
||||
|
||||
library_t *libclib; // shortcut to libc library (if loaded, so probably yes)
|
||||
library_t *sdl1lib; // shortcut to SDL1 library (if loaded)
|
||||
|
@ -17,6 +17,7 @@ typedef struct onecallback_s {
|
||||
uintptr_t fnc;
|
||||
int nb_args;
|
||||
void* arg[10];
|
||||
int shared;
|
||||
} onecallback_t;
|
||||
|
||||
KHASH_MAP_INIT_INT(callbacks, onecallback_t*)
|
||||
@ -32,6 +33,7 @@ x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, voi
|
||||
callbacklist_t *callbacks = emu->context->callbacks;
|
||||
int stsize = 2*1024*1024; // 2MB stack (1MB is not enough for Xenonauts)
|
||||
void* stack = malloc(stsize);
|
||||
if(!stack) {printf_log(LOG_NONE, "BOX86: Error, cannot allocate 2MB Stack for callback\n");}
|
||||
x86emu_t * newemu = NewX86Emu(emu->context, fnc, (uintptr_t)stack, stsize);
|
||||
SetupX86Emu(newemu, emu->shared_global, emu->globals);
|
||||
newemu->trace_start = emu->trace_start;
|
||||
@ -50,12 +52,42 @@ x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, voi
|
||||
cb->arg[2] = arg3;
|
||||
cb->arg[3] = arg4;
|
||||
|
||||
cb->shared = 0;
|
||||
|
||||
return newemu;
|
||||
}
|
||||
|
||||
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4) __attribute__((alias("AddCallback")));
|
||||
/*{
|
||||
// doesn't work for now
|
||||
x86emu_t* AddSmallCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4)
|
||||
{
|
||||
callbacklist_t *callbacks = emu->context->callbacks;
|
||||
int stsize = 64*1024; // 64KB stack
|
||||
void* stack = malloc(stsize);
|
||||
if(!stack) {printf_log(LOG_NONE, "BOX86: Error, cannot allocate 64KB Stack for small callback\n");}
|
||||
x86emu_t * newemu = NewX86Emu(emu->context, fnc, (uintptr_t)stack, stsize);
|
||||
SetupX86Emu(newemu, emu->shared_global, emu->globals);
|
||||
newemu->trace_start = emu->trace_start;
|
||||
newemu->trace_end = emu->trace_end;
|
||||
|
||||
onecallback_t * cb;
|
||||
int ret;
|
||||
khint_t k = kh_put(callbacks, callbacks->list, (uintptr_t)newemu, &ret);
|
||||
cb = kh_value(callbacks->list, k) = (onecallback_t*)calloc(1, sizeof(onecallback_t));
|
||||
|
||||
cb->emu = newemu;
|
||||
cb->fnc = fnc;
|
||||
cb->nb_args = nb_args;
|
||||
cb->arg[0] = arg1;
|
||||
cb->arg[1] = arg2;
|
||||
cb->arg[2] = arg3;
|
||||
cb->arg[3] = arg4;
|
||||
|
||||
cb->shared = 0;
|
||||
|
||||
return newemu;
|
||||
}
|
||||
|
||||
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4) //__attribute__((alias("AddCallback")));
|
||||
{
|
||||
callbacklist_t *callbacks = emu->context->callbacks;
|
||||
x86emu_t * newemu = emu;
|
||||
|
||||
@ -71,9 +103,10 @@ x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg
|
||||
cb->arg[1] = arg2;
|
||||
cb->arg[2] = arg3;
|
||||
cb->arg[3] = arg4;
|
||||
cb->shared = 1;
|
||||
|
||||
return newemu;
|
||||
}*/
|
||||
}
|
||||
|
||||
onecallback_t* FindCallback(x86emu_t* emu)
|
||||
{
|
||||
@ -93,7 +126,8 @@ void FreeCallback(x86emu_t* emu)
|
||||
if(k==kh_end(callbacks->list))
|
||||
return;
|
||||
onecallback_t* cb = kh_value(callbacks->list, k);
|
||||
FreeX86Emu(&cb->emu);
|
||||
if(!cb->shared)
|
||||
FreeX86Emu(&cb->emu);
|
||||
free(cb);
|
||||
kh_del(callbacks, callbacks->list, k);
|
||||
}
|
||||
@ -105,6 +139,7 @@ uint32_t RunCallback(x86emu_t* emu)
|
||||
for (int i=cb->nb_args-1; i>=0; --i) // reverse order
|
||||
Push(emu, (uint32_t)cb->arg[i]);
|
||||
EmuCall(emu, cb->fnc);
|
||||
R_ESP+=(cb->nb_args*4);
|
||||
return R_EAX;
|
||||
}
|
||||
printf_log(LOG_INFO, "Warning, Callback not found?!\n");
|
||||
|
@ -10,6 +10,7 @@ callbacklist_t* NewCallbackList();
|
||||
void FreeCallbackList(callbacklist_t** callbacks);
|
||||
|
||||
x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
|
||||
x86emu_t* AddSmallCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
|
||||
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
|
||||
void FreeCallback(x86emu_t* emu);
|
||||
uint32_t RunCallback(x86emu_t* emu);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
@ -107,18 +108,36 @@ static void my_thread_once_callback()
|
||||
return;
|
||||
EmuCall(once_emu, once_fnc);
|
||||
}
|
||||
static x86emu_t *once2_emu = NULL;
|
||||
static uintptr_t once2_fnc = 0;
|
||||
static void my_thread_once2_callback()
|
||||
{
|
||||
if(!once2_emu)
|
||||
return;
|
||||
EmuCall(once2_emu, once2_fnc);
|
||||
}
|
||||
|
||||
int EXPORT my_pthread_once(x86emu_t* emu, void* once, void* cb)
|
||||
{
|
||||
pthread_mutex_lock(&emu->context->mutex_once); // what if it deadlock here?
|
||||
if(pthread_mutex_trylock(&emu->context->mutex_once)==EBUSY)
|
||||
{
|
||||
// 2nd level...
|
||||
pthread_mutex_lock(&emu->context->mutex_once2);
|
||||
once2_emu = emu;
|
||||
once2_fnc = (uintptr_t)cb;
|
||||
int ret = pthread_once(once, my_thread_once2_callback);
|
||||
once_emu = NULL;
|
||||
pthread_mutex_unlock(&emu->context->mutex_once2);
|
||||
return ret;
|
||||
} else {
|
||||
once_emu = emu;
|
||||
once_fnc = (uintptr_t)cb;
|
||||
int ret = pthread_once(once, my_thread_once_callback);
|
||||
once_emu = NULL;
|
||||
|
||||
once_emu = emu;
|
||||
once_fnc = (uintptr_t)cb;
|
||||
int ret = pthread_once(once, my_thread_once_callback);
|
||||
once_emu = NULL;
|
||||
|
||||
pthread_mutex_unlock(&emu->context->mutex_once);
|
||||
return ret;
|
||||
pthread_mutex_unlock(&emu->context->mutex_once);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT int my_pthread_key_create(x86emu_t* emu, void* key, void* dtor)
|
||||
@ -129,7 +148,7 @@ EXPORT int my_pthread_key_create(x86emu_t* emu, void* key, void* dtor)
|
||||
while (n<nb_dtor) {
|
||||
if(!dtor_emu[n] || GetCallbackAddress(dtor_emu[n])==((uintptr_t)dtor)) {
|
||||
if(!dtor_emu[n])
|
||||
dtor_emu[n] = AddCallback(emu, (uintptr_t)dtor, 1, NULL, NULL, NULL, NULL);
|
||||
dtor_emu[n] = AddSmallCallback(emu, (uintptr_t)dtor, 1, NULL, NULL, NULL, NULL);
|
||||
return pthread_key_create((pthread_key_t*)key, dtor_cb[n]);
|
||||
}
|
||||
++n;
|
||||
|
@ -381,7 +381,7 @@ static int qsort_cmp(const void* a, const void* b, void* e)
|
||||
EXPORT void my_qsort(x86emu_t* emu, void* base, size_t nmemb, size_t size, void* fnc)
|
||||
{
|
||||
// use a temporary callback
|
||||
x86emu_t *cbemu = AddCallback(emu, (uintptr_t)fnc, 3, NULL, NULL, NULL, NULL);
|
||||
x86emu_t *cbemu = AddSharedCallback(emu, (uintptr_t)fnc, 2, NULL, NULL, NULL, NULL);
|
||||
qsort_r(base, nmemb, size, qsort_cmp, cbemu);
|
||||
FreeCallback(cbemu);
|
||||
}
|
||||
@ -449,7 +449,7 @@ static int glob_errfnccallback(const char* epath, int no)
|
||||
EXPORT int32_t my_glob(x86emu_t *emu, void* pat, int32_t flags, void* errfnc, void* pblog)
|
||||
{
|
||||
if(errfnc)
|
||||
globemu = AddCallback(emu, (uintptr_t)errfnc, 2, NULL, NULL, NULL, NULL);
|
||||
globemu = AddSharedCallback(emu, (uintptr_t)errfnc, 2, NULL, NULL, NULL, NULL);
|
||||
int32_t r = glob((const char*)pat, flags, globemu?glob_errfnccallback:NULL, (glob_t*)pblog);
|
||||
if(globemu) {
|
||||
FreeCallback(globemu);
|
||||
|
Loading…
Reference in New Issue
Block a user