bool rp_kcache_tracker::try_reserve(node* n) { bool need_unreserve = false; vvec::iterator I(n->src.begin()), E(n->src.end()); for (; I != E; ++I) { value *v = *I; if (v->is_kcache()) { if (!try_reserve(v->select)) break; else need_unreserve = true; } } if (I == E) return true; if (need_unreserve && I != n->src.begin()) { do { --I; value *v =*I; if (v->is_kcache()) unreserve(v->select); } while (I != n->src.begin()); } return false; }
void *uae_vm_reserve(uae_u32 size, int flags) { void *address = NULL; #ifdef _WIN32 address = try_reserve(0x80000000, size, flags); if (address == NULL && (flags & UAE_VM_32BIT)) { if (size <= 768 * 1024 * 1024) { address = try_reserve(0x78000000 - size, size, flags); } } if (address == NULL && (flags & UAE_VM_32BIT) == 0) { address = try_reserve(0, size, flags); } #else #ifdef CPU_64_BIT if (flags & UAE_VM_32BIT) { #else if (true) { #endif uintptr_t try_addr = 0x80000000; while (address == NULL) { address = try_reserve(try_addr, size, flags); if (address == NULL) { try_addr -= 0x4000000; if (try_addr < 0x20000000) { break; } continue; } } } if (address == NULL && (flags & UAE_VM_32BIT) == 0) { address = try_reserve(0, size, flags); } #endif if (address) { uae_log("VM: Reserve 0x%-8x bytes, got address 0x%llx\n", size, (uae_u64) (uintptr_t) address); } else { uae_log("VM: Reserve 0x%-8x bytes failed!\n", size); } return address; } void *uae_vm_reserve_fixed(void *want_addr, uae_u32 size, int flags) { void *address = NULL; uae_log("VM: Reserve 0x%-8x bytes at %p (fixed)\n", size, want_addr); address = try_reserve((uintptr_t) want_addr, size, flags); if (address == NULL) { uae_log("VM: Reserve 0x%-8x bytes at %p failed!\n", size, want_addr); return NULL; } if (address != want_addr) { do_free(address, size); return NULL; } uae_log("VM: Reserve 0x%-8x bytes, got address 0x%llx\n", size, (uae_u64) (uintptr_t) address); return address; }
void cli_reserve_lock(int sock, oid_t *pid) { if (try_reserve(*pid)) send_reply(sock, NULL, 0); else send_error(sock, EBUSY); }