diff options
| author | 2018-09-22 19:46:53 -0400 | |
|---|---|---|
| committer | 2018-09-22 19:46:53 -0400 | |
| commit | 93fea4e17943fa189f30a73c179d8efb64a83318 (patch) | |
| tree | fc2f8a95980b3a9d466f0c069c6c432ae69d2e5c /src/core/hle/kernel/thread.cpp | |
| parent | Merge pull request #1386 from jroweboy/oops (diff) | |
| parent | svc: Move most process termination code to its own function within Process (diff) | |
| download | yuzu-93fea4e17943fa189f30a73c179d8efb64a83318.tar.gz yuzu-93fea4e17943fa189f30a73c179d8efb64a83318.tar.xz yuzu-93fea4e17943fa189f30a73c179d8efb64a83318.zip | |
Merge pull request #1378 from lioncash/thread
process: Make a few member variables private where applicable
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 58 |
1 files changed, 2 insertions, 56 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index c2d7535c9..315f65338 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -65,10 +65,7 @@ void Thread::Stop() { | |||
| 65 | wait_objects.clear(); | 65 | wait_objects.clear(); |
| 66 | 66 | ||
| 67 | // Mark the TLS slot in the thread's page as free. | 67 | // Mark the TLS slot in the thread's page as free. |
| 68 | const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; | 68 | owner_process->FreeTLSSlot(tls_address); |
| 69 | const u64 tls_slot = | ||
| 70 | ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; | ||
| 71 | Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); | ||
| 72 | } | 69 | } |
| 73 | 70 | ||
| 74 | void WaitCurrentThread_Sleep() { | 71 | void WaitCurrentThread_Sleep() { |
| @@ -178,32 +175,6 @@ void Thread::ResumeFromWait() { | |||
| 178 | } | 175 | } |
| 179 | 176 | ||
| 180 | /** | 177 | /** |
| 181 | * Finds a free location for the TLS section of a thread. | ||
| 182 | * @param tls_slots The TLS page array of the thread's owner process. | ||
| 183 | * Returns a tuple of (page, slot, alloc_needed) where: | ||
| 184 | * page: The index of the first allocated TLS page that has free slots. | ||
| 185 | * slot: The index of the first free slot in the indicated page. | ||
| 186 | * alloc_needed: Whether there's a need to allocate a new TLS page (All pages are full). | ||
| 187 | */ | ||
| 188 | static std::tuple<std::size_t, std::size_t, bool> GetFreeThreadLocalSlot( | ||
| 189 | const std::vector<std::bitset<8>>& tls_slots) { | ||
| 190 | // Iterate over all the allocated pages, and try to find one where not all slots are used. | ||
| 191 | for (std::size_t page = 0; page < tls_slots.size(); ++page) { | ||
| 192 | const auto& page_tls_slots = tls_slots[page]; | ||
| 193 | if (!page_tls_slots.all()) { | ||
| 194 | // We found a page with at least one free slot, find which slot it is | ||
| 195 | for (std::size_t slot = 0; slot < page_tls_slots.size(); ++slot) { | ||
| 196 | if (!page_tls_slots.test(slot)) { | ||
| 197 | return std::make_tuple(page, slot, false); | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | return std::make_tuple(0, 0, true); | ||
| 204 | } | ||
| 205 | |||
| 206 | /** | ||
| 207 | * Resets a thread context, making it ready to be scheduled and run by the CPU | 178 | * Resets a thread context, making it ready to be scheduled and run by the CPU |
| 208 | * @param context Thread context to reset | 179 | * @param context Thread context to reset |
| 209 | * @param stack_top Address of the top of the stack | 180 | * @param stack_top Address of the top of the stack |
| @@ -264,32 +235,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name | |||
| 264 | thread->owner_process = owner_process; | 235 | thread->owner_process = owner_process; |
| 265 | thread->scheduler = Core::System::GetInstance().Scheduler(processor_id); | 236 | thread->scheduler = Core::System::GetInstance().Scheduler(processor_id); |
| 266 | thread->scheduler->AddThread(thread, priority); | 237 | thread->scheduler->AddThread(thread, priority); |
| 267 | 238 | thread->tls_address = thread->owner_process->MarkNextAvailableTLSSlotAsUsed(*thread); | |
| 268 | // Find the next available TLS index, and mark it as used | ||
| 269 | auto& tls_slots = owner_process->tls_slots; | ||
| 270 | |||
| 271 | auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); | ||
| 272 | if (needs_allocation) { | ||
| 273 | tls_slots.emplace_back(0); // The page is completely available at the start | ||
| 274 | available_page = tls_slots.size() - 1; | ||
| 275 | available_slot = 0; // Use the first slot in the new page | ||
| 276 | |||
| 277 | // Allocate some memory from the end of the linear heap for this region. | ||
| 278 | const std::size_t offset = thread->tls_memory->size(); | ||
| 279 | thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0); | ||
| 280 | |||
| 281 | auto& vm_manager = owner_process->vm_manager; | ||
| 282 | vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get()); | ||
| 283 | |||
| 284 | vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, | ||
| 285 | thread->tls_memory, 0, Memory::PAGE_SIZE, | ||
| 286 | MemoryState::ThreadLocal); | ||
| 287 | } | ||
| 288 | |||
| 289 | // Mark the slot as used | ||
| 290 | tls_slots[available_page].set(available_slot); | ||
| 291 | thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE + | ||
| 292 | available_slot * Memory::TLS_ENTRY_SIZE; | ||
| 293 | 239 | ||
| 294 | // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used | 240 | // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used |
| 295 | // to initialize the context | 241 | // to initialize the context |