diff options
| author | 2015-05-10 23:19:54 -0500 | |
|---|---|---|
| committer | 2015-05-11 20:09:23 -0500 | |
| commit | dda94e56dde35f5df969b71b2be9195b7d8cdc05 (patch) | |
| tree | bbded5ba6fc9d9a52268614f87c8ac11ed5789f6 /src | |
| parent | Merge pull request #750 from Subv/process_svc (diff) | |
| download | yuzu-dda94e56dde35f5df969b71b2be9195b7d8cdc05.tar.gz yuzu-dda94e56dde35f5df969b71b2be9195b7d8cdc05.tar.xz yuzu-dda94e56dde35f5df969b71b2be9195b7d8cdc05.zip | |
Core/Memory: Add TLS support for creating up to 300 threads
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/process.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 2 | ||||
| -rw-r--r-- | src/core/mem_map.h | 8 |
4 files changed, 24 insertions, 10 deletions
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 22cd1049b..90881054c 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -74,6 +74,9 @@ public: | |||
| 74 | /// The id of this process | 74 | /// The id of this process |
| 75 | u32 process_id = next_process_id++; | 75 | u32 process_id = next_process_id++; |
| 76 | 76 | ||
| 77 | /// Bitmask of the used TLS slots | ||
| 78 | std::bitset<300> used_tls_slots; | ||
| 79 | |||
| 77 | /** | 80 | /** |
| 78 | * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them | 81 | * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them |
| 79 | * to this process. | 82 | * to this process. |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index ab69a4262..34dc257aa 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -107,6 +107,8 @@ void Thread::Stop() { | |||
| 107 | for (auto& wait_object : wait_objects) { | 107 | for (auto& wait_object : wait_objects) { |
| 108 | wait_object->RemoveWaitingThread(this); | 108 | wait_object->RemoveWaitingThread(this); |
| 109 | } | 109 | } |
| 110 | |||
| 111 | Kernel::g_current_process->used_tls_slots[tls_index] = false; | ||
| 110 | } | 112 | } |
| 111 | 113 | ||
| 112 | Thread* ArbitrateHighestPriorityThread(u32 address) { | 114 | Thread* ArbitrateHighestPriorityThread(u32 address) { |
| @@ -404,12 +406,19 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 404 | thread->name = std::move(name); | 406 | thread->name = std::move(name); |
| 405 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom(); | 407 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom(); |
| 406 | thread->owner_process = g_current_process; | 408 | thread->owner_process = g_current_process; |
| 409 | thread->tls_index = -1; | ||
| 410 | |||
| 411 | // Find the next available TLS index, and mark it as used | ||
| 412 | auto& used_tls_slots = Kernel::g_current_process->used_tls_slots; | ||
| 413 | for (unsigned int i = 0; i < used_tls_slots.size(); ++i) { | ||
| 414 | if (used_tls_slots[i] == false) { | ||
| 415 | thread->tls_index = i; | ||
| 416 | used_tls_slots[i] = true; | ||
| 417 | break; | ||
| 418 | } | ||
| 419 | } | ||
| 407 | 420 | ||
| 408 | VAddr tls_address = Memory::TLS_AREA_VADDR + (thread->thread_id - 1) * 0x200; | 421 | ASSERT_MSG(thread->tls_index != -1, "Out of TLS space"); |
| 409 | |||
| 410 | ASSERT_MSG(tls_address < Memory::TLS_AREA_VADDR_END, "Too many threads"); | ||
| 411 | |||
| 412 | thread->tls_address = tls_address; | ||
| 413 | 422 | ||
| 414 | // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used | 423 | // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used |
| 415 | // to initialize the context | 424 | // to initialize the context |
| @@ -505,7 +514,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) { | |||
| 505 | } | 514 | } |
| 506 | 515 | ||
| 507 | VAddr Thread::GetTLSAddress() const { | 516 | VAddr Thread::GetTLSAddress() const { |
| 508 | return tls_address; | 517 | return Memory::TLS_AREA_VADDR + tls_index * 0x200; |
| 509 | } | 518 | } |
| 510 | 519 | ||
| 511 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 520 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 1d4d010fe..cfbebab08 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -157,7 +157,7 @@ public: | |||
| 157 | 157 | ||
| 158 | s32 processor_id; | 158 | s32 processor_id; |
| 159 | 159 | ||
| 160 | VAddr tls_address; ///< Address of the Thread Local Storage of the thread | 160 | s32 tls_index; ///< Index of the Thread Local Storage of the thread |
| 161 | 161 | ||
| 162 | /// Mutexes currently held by this thread, which will be released when it exits. | 162 | /// Mutexes currently held by this thread, which will be released when it exits. |
| 163 | boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; | 163 | boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; |
diff --git a/src/core/mem_map.h b/src/core/mem_map.h index 64de76c39..71f90cb8a 100644 --- a/src/core/mem_map.h +++ b/src/core/mem_map.h | |||
| @@ -94,10 +94,12 @@ enum : VAddr { | |||
| 94 | SHARED_PAGE_SIZE = 0x00001000, | 94 | SHARED_PAGE_SIZE = 0x00001000, |
| 95 | SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, | 95 | SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, |
| 96 | 96 | ||
| 97 | // TODO(yuriks): The exact location and size of this area is uncomfirmed. | 97 | // TODO(yuriks): The size of this area is dynamic, the kernel grows |
| 98 | // it as more and more threads are created. For now we'll just use a | ||
| 99 | // hardcoded value. | ||
| 98 | /// Area where TLS (Thread-Local Storage) buffers are allocated. | 100 | /// Area where TLS (Thread-Local Storage) buffers are allocated. |
| 99 | TLS_AREA_VADDR = 0x1FFA0000, | 101 | TLS_AREA_VADDR = 0x1FF82000, |
| 100 | TLS_AREA_SIZE = 0x00002000, // Each TLS buffer is 0x200 bytes, allows for 16 threads | 102 | TLS_AREA_SIZE = 0x00030000, // Each TLS buffer is 0x200 bytes, allows for 300 threads |
| 101 | TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE, | 103 | TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE, |
| 102 | }; | 104 | }; |
| 103 | 105 | ||