summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDr. Chat <arkolbed@gmail.com>2018-11-18 18:24:35 -0600
committerDr. Chat <arkolbed@gmail.com>2018-11-23 17:53:26 -0600
commita8bef91cc4ab6758c5bbbe02df734c2d7a346aaa (patch)
treec741a44580dc0ae794d89260842722a3c52a3e60
parentbcfaf530cb1e24a4e0f80d694263a14ada2b821b (diff)
[x64] Fix improper use of compare_exchange_strong when adjusting code commit mark
-rw-r--r--src/xenia/cpu/backend/x64/x64_code_cache.cc28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/xenia/cpu/backend/x64/x64_code_cache.cc b/src/xenia/cpu/backend/x64/x64_code_cache.cc
index b258f2658..e4a23248e 100644
--- a/src/xenia/cpu/backend/x64/x64_code_cache.cc
+++ b/src/xenia/cpu/backend/x64/x64_code_cache.cc
@@ -174,15 +174,17 @@ void* X64CodeCache::PlaceGuestCode(uint32_t guest_address, void* machine_code,
// If we are going above the high water mark of committed memory, commit
// some more. It's ok if multiple threads do this, as redundant commits
// aren't harmful.
- size_t old_commit_mark = generated_code_commit_mark_;
- if (high_mark > old_commit_mark) {
- size_t new_commit_mark = old_commit_mark + 16 * 1024 * 1024;
+ size_t old_commit_mark, new_commit_mark;
+ do {
+ old_commit_mark = generated_code_commit_mark_;
+ if (high_mark <= old_commit_mark) break;
+
+ new_commit_mark = old_commit_mark + 16 * 1024 * 1024;
xe::memory::AllocFixed(generated_code_base_, new_commit_mark,
xe::memory::AllocationType::kCommit,
xe::memory::PageAccess::kExecuteReadWrite);
- generated_code_commit_mark_.compare_exchange_strong(old_commit_mark,
- new_commit_mark);
- }
+ } while (generated_code_commit_mark_.compare_exchange_weak(
+ old_commit_mark, new_commit_mark));
// Copy code.
std::memcpy(code_address, machine_code, code_size);
@@ -248,15 +250,17 @@ uint32_t X64CodeCache::PlaceData(const void* data, size_t length) {
// If we are going above the high water mark of committed memory, commit some
// more. It's ok if multiple threads do this, as redundant commits aren't
// harmful.
- size_t old_commit_mark = generated_code_commit_mark_;
- if (high_mark > old_commit_mark) {
- size_t new_commit_mark = old_commit_mark + 16 * 1024 * 1024;
+ size_t old_commit_mark, new_commit_mark;
+ do {
+ old_commit_mark = generated_code_commit_mark_;
+ if (high_mark <= old_commit_mark) break;
+
+ new_commit_mark = old_commit_mark + 16 * 1024 * 1024;
xe::memory::AllocFixed(generated_code_base_, new_commit_mark,
xe::memory::AllocationType::kCommit,
xe::memory::PageAccess::kExecuteReadWrite);
- generated_code_commit_mark_.compare_exchange_strong(old_commit_mark,
- new_commit_mark);
- }
+ } while (generated_code_commit_mark_.compare_exchange_weak(old_commit_mark,
+ new_commit_mark));
// Copy code.
std::memcpy(data_address, data, length);