summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp33
1 files changed, 2 insertions, 31 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index cdb8120f2..ea9554cbb 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -20,7 +20,6 @@
20#include "core/core_timing_util.h" 20#include "core/core_timing_util.h"
21#include "core/hle/kernel/errors.h" 21#include "core/hle/kernel/errors.h"
22#include "core/hle/kernel/handle_table.h" 22#include "core/hle/kernel/handle_table.h"
23#include "core/hle/kernel/memory.h"
24#include "core/hle/kernel/object.h" 23#include "core/hle/kernel/object.h"
25#include "core/hle/kernel/process.h" 24#include "core/hle/kernel/process.h"
26#include "core/hle/kernel/thread.h" 25#include "core/hle/kernel/thread.h"
@@ -81,8 +80,8 @@ void Thread::Stop() {
81 wait_objects.clear(); 80 wait_objects.clear();
82 81
83 // Mark the TLS slot in the thread's page as free. 82 // Mark the TLS slot in the thread's page as free.
84 u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; 83 const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
85 u64 tls_slot = 84 const u64 tls_slot =
86 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; 85 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
87 Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); 86 Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
88} 87}
@@ -336,38 +335,10 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
336 auto& tls_slots = owner_process->tls_slots; 335 auto& tls_slots = owner_process->tls_slots;
337 336
338 auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); 337 auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots);
339
340 if (needs_allocation) { 338 if (needs_allocation) {
341 // There are no already-allocated pages with free slots, lets allocate a new one.
342 // TLS pages are allocated from the BASE region in the linear heap.
343 MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE);
344 auto& linheap_memory = memory_region->linear_heap_memory;
345
346 if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
347 LOG_ERROR(Kernel_SVC,
348 "Not enough space in region to allocate a new TLS page for thread");
349 return ERR_OUT_OF_MEMORY;
350 }
351
352 size_t offset = linheap_memory->size();
353
354 // Allocate some memory from the end of the linear heap for this region.
355 linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
356 memory_region->used += Memory::PAGE_SIZE;
357 owner_process->linear_heap_used += Memory::PAGE_SIZE;
358
359 tls_slots.emplace_back(0); // The page is completely available at the start 339 tls_slots.emplace_back(0); // The page is completely available at the start
360 available_page = tls_slots.size() - 1; 340 available_page = tls_slots.size() - 1;
361 available_slot = 0; // Use the first slot in the new page 341 available_slot = 0; // Use the first slot in the new page
362
363 auto& vm_manager = owner_process->vm_manager;
364 vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
365
366 // Map the page to the current process' address space.
367 // TODO(Subv): Find the correct MemoryState for this region.
368 vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
369 linheap_memory, offset, Memory::PAGE_SIZE,
370 MemoryState::ThreadLocal);
371 } 342 }
372 343
373 // Mark the slot as used 344 // Mark the slot as used