mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:57:35 +00:00
Kernel: Support thread-local storage
This patch adds support for TLS according to the x86 System V ABI. Each thread gets a thread-specific memory region, and the GS segment register always points _to a pointer_ to the thread-specific memory. In other words, to access thread-local variables, userspace programs start by dereferencing the pointer at [gs:0]. The Process keeps a master copy of the TLS segment that new threads should use, and when a new thread is created, they get a copy of it. It's basically whatever the PT_TLS program header in the ELF says.
This commit is contained in:
parent
bcfdf9ffa7
commit
ec6bceaa08
7 changed files with 92 additions and 5 deletions
|
@ -30,6 +30,10 @@ struct SignalActionData {
|
|||
int flags { 0 };
|
||||
};
|
||||
|
||||
struct ThreadSpecificData {
|
||||
ThreadSpecificData* self;
|
||||
};
|
||||
|
||||
class Thread {
|
||||
friend class Process;
|
||||
friend class Scheduler;
|
||||
|
@ -214,6 +218,8 @@ public:
|
|||
const char* state_string() const;
|
||||
u32 ticks() const { return m_ticks; }
|
||||
|
||||
VirtualAddress thread_specific_data() const { return m_thread_specific_data; }
|
||||
|
||||
u64 sleep(u32 ticks);
|
||||
|
||||
enum class BlockResult {
|
||||
|
@ -301,6 +307,8 @@ public:
|
|||
void make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment);
|
||||
void make_userspace_stack_for_secondary_thread(void* argument);
|
||||
|
||||
void make_thread_specific_region(Badge<Process>);
|
||||
|
||||
Thread* clone(Process&);
|
||||
|
||||
template<typename Callback>
|
||||
|
@ -336,6 +344,7 @@ private:
|
|||
RefPtr<Region> m_userspace_stack_region;
|
||||
RefPtr<Region> m_kernel_stack_region;
|
||||
RefPtr<Region> m_kernel_stack_for_signal_handler_region;
|
||||
VirtualAddress m_thread_specific_data;
|
||||
SignalActionData m_signal_action_data[32];
|
||||
Region* m_signal_stack_user_region { nullptr };
|
||||
IntrusiveList<Blocker, &Blocker::m_blocker_list_node> m_blockers;
|
||||
|
@ -432,3 +441,6 @@ inline IterationDecision Scheduler::for_each_nonrunnable(Callback callback)
|
|||
|
||||
return IterationDecision::Continue;
|
||||
}
|
||||
|
||||
u16 thread_specific_selector();
|
||||
Descriptor& thread_specific_descriptor();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue