mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 15:39:02 -05:00 
			
		
		
		
	core/memory: Get rid of 3DS leftovers
Removes leftover code from citra that isn't needed.
This commit is contained in:
		| @@ -4,7 +4,6 @@ | ||||
|  | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/memory.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/resource_limit.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| @@ -15,9 +14,7 @@ namespace Kernel { | ||||
| unsigned int Object::next_object_id; | ||||
|  | ||||
| /// Initialize the kernel | ||||
| void Init(u32 system_mode) { | ||||
|     Kernel::MemoryInit(system_mode); | ||||
|  | ||||
| void Init() { | ||||
|     Kernel::ResourceLimitsInit(); | ||||
|     Kernel::ThreadingInit(); | ||||
|     Kernel::TimersInit(); | ||||
| @@ -37,7 +34,6 @@ void Shutdown() { | ||||
|  | ||||
|     Kernel::TimersShutdown(); | ||||
|     Kernel::ResourceLimitsShutdown(); | ||||
|     Kernel::MemoryShutdown(); | ||||
| } | ||||
|  | ||||
| } // namespace Kernel | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| namespace Kernel { | ||||
|  | ||||
| /// Initialize the kernel with the specified system mode. | ||||
| void Init(u32 system_mode); | ||||
| void Init(); | ||||
|  | ||||
| /// Shutdown the kernel | ||||
| void Shutdown(); | ||||
|   | ||||
| @@ -1,90 +0,0 @@ | ||||
| // Copyright 2014 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <algorithm> | ||||
| #include <cinttypes> | ||||
| #include <memory> | ||||
| #include <utility> | ||||
| #include <vector> | ||||
| #include "common/assert.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/kernel/memory.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/vm_manager.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| MemoryRegionInfo memory_regions[3]; | ||||
|  | ||||
| /// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system | ||||
| /// memory configuration type. | ||||
| static const u32 memory_region_sizes[8][3] = { | ||||
|     // Old 3DS layouts | ||||
|     {0x04000000, 0x02C00000, 0x01400000}, // 0 | ||||
|     {/* This appears to be unused. */},   // 1 | ||||
|     {0x06000000, 0x00C00000, 0x01400000}, // 2 | ||||
|     {0x05000000, 0x01C00000, 0x01400000}, // 3 | ||||
|     {0x04800000, 0x02400000, 0x01400000}, // 4 | ||||
|     {0x02000000, 0x04C00000, 0x01400000}, // 5 | ||||
|  | ||||
|     // New 3DS layouts | ||||
|     {0x07C00000, 0x06400000, 0x02000000}, // 6 | ||||
|     {0x0B200000, 0x02E00000, 0x02000000}, // 7 | ||||
| }; | ||||
|  | ||||
| void MemoryInit(u32 mem_type) { | ||||
|     // TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead. | ||||
|     ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!"); | ||||
|     ASSERT(mem_type != 1); | ||||
|  | ||||
|     // The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with | ||||
|     // the sizes specified in the memory_region_sizes table. | ||||
|     VAddr base = 0; | ||||
|     for (int i = 0; i < 3; ++i) { | ||||
|         memory_regions[i].base = base; | ||||
|         memory_regions[i].size = memory_region_sizes[mem_type][i]; | ||||
|         memory_regions[i].used = 0; | ||||
|         memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>(); | ||||
|         // Reserve enough space for this region of FCRAM. | ||||
|         // We do not want this block of memory to be relocated when allocating from it. | ||||
|         memory_regions[i].linear_heap_memory->reserve(memory_regions[i].size); | ||||
|  | ||||
|         base += memory_regions[i].size; | ||||
|     } | ||||
|  | ||||
|     // We must've allocated the entire FCRAM by the end | ||||
|     ASSERT(base == Memory::FCRAM_SIZE); | ||||
| } | ||||
|  | ||||
| void MemoryShutdown() { | ||||
|     for (auto& region : memory_regions) { | ||||
|         region.base = 0; | ||||
|         region.size = 0; | ||||
|         region.used = 0; | ||||
|         region.linear_heap_memory = nullptr; | ||||
|     } | ||||
| } | ||||
|  | ||||
| MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) { | ||||
|     switch (region) { | ||||
|     case MemoryRegion::APPLICATION: | ||||
|         return &memory_regions[0]; | ||||
|     case MemoryRegion::SYSTEM: | ||||
|         return &memory_regions[1]; | ||||
|     case MemoryRegion::BASE: | ||||
|         return &memory_regions[2]; | ||||
|     default: | ||||
|         UNREACHABLE(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {} | ||||
|  | ||||
| void MapSharedPages(VMManager& address_space) {} | ||||
|  | ||||
| } // namespace Kernel | ||||
| @@ -1,34 +0,0 @@ | ||||
| // Copyright 2014 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <memory> | ||||
| #include <vector> | ||||
|  | ||||
| #include "common/common_types.h" | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| class VMManager; | ||||
| enum class MemoryRegion : u16; | ||||
| struct AddressMapping; | ||||
|  | ||||
| struct MemoryRegionInfo { | ||||
|     u64 base; // Not an address, but offset from start of FCRAM | ||||
|     u64 size; | ||||
|     u64 used; | ||||
|  | ||||
|     std::shared_ptr<std::vector<u8>> linear_heap_memory; | ||||
| }; | ||||
|  | ||||
| void MemoryInit(u32 mem_type); | ||||
| void MemoryShutdown(); | ||||
| MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); | ||||
|  | ||||
| void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping); | ||||
| void MapSharedPages(VMManager& address_space); | ||||
|  | ||||
| extern MemoryRegionInfo memory_regions[3]; | ||||
| } // namespace Kernel | ||||
| @@ -8,7 +8,6 @@ | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/kernel/errors.h" | ||||
| #include "core/hle/kernel/memory.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/resource_limit.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| @@ -125,14 +124,6 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | ||||
|                         std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, | ||||
|                         MemoryState::Mapped) | ||||
|         .Unwrap(); | ||||
|     misc_memory_used += stack_size; | ||||
|     memory_region->used += stack_size; | ||||
|  | ||||
|     // Map special address mappings | ||||
|     MapSharedPages(vm_manager); | ||||
|     for (const auto& mapping : address_mappings) { | ||||
|         HandleSpecialMapping(vm_manager, mapping); | ||||
|     } | ||||
|  | ||||
|     vm_manager.LogLayout(); | ||||
|     status = ProcessStatus::Running; | ||||
| @@ -141,17 +132,13 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | ||||
| } | ||||
|  | ||||
| void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { | ||||
|     memory_region = GetMemoryRegion(flags.memory_region); | ||||
|  | ||||
|     auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, | ||||
|                           MemoryState memory_state) { | ||||
|     const auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, | ||||
|                                 MemoryState memory_state) { | ||||
|         auto vma = vm_manager | ||||
|                        .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, | ||||
|                                        segment.size, memory_state) | ||||
|                        .Unwrap(); | ||||
|         vm_manager.Reprotect(vma, permissions); | ||||
|         misc_memory_used += segment.size; | ||||
|         memory_region->used += segment.size; | ||||
|     }; | ||||
|  | ||||
|     // Map CodeSet segments | ||||
| @@ -160,20 +147,6 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { | ||||
|     MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable); | ||||
| } | ||||
|  | ||||
| VAddr Process::GetLinearHeapAreaAddress() const { | ||||
|     // Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of | ||||
|     // the extra RAM in the n3DS. | ||||
|     return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR; | ||||
| } | ||||
|  | ||||
| VAddr Process::GetLinearHeapBase() const { | ||||
|     return GetLinearHeapAreaAddress() + memory_region->base; | ||||
| } | ||||
|  | ||||
| VAddr Process::GetLinearHeapLimit() const { | ||||
|     return GetLinearHeapBase() + memory_region->size; | ||||
| } | ||||
|  | ||||
| ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { | ||||
|     if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || | ||||
|         target + size < target) { | ||||
| @@ -206,7 +179,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per | ||||
|     vm_manager.Reprotect(vma, perms); | ||||
|  | ||||
|     heap_used = size; | ||||
|     memory_region->used += size; | ||||
|  | ||||
|     return MakeResult<VAddr>(heap_end - size); | ||||
| } | ||||
| @@ -226,52 +198,6 @@ ResultCode Process::HeapFree(VAddr target, u32 size) { | ||||
|         return result; | ||||
|  | ||||
|     heap_used -= size; | ||||
|     memory_region->used -= size; | ||||
|  | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) { | ||||
|     UNIMPLEMENTED(); | ||||
|     return {}; | ||||
| } | ||||
|  | ||||
| ResultCode Process::LinearFree(VAddr target, u32 size) { | ||||
|     auto& linheap_memory = memory_region->linear_heap_memory; | ||||
|  | ||||
|     if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() || | ||||
|         target + size < target) { | ||||
|  | ||||
|         return ERR_INVALID_ADDRESS; | ||||
|     } | ||||
|  | ||||
|     if (size == 0) { | ||||
|         return RESULT_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size(); | ||||
|     if (target + size > heap_end) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|     ResultCode result = vm_manager.UnmapRange(target, size); | ||||
|     if (result.IsError()) | ||||
|         return result; | ||||
|  | ||||
|     linear_heap_used -= size; | ||||
|     memory_region->used -= size; | ||||
|  | ||||
|     if (target + size == heap_end) { | ||||
|         // End of linear heap has been freed, so check what's the last allocated block in it and | ||||
|         // reduce the size. | ||||
|         auto vma = vm_manager.FindVMA(target); | ||||
|         ASSERT(vma != vm_manager.vma_map.end()); | ||||
|         ASSERT(vma->second.type == VMAType::Free); | ||||
|         VAddr new_end = vma->second.base; | ||||
|         if (new_end >= GetLinearHeapBase()) { | ||||
|             linheap_memory->resize(new_end - GetLinearHeapBase()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|   | ||||
| @@ -53,7 +53,6 @@ union ProcessFlags { | ||||
| enum class ProcessStatus { Created, Running, Exited }; | ||||
|  | ||||
| class ResourceLimit; | ||||
| struct MemoryRegionInfo; | ||||
|  | ||||
| struct CodeSet final : public Object { | ||||
|     static SharedPtr<CodeSet> Create(std::string name); | ||||
| @@ -163,12 +162,11 @@ public: | ||||
|     // This makes deallocation and reallocation of holes fast and keeps process memory contiguous | ||||
|     // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. | ||||
|     std::shared_ptr<std::vector<u8>> heap_memory; | ||||
|  | ||||
|     // The left/right bounds of the address space covered by heap_memory. | ||||
|     VAddr heap_start = 0, heap_end = 0; | ||||
|  | ||||
|     u64 heap_used = 0, linear_heap_used = 0, misc_memory_used = 0; | ||||
|  | ||||
|     MemoryRegionInfo* memory_region = nullptr; | ||||
|     VAddr heap_start = 0; | ||||
|     VAddr heap_end = 0; | ||||
|     u64 heap_used = 0; | ||||
|  | ||||
|     /// The Thread Local Storage area is allocated as processes create threads, | ||||
|     /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part | ||||
| @@ -179,16 +177,9 @@ public: | ||||
|  | ||||
|     std::string name; | ||||
|  | ||||
|     VAddr GetLinearHeapAreaAddress() const; | ||||
|     VAddr GetLinearHeapBase() const; | ||||
|     VAddr GetLinearHeapLimit() const; | ||||
|  | ||||
|     ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); | ||||
|     ResultCode HeapFree(VAddr target, u32 size); | ||||
|  | ||||
|     ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms); | ||||
|     ResultCode LinearFree(VAddr target, u32 size); | ||||
|  | ||||
|     ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); | ||||
|  | ||||
|     ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); | ||||
|   | ||||
| @@ -8,7 +8,6 @@ | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/errors.h" | ||||
| #include "core/hle/kernel/memory.h" | ||||
| #include "core/hle/kernel/shared_memory.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| @@ -29,51 +28,22 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u | ||||
|     shared_memory->permissions = permissions; | ||||
|     shared_memory->other_permissions = other_permissions; | ||||
|  | ||||
|     if (address == 0) { | ||||
|         // We need to allocate a block from the Linear Heap ourselves. | ||||
|         // We'll manually allocate some memory from the linear heap in the specified region. | ||||
|         MemoryRegionInfo* memory_region = GetMemoryRegion(region); | ||||
|         auto& linheap_memory = memory_region->linear_heap_memory; | ||||
|     auto& vm_manager = shared_memory->owner_process->vm_manager; | ||||
|  | ||||
|         ASSERT_MSG(linheap_memory->size() + size <= memory_region->size, | ||||
|                    "Not enough space in region to allocate shared memory!"); | ||||
|     // 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"); | ||||
|  | ||||
|         shared_memory->backing_block = linheap_memory; | ||||
|         shared_memory->backing_block_offset = linheap_memory->size(); | ||||
|         // Allocate some memory from the end of the linear heap for this region. | ||||
|         linheap_memory->insert(linheap_memory->end(), size, 0); | ||||
|         memory_region->used += size; | ||||
|  | ||||
|         shared_memory->linear_heap_phys_address = | ||||
|             Memory::FCRAM_PADDR + memory_region->base + | ||||
|             static_cast<PAddr>(shared_memory->backing_block_offset); | ||||
|  | ||||
|         // Increase the amount of used linear heap memory for the owner process. | ||||
|         if (shared_memory->owner_process != nullptr) { | ||||
|             shared_memory->owner_process->linear_heap_used += size; | ||||
|         } | ||||
|  | ||||
|         // Refresh the address mappings for the current process. | ||||
|         if (Core::CurrentProcess() != nullptr) { | ||||
|             Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.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; | ||||
|     } | ||||
|     // 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->base_address = address; | ||||
|  | ||||
|     return shared_memory; | ||||
| } | ||||
|  | ||||
| @@ -124,11 +94,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi | ||||
|  | ||||
|     VAddr target_address = address; | ||||
|  | ||||
|     if (base_address == 0 && target_address == 0) { | ||||
|         // Calculate the address at which to map the memory block. | ||||
|         target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value(); | ||||
|     } | ||||
|  | ||||
|     // Map the memory block into the target process | ||||
|     auto result = target_process->vm_manager.MapMemoryBlock( | ||||
|         target_address, backing_block, backing_block_offset, size, MemoryState::Shared); | ||||
|   | ||||
| @@ -111,9 +111,6 @@ public: | ||||
|     SharedPtr<Process> owner_process; | ||||
|     /// Address of shared memory block in the owner process if specified. | ||||
|     VAddr base_address; | ||||
|     /// Physical address of the shared memory block in the linear heap if no address was specified | ||||
|     /// during creation. | ||||
|     PAddr linear_heap_phys_address; | ||||
|     /// Backing memory for this shared memory block. | ||||
|     std::shared_ptr<std::vector<u8>> backing_block; | ||||
|     /// Offset into the backing block for this shared memory. | ||||
|   | ||||
| @@ -20,7 +20,6 @@ | ||||
| #include "core/core_timing_util.h" | ||||
| #include "core/hle/kernel/errors.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/memory.h" | ||||
| #include "core/hle/kernel/object.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| @@ -81,8 +80,8 @@ void Thread::Stop() { | ||||
|     wait_objects.clear(); | ||||
|  | ||||
|     // Mark the TLS slot in the thread's page as free. | ||||
|     u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; | ||||
|     u64 tls_slot = | ||||
|     const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; | ||||
|     const u64 tls_slot = | ||||
|         ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; | ||||
|     Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); | ||||
| } | ||||
| @@ -336,38 +335,10 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | ||||
|     auto& tls_slots = owner_process->tls_slots; | ||||
|  | ||||
|     auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); | ||||
|  | ||||
|     if (needs_allocation) { | ||||
|         // There are no already-allocated pages with free slots, lets allocate a new one. | ||||
|         // TLS pages are allocated from the BASE region in the linear heap. | ||||
|         MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE); | ||||
|         auto& linheap_memory = memory_region->linear_heap_memory; | ||||
|  | ||||
|         if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { | ||||
|             LOG_ERROR(Kernel_SVC, | ||||
|                       "Not enough space in region to allocate a new TLS page for thread"); | ||||
|             return ERR_OUT_OF_MEMORY; | ||||
|         } | ||||
|  | ||||
|         size_t offset = linheap_memory->size(); | ||||
|  | ||||
|         // Allocate some memory from the end of the linear heap for this region. | ||||
|         linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0); | ||||
|         memory_region->used += Memory::PAGE_SIZE; | ||||
|         owner_process->linear_heap_used += Memory::PAGE_SIZE; | ||||
|  | ||||
|         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 | ||||
|  | ||||
|         auto& vm_manager = owner_process->vm_manager; | ||||
|         vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); | ||||
|  | ||||
|         // Map the page to the current process' address space. | ||||
|         // TODO(Subv): Find the correct MemoryState for this region. | ||||
|         vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, | ||||
|                                   linheap_memory, offset, Memory::PAGE_SIZE, | ||||
|                                   MemoryState::ThreadLocal); | ||||
|     } | ||||
|  | ||||
|     // Mark the slot as used | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lioncash
					Lioncash