mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 02:58:12 +00:00
Kernel+LibC: Add a simple create_thread() syscall.
It takes two parameters, a function pointer for the entry function, and a void* argument to be passed to that function on the new thread.
This commit is contained in:
parent
7f1757b16c
commit
e561ab1b0b
10 changed files with 45 additions and 5 deletions
|
@ -406,7 +406,7 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
|
||||||
main_thread().m_tss.gs = 0x23;
|
main_thread().m_tss.gs = 0x23;
|
||||||
main_thread().m_tss.ss = 0x23;
|
main_thread().m_tss.ss = 0x23;
|
||||||
main_thread().m_tss.cr3 = page_directory().cr3();
|
main_thread().m_tss.cr3 = page_directory().cr3();
|
||||||
main_thread().make_userspace_stack(move(arguments), move(environment));
|
main_thread().make_userspace_stack_for_main_thread(move(arguments), move(environment));
|
||||||
main_thread().m_tss.ss0 = 0x10;
|
main_thread().m_tss.ss0 = 0x10;
|
||||||
main_thread().m_tss.esp0 = old_esp0;
|
main_thread().m_tss.esp0 = old_esp0;
|
||||||
main_thread().m_tss.ss2 = m_pid;
|
main_thread().m_tss.ss2 = m_pid;
|
||||||
|
@ -2452,3 +2452,18 @@ int Process::thread_count() const
|
||||||
});
|
});
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Process::sys$create_thread(int(*entry)(void*), void* argument)
|
||||||
|
{
|
||||||
|
if (!validate_read((const void*)entry, sizeof(void*)))
|
||||||
|
return -EFAULT;
|
||||||
|
auto* thread = new Thread(*this);
|
||||||
|
auto& tss = thread->tss();
|
||||||
|
tss.eip = (dword)entry;
|
||||||
|
tss.eflags = 0x0202;
|
||||||
|
tss.cr3 = page_directory().cr3();
|
||||||
|
thread->make_userspace_stack_for_secondary_thread(argument);
|
||||||
|
|
||||||
|
thread->set_state(Thread::State::Runnable);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -178,6 +178,7 @@ public:
|
||||||
int sys$getsockopt(const Syscall::SC_getsockopt_params*);
|
int sys$getsockopt(const Syscall::SC_getsockopt_params*);
|
||||||
int sys$setsockopt(const Syscall::SC_setsockopt_params*);
|
int sys$setsockopt(const Syscall::SC_setsockopt_params*);
|
||||||
int sys$restore_signal_mask(dword mask);
|
int sys$restore_signal_mask(dword mask);
|
||||||
|
int sys$create_thread(int(*)(void*), void*);
|
||||||
|
|
||||||
int sys$create_shared_buffer(pid_t peer_pid, int, void** buffer);
|
int sys$create_shared_buffer(pid_t peer_pid, int, void** buffer);
|
||||||
void* sys$get_shared_buffer(int shared_buffer_id);
|
void* sys$get_shared_buffer(int shared_buffer_id);
|
||||||
|
|
|
@ -235,6 +235,8 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
|
||||||
return current->process().sys$getsockopt((const SC_getsockopt_params*)arg1);
|
return current->process().sys$getsockopt((const SC_getsockopt_params*)arg1);
|
||||||
case Syscall::SC_setsockopt:
|
case Syscall::SC_setsockopt:
|
||||||
return current->process().sys$setsockopt((const SC_setsockopt_params*)arg1);
|
return current->process().sys$setsockopt((const SC_setsockopt_params*)arg1);
|
||||||
|
case Syscall::SC_create_thread:
|
||||||
|
return current->process().sys$create_thread((int(*)(void*))arg1, (void*)arg2);
|
||||||
default:
|
default:
|
||||||
kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3);
|
kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -92,6 +92,7 @@
|
||||||
__ENUMERATE_SYSCALL(recvfrom) \
|
__ENUMERATE_SYSCALL(recvfrom) \
|
||||||
__ENUMERATE_SYSCALL(getsockopt) \
|
__ENUMERATE_SYSCALL(getsockopt) \
|
||||||
__ENUMERATE_SYSCALL(setsockopt) \
|
__ENUMERATE_SYSCALL(setsockopt) \
|
||||||
|
__ENUMERATE_SYSCALL(create_thread) \
|
||||||
|
|
||||||
|
|
||||||
namespace Syscall {
|
namespace Syscall {
|
||||||
|
|
|
@ -435,7 +435,7 @@ void Thread::push_value_on_stack(dword value)
|
||||||
*stack_ptr = value;
|
*stack_ptr = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::make_userspace_stack(Vector<String> arguments, Vector<String> environment)
|
void Thread::make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment)
|
||||||
{
|
{
|
||||||
auto* region = m_process.allocate_region(LinearAddress(), default_userspace_stack_size, "stack");
|
auto* region = m_process.allocate_region(LinearAddress(), default_userspace_stack_size, "stack");
|
||||||
ASSERT(region);
|
ASSERT(region);
|
||||||
|
@ -482,12 +482,23 @@ void Thread::make_userspace_stack(Vector<String> arguments, Vector<String> envir
|
||||||
push_value_on_stack(0);
|
push_value_on_stack(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Thread::make_userspace_stack_for_secondary_thread(void *argument)
|
||||||
|
{
|
||||||
|
auto* region = m_process.allocate_region(LinearAddress(), default_userspace_stack_size, String::format("Thread %u Stack", tid()));
|
||||||
|
ASSERT(region);
|
||||||
|
m_stack_top3 = region->laddr().offset(default_userspace_stack_size).get();
|
||||||
|
m_tss.esp = m_stack_top3;
|
||||||
|
|
||||||
|
// NOTE: The stack needs to be 16-byte aligned.
|
||||||
|
push_value_on_stack((dword)argument);
|
||||||
|
push_value_on_stack(0);
|
||||||
|
}
|
||||||
|
|
||||||
Thread* Thread::clone(Process& process)
|
Thread* Thread::clone(Process& process)
|
||||||
{
|
{
|
||||||
auto* clone = new Thread(process);
|
auto* clone = new Thread(process);
|
||||||
memcpy(clone->m_signal_action_data, m_signal_action_data, sizeof(m_signal_action_data));
|
memcpy(clone->m_signal_action_data, m_signal_action_data, sizeof(m_signal_action_data));
|
||||||
clone->m_signal_mask = m_signal_mask;
|
clone->m_signal_mask = m_signal_mask;
|
||||||
//clone->m_tss = m_tss;
|
|
||||||
clone->m_fpu_state = m_fpu_state;
|
clone->m_fpu_state = m_fpu_state;
|
||||||
clone->m_has_used_fpu = m_has_used_fpu;
|
clone->m_has_used_fpu = m_has_used_fpu;
|
||||||
return clone;
|
return clone;
|
||||||
|
|
|
@ -116,7 +116,8 @@ public:
|
||||||
|
|
||||||
void set_default_signal_dispositions();
|
void set_default_signal_dispositions();
|
||||||
void push_value_on_stack(dword);
|
void push_value_on_stack(dword);
|
||||||
void make_userspace_stack(Vector<String> arguments, Vector<String> environment);
|
void make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment);
|
||||||
|
void make_userspace_stack_for_secondary_thread(void* argument);
|
||||||
|
|
||||||
Thread* clone(Process&);
|
Thread* clone(Process&);
|
||||||
|
|
||||||
|
|
|
@ -273,9 +273,10 @@ void exception_14_handler(RegisterDumpWithExceptionCode& regs)
|
||||||
auto response = MM.handle_page_fault(PageFault(regs.exception_code, LinearAddress(faultAddress)));
|
auto response = MM.handle_page_fault(PageFault(regs.exception_code, LinearAddress(faultAddress)));
|
||||||
|
|
||||||
if (response == PageFaultResponse::ShouldCrash) {
|
if (response == PageFaultResponse::ShouldCrash) {
|
||||||
kprintf("%s(%u) unrecoverable page fault, %s laddr=%p\n",
|
kprintf("%s(%u:%u) unrecoverable page fault, %s laddr=%p\n",
|
||||||
current->process().name().characters(),
|
current->process().name().characters(),
|
||||||
current->pid(),
|
current->pid(),
|
||||||
|
current->tid(),
|
||||||
regs.exception_code & 2 ? "write" : "read",
|
regs.exception_code & 2 ? "write" : "read",
|
||||||
faultAddress);
|
faultAddress);
|
||||||
dump(regs);
|
dump(regs);
|
||||||
|
|
|
@ -89,6 +89,7 @@ cp -v ../Applications/About/About mnt/bin/About
|
||||||
cp -v ../Applications/TextEditor/TextEditor mnt/bin/TextEditor
|
cp -v ../Applications/TextEditor/TextEditor mnt/bin/TextEditor
|
||||||
cp -v ../Applications/IRCClient/IRCClient mnt/bin/IRCClient
|
cp -v ../Applications/IRCClient/IRCClient mnt/bin/IRCClient
|
||||||
ln -s IRCClient mnt/bin/irc
|
ln -s IRCClient mnt/bin/irc
|
||||||
|
ln -s FileManager mnt/bin/fm
|
||||||
cp -v ../Servers/LookupServer/LookupServer mnt/bin/LookupServer
|
cp -v ../Servers/LookupServer/LookupServer mnt/bin/LookupServer
|
||||||
cp -v ../Servers/WindowServer/WindowServer mnt/bin/WindowServer
|
cp -v ../Servers/WindowServer/WindowServer mnt/bin/WindowServer
|
||||||
cp -v kernel.map mnt/
|
cp -v kernel.map mnt/
|
||||||
|
|
|
@ -410,4 +410,10 @@ char* getlogin()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int create_thread(int(*entry)(void*), void* argument)
|
||||||
|
{
|
||||||
|
int rc = syscall(SC_create_thread, entry, argument);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ __BEGIN_DECLS
|
||||||
|
|
||||||
extern char** environ;
|
extern char** environ;
|
||||||
|
|
||||||
|
int create_thread(int(*)(void*), void*);
|
||||||
int create_shared_buffer(pid_t peer_pid, int, void** buffer);
|
int create_shared_buffer(pid_t peer_pid, int, void** buffer);
|
||||||
void* get_shared_buffer(int shared_buffer_id);
|
void* get_shared_buffer(int shared_buffer_id);
|
||||||
int release_shared_buffer(int shared_buffer_id);
|
int release_shared_buffer(int shared_buffer_id);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue