summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/shared_memory.cpp38
-rw-r--r--src/core/hle/kernel/thread.cpp11
-rw-r--r--src/core/hle/kernel/thread.h2
3 files changed, 38 insertions, 13 deletions
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index b3ddebb3d..21ddc2f7d 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -28,20 +28,32 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
shared_memory->permissions = permissions;
shared_memory->other_permissions = other_permissions;
- auto& vm_manager = shared_memory->owner_process->vm_manager;
-
- // The memory is already available and mapped in the owner process.
- auto vma = vm_manager.FindVMA(address);
- ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
- ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address");
-
- // The returned VMA might be a bigger one encompassing the desired address.
- auto vma_offset = address - vma->first;
- ASSERT_MSG(vma_offset + size <= vma->second.size,
- "Shared memory exceeds bounds of mapped block");
+ if (address == 0) {
+ shared_memory->backing_block = std::make_shared<std::vector<u8>>(size);
+ shared_memory->backing_block_offset = 0;
+
+ // Refresh the address mappings for the current process.
+ if (Core::CurrentProcess() != nullptr) {
+ Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(
+ shared_memory->backing_block.get());
+ }
+ } else {
+ auto& vm_manager = shared_memory->owner_process->vm_manager;
+
+ // The memory is already available and mapped in the owner process.
+ auto vma = vm_manager.FindVMA(address);
+ ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
+ ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address");
+
+ // The returned VMA might be a bigger one encompassing the desired address.
+ auto vma_offset = address - vma->first;
+ ASSERT_MSG(vma_offset + size <= vma->second.size,
+ "Shared memory exceeds bounds of mapped block");
+
+ shared_memory->backing_block = vma->second.backing_block;
+ shared_memory->backing_block_offset = vma->second.offset + vma_offset;
+ }
- shared_memory->backing_block = vma->second.backing_block;
- shared_memory->backing_block_offset = vma->second.offset + vma_offset;
shared_memory->base_address = address;
return shared_memory;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index ea9554cbb..b9022feae 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -339,6 +339,17 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
tls_slots.emplace_back(0); // The page is completely available at the start
available_page = tls_slots.size() - 1;
available_slot = 0; // Use the first slot in the new page
+
+ // Allocate some memory from the end of the linear heap for this region.
+ const size_t offset = thread->tls_memory->size();
+ thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0);
+
+ auto& vm_manager = owner_process->vm_manager;
+ vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get());
+
+ vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
+ thread->tls_memory, 0, Memory::PAGE_SIZE,
+ MemoryState::ThreadLocal);
}
// Mark the slot as used
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 146955e13..adc804248 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -265,6 +265,8 @@ public:
private:
Thread();
~Thread() override;
+
+ std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>();
};
/**