diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-18 15:07:27 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-18 15:07:27 +0100 |
| commit | 0965273711cae3107e98a8c5f5dd33b054526c5c (patch) | |
| tree | ad6e7ac9fcea39f1afe0c2f704a6023d79989043 /src | |
| parent | dd9e8ae8ffe211ffd1e69c637ad9b425a6e8e907 (diff) | |
| download | box64-0965273711cae3107e98a8c5f5dd33b054526c5c.tar.gz box64-0965273711cae3107e98a8c5f5dd33b054526c5c.zip | |
Improvments to bridge handling to avoid deadlock
Diffstat (limited to 'src')
| -rwxr-xr-x | src/tools/bridge.c | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/src/tools/bridge.c b/src/tools/bridge.c index a89f32ca..dd97dd45 100755 --- a/src/tools/bridge.c +++ b/src/tools/bridge.c @@ -37,7 +37,9 @@ typedef struct bridge_s { brick_t* NewBrick() { brick_t* ret = (brick_t*)calloc(1, sizeof(brick_t)); - posix_memalign((void**)&ret->b, box64_pagesize, NBRICK*sizeof(onebridge_t)); + if(posix_memalign((void**)&ret->b, box64_pagesize, NBRICK*sizeof(onebridge_t))) { + printf_log(LOG_NONE, "Warning, cannot allocate 0x%lx aligned bytes for bridge, will probably crash later\n", NBRICK*sizeof(onebridge_t)); + } return ret; } @@ -76,43 +78,53 @@ void addBridgeName(void* addr, const char* name); uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name) { - pthread_mutex_lock(&bridge->mutex); - brick_t *b = bridge->last; - if(b->sz == NBRICK) { - b->next = NewBrick(); - b = b->next; - bridge->last = b; - } + brick_t *b = NULL; + int sz = -1; #ifdef DYNAREC int prot = 0; - if(box64_dynarec) { - prot=(getProtection((uintptr_t)b->b)&PROT_DYNAREC)?1:0; - if(prot) - unprotectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t)); - addDBFromAddressRange((uintptr_t)&b->b[b->sz].CC, sizeof(onebridge_t)); - } - #endif - b->b[b->sz].CC = 0xCC; - b->b[b->sz].S = 'S'; b->b[b->sz].C='C'; - b->b[b->sz].w = w; - b->b[b->sz].f = (uintptr_t)fnc; - b->b[b->sz].C3 = N?0xC2:0xC3; - b->b[b->sz].N = N; - #ifdef DYNAREC - if(box64_dynarec && prot) - protectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t)); + do { + #endif + pthread_mutex_lock(&bridge->mutex); + b = bridge->last; + if(b->sz == NBRICK) { + b->next = NewBrick(); + b = b->next; + bridge->last = b; + } + #ifdef DYNAREC + sz = b->sz; + pthread_mutex_unlock(&bridge->mutex); + if(box64_dynarec) { + prot=(getProtection((uintptr_t)b->b)&PROT_DYNAREC)?1:0; + if(prot) + unprotectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t)); + addDBFromAddressRange((uintptr_t)&b->b[b->sz].CC, sizeof(onebridge_t)); + } + } while(sz!=b->sz); // this while loop if someone took the slot when the bridge mutex was unlocked doing memory protection managment + pthread_mutex_lock(&bridge->mutex); #endif + b->sz++; + b->b[sz].CC = 0xCC; + b->b[sz].S = 'S'; b->b[sz].C='C'; + b->b[sz].w = w; + b->b[sz].f = (uintptr_t)fnc; + b->b[sz].C3 = N?0xC2:0xC3; + b->b[sz].N = N; // add bridge to map, for fast recovery int ret; khint_t k = kh_put(bridgemap, bridge->bridgemap, (uintptr_t)fnc, &ret); - kh_value(bridge->bridgemap, k) = (uintptr_t)&b->b[b->sz].CC; + kh_value(bridge->bridgemap, k) = (uintptr_t)&b->b[sz].CC; pthread_mutex_unlock(&bridge->mutex); + #ifdef DYNAREC + if(box64_dynarec && prot) + protectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t)); + #endif #ifdef HAVE_TRACE if(name) addBridgeName(fnc, name); #endif - return (uintptr_t)&b->b[b->sz++].CC; + return (uintptr_t)&b->b[sz].CC; } uintptr_t CheckBridged(bridge_t* bridge, void* fnc) |