mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 01:37:39 +03:00
Kernel: PID/TID typing
This compiles, and contains exactly the same bugs as before. The regex 'FIXME: PID/' should reveal all markers that I left behind, including: - Incomplete conversion - Issues or things that look fishy - Actual bugs that will go wrong during runtime
This commit is contained in:
parent
f225321184
commit
f5744a6f2f
Notes:
sideshowbarker
2024-07-19 04:06:48 +09:00
Author: https://github.com/BenWiederhake Commit: https://github.com/SerenityOS/serenity/commit/f5744a6f2f6 Pull-request: https://github.com/SerenityOS/serenity/pull/3057 Reviewed-by: https://github.com/alimpfard Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/bgianfo
@ -123,7 +123,7 @@ enum ProcFileType {
|
||||
FI_MaxStaticFileIndex,
|
||||
};
|
||||
|
||||
static inline pid_t to_pid(const InodeIdentifier& identifier)
|
||||
static inline ProcessID to_pid(const InodeIdentifier& identifier)
|
||||
{
|
||||
#ifdef PROCFS_DEBUG
|
||||
dbg() << "to_pid, index=" << String::format("%08x", identifier.index()) << " -> " << (identifier.index() >> 16);
|
||||
@ -154,14 +154,14 @@ static inline size_t to_sys_index(const InodeIdentifier& identifier)
|
||||
return identifier.index() >> 16u;
|
||||
}
|
||||
|
||||
static inline InodeIdentifier to_identifier(unsigned fsid, ProcParentDirectory parent, pid_t pid, ProcFileType proc_file_type)
|
||||
static inline InodeIdentifier to_identifier(unsigned fsid, ProcParentDirectory parent, ProcessID pid, ProcFileType proc_file_type)
|
||||
{
|
||||
return { fsid, ((unsigned)parent << 12u) | ((unsigned)pid << 16u) | (unsigned)proc_file_type };
|
||||
return { fsid, ((unsigned)parent << 12u) | ((unsigned)pid.value() << 16u) | (unsigned)proc_file_type };
|
||||
}
|
||||
|
||||
static inline InodeIdentifier to_identifier_with_fd(unsigned fsid, pid_t pid, int fd)
|
||||
static inline InodeIdentifier to_identifier_with_fd(unsigned fsid, ProcessID pid, int fd)
|
||||
{
|
||||
return { fsid, (PDI_PID_fd << 12u) | ((unsigned)pid << 16u) | (FI_MaxStaticFileIndex + fd) };
|
||||
return { fsid, (PDI_PID_fd << 12u) | ((unsigned)pid.value() << 16u) | (FI_MaxStaticFileIndex + fd) };
|
||||
}
|
||||
|
||||
static inline InodeIdentifier sys_var_to_identifier(unsigned fsid, unsigned index)
|
||||
@ -663,7 +663,7 @@ Optional<KBuffer> procfs$pid_root(InodeIdentifier identifier)
|
||||
Optional<KBuffer> procfs$self(InodeIdentifier)
|
||||
{
|
||||
char buffer[16];
|
||||
sprintf(buffer, "%u", Process::current()->pid());
|
||||
sprintf(buffer, "%d", Process::current()->pid().value());
|
||||
return KBuffer::copy((const u8*)buffer, strlen(buffer));
|
||||
}
|
||||
|
||||
@ -821,13 +821,13 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
|
||||
break;
|
||||
}
|
||||
|
||||
process_object.add("pid", process.pid());
|
||||
process_object.add("pid", process.pid().value());
|
||||
process_object.add("pgid", process.tty() ? process.tty()->pgid() : 0);
|
||||
process_object.add("pgp", process.pgid());
|
||||
process_object.add("sid", process.sid());
|
||||
process_object.add("uid", process.uid());
|
||||
process_object.add("gid", process.gid());
|
||||
process_object.add("ppid", process.ppid());
|
||||
process_object.add("ppid", process.ppid().value());
|
||||
process_object.add("nfds", process.number_of_open_file_descriptors());
|
||||
process_object.add("name", process.name());
|
||||
process_object.add("tty", process.tty() ? process.tty()->tty_name() : "notty");
|
||||
@ -842,7 +842,7 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
|
||||
auto thread_array = process_object.add_array("threads");
|
||||
process.for_each_thread([&](const Thread& thread) {
|
||||
auto thread_object = thread_array.add_object();
|
||||
thread_object.add("tid", thread.tid());
|
||||
thread_object.add("tid", thread.tid().value());
|
||||
thread_object.add("name", thread.name());
|
||||
thread_object.add("times_scheduled", thread.times_scheduled());
|
||||
thread_object.add("ticks", thread.ticks());
|
||||
@ -1227,7 +1227,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
|
||||
}
|
||||
for (auto pid_child : Process::all_pids()) {
|
||||
char name[16];
|
||||
size_t name_length = (size_t)sprintf(name, "%u", pid_child);
|
||||
size_t name_length = (size_t)sprintf(name, "%d", pid_child.value());
|
||||
callback({ name, name_length, to_identifier(fsid(), PDI_Root, pid_child, FI_PID), 0 });
|
||||
}
|
||||
break;
|
||||
@ -1270,7 +1270,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
|
||||
if (!description)
|
||||
continue;
|
||||
char name[16];
|
||||
size_t name_length = (size_t)sprintf(name, "%u", i);
|
||||
size_t name_length = (size_t)sprintf(name, "%d", i);
|
||||
callback({ name, name_length, to_identifier_with_fd(fsid(), pid, i), 0 });
|
||||
}
|
||||
} break;
|
||||
|
@ -56,7 +56,7 @@ Socket::Socket(int domain, int type, int protocol)
|
||||
, m_protocol(protocol)
|
||||
{
|
||||
auto& process = *Process::current();
|
||||
m_origin = { process.pid(), process.uid(), process.gid() };
|
||||
m_origin = { process.pid().value(), process.uid(), process.gid() };
|
||||
}
|
||||
|
||||
Socket::~Socket()
|
||||
@ -83,7 +83,7 @@ RefPtr<Socket> Socket::accept()
|
||||
auto client = m_pending.take_first();
|
||||
ASSERT(!client->is_connected());
|
||||
auto& process = *Process::current();
|
||||
client->m_acceptor = { process.pid(), process.uid(), process.gid() };
|
||||
client->m_acceptor = { process.pid().value(), process.uid(), process.gid() };
|
||||
client->m_connected = true;
|
||||
client->m_role = Role::Accepted;
|
||||
return client;
|
||||
|
@ -94,12 +94,12 @@ PerformanceEvent& PerformanceEventBuffer::at(size_t index)
|
||||
return events[index];
|
||||
}
|
||||
|
||||
KBuffer PerformanceEventBuffer::to_json(pid_t pid, const String& executable_path) const
|
||||
KBuffer PerformanceEventBuffer::to_json(ProcessID pid, const String& executable_path) const
|
||||
{
|
||||
KBufferBuilder builder;
|
||||
|
||||
JsonObjectSerializer object(builder);
|
||||
object.add("pid", pid);
|
||||
object.add("pid", pid.value());
|
||||
object.add("executable", executable_path);
|
||||
|
||||
auto array = object.add_array("events");
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
return const_cast<PerformanceEventBuffer&>(*this).at(index);
|
||||
}
|
||||
|
||||
KBuffer to_json(pid_t, const String& executable_path) const;
|
||||
KBuffer to_json(ProcessID, const String& executable_path) const;
|
||||
|
||||
private:
|
||||
PerformanceEvent& at(size_t index);
|
||||
|
@ -95,8 +95,12 @@ Lock* g_hostname_lock;
|
||||
VirtualAddress g_return_to_ring3_from_signal_trampoline;
|
||||
HashMap<String, OwnPtr<Module>>* g_modules;
|
||||
|
||||
pid_t Process::allocate_pid()
|
||||
ProcessID Process::allocate_pid()
|
||||
{
|
||||
// Overflow is UB, and negative PIDs wreck havoc.
|
||||
// TODO: Handle PID overflow
|
||||
// For example: Use an Atomic<u32>, mask the most significant bit,
|
||||
// retry if PID is already taken as a PID, taken as a TID, or zero.
|
||||
return next_pid.fetch_add(1, AK::MemoryOrder::memory_order_acq_rel);
|
||||
}
|
||||
|
||||
@ -112,9 +116,9 @@ void Process::initialize()
|
||||
create_signal_trampolines();
|
||||
}
|
||||
|
||||
Vector<pid_t> Process::all_pids()
|
||||
Vector<ProcessID> Process::all_pids()
|
||||
{
|
||||
Vector<pid_t> pids;
|
||||
Vector<ProcessID> pids;
|
||||
ScopedSpinLock lock(g_processes_lock);
|
||||
pids.ensure_capacity((int)g_processes->size_slow());
|
||||
for (auto& process : *g_processes)
|
||||
@ -286,7 +290,7 @@ void Process::kill_all_threads()
|
||||
});
|
||||
}
|
||||
|
||||
RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String& path, uid_t uid, gid_t gid, pid_t parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty)
|
||||
RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String& path, uid_t uid, gid_t gid, ProcessID parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty)
|
||||
{
|
||||
auto parts = path.split('/');
|
||||
if (arguments.is_empty()) {
|
||||
@ -334,7 +338,7 @@ RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String
|
||||
|
||||
NonnullRefPtr<Process> Process::create_kernel_process(Thread*& first_thread, String&& name, void (*e)(), u32 affinity)
|
||||
{
|
||||
auto process = adopt(*new Process(first_thread, move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0));
|
||||
auto process = adopt(*new Process(first_thread, move(name), (uid_t)0, (gid_t)0, ProcessID(0), Ring0));
|
||||
first_thread->tss().eip = (FlatPtr)e;
|
||||
|
||||
if (process->pid() != 0) {
|
||||
@ -348,7 +352,7 @@ NonnullRefPtr<Process> Process::create_kernel_process(Thread*& first_thread, Str
|
||||
return process;
|
||||
}
|
||||
|
||||
Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
|
||||
Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid, ProcessID ppid, RingLevel ring, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
|
||||
: m_name(move(name))
|
||||
, m_pid(allocate_pid())
|
||||
, m_euid(uid)
|
||||
@ -473,10 +477,11 @@ void Process::crash(int signal, u32 eip, bool out_of_memory)
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
RefPtr<Process> Process::from_pid(pid_t pid)
|
||||
RefPtr<Process> Process::from_pid(ProcessID pid)
|
||||
{
|
||||
ScopedSpinLock lock(g_processes_lock);
|
||||
for (auto& process : *g_processes) {
|
||||
process.pid();
|
||||
if (process.pid() == pid)
|
||||
return &process;
|
||||
}
|
||||
@ -553,7 +558,7 @@ siginfo_t Process::reap(Process& process)
|
||||
siginfo_t siginfo;
|
||||
memset(&siginfo, 0, sizeof(siginfo));
|
||||
siginfo.si_signo = SIGCHLD;
|
||||
siginfo.si_pid = process.pid();
|
||||
siginfo.si_pid = process.pid().value();
|
||||
siginfo.si_uid = process.uid();
|
||||
|
||||
if (process.m_termination_signal) {
|
||||
@ -566,7 +571,7 @@ siginfo_t Process::reap(Process& process)
|
||||
|
||||
ASSERT(g_processes_lock.is_locked());
|
||||
|
||||
if (process.ppid()) {
|
||||
if (!!process.ppid()) {
|
||||
auto parent = Process::from_pid(process.ppid());
|
||||
if (parent) {
|
||||
parent->m_ticks_in_user_for_dead_children += process.m_ticks_in_user + process.m_ticks_in_user_for_dead_children;
|
||||
@ -654,7 +659,8 @@ void Process::finalize()
|
||||
disown_all_shared_buffers();
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
if (auto* parent_thread = Thread::from_tid(m_ppid)) {
|
||||
// FIXME: PID/TID BUG
|
||||
if (auto* parent_thread = Thread::from_tid(m_ppid.value())) {
|
||||
if (parent_thread->m_signal_action_data[SIGCHLD].flags & SA_NOCLDWAIT) {
|
||||
// NOTE: If the parent doesn't care about this process, let it go.
|
||||
m_ppid = 0;
|
||||
@ -783,7 +789,8 @@ void Process::terminate_due_to_signal(u8 signal)
|
||||
KResult Process::send_signal(u8 signal, Process* sender)
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
if (auto* thread = Thread::from_tid(m_pid)) {
|
||||
// FIXME: PID/TID BUG
|
||||
if (auto* thread = Thread::from_tid(m_pid.value())) {
|
||||
thread->send_signal(signal, sender);
|
||||
return KSuccess;
|
||||
}
|
||||
|
@ -126,10 +126,10 @@ public:
|
||||
}
|
||||
|
||||
static NonnullRefPtr<Process> create_kernel_process(Thread*& first_thread, String&& name, void (*entry)(), u32 affinity = THREAD_AFFINITY_DEFAULT);
|
||||
static RefPtr<Process> create_user_process(Thread*& first_thread, const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
|
||||
static RefPtr<Process> create_user_process(Thread*& first_thread, const String& path, uid_t, gid_t, ProcessID ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
|
||||
~Process();
|
||||
|
||||
static Vector<pid_t> all_pids();
|
||||
static Vector<ProcessID> all_pids();
|
||||
static AK::NonnullRefPtrVector<Process> all_processes();
|
||||
|
||||
Thread* create_kernel_thread(void (*entry)(), u32 priority, const String& name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true);
|
||||
@ -152,10 +152,10 @@ public:
|
||||
PageDirectory& page_directory() { return *m_page_directory; }
|
||||
const PageDirectory& page_directory() const { return *m_page_directory; }
|
||||
|
||||
static RefPtr<Process> from_pid(pid_t);
|
||||
static RefPtr<Process> from_pid(ProcessID);
|
||||
|
||||
const String& name() const { return m_name; }
|
||||
pid_t pid() const { return m_pid; }
|
||||
ProcessID pid() const { return m_pid; }
|
||||
pid_t sid() const { return m_sid; }
|
||||
pid_t pgid() const { return m_pgid; }
|
||||
const FixedArray<gid_t>& extra_gids() const { return m_extra_gids; }
|
||||
@ -165,9 +165,9 @@ public:
|
||||
gid_t gid() const { return m_gid; }
|
||||
uid_t suid() const { return m_suid; }
|
||||
gid_t sgid() const { return m_sgid; }
|
||||
pid_t ppid() const { return m_ppid; }
|
||||
ProcessID ppid() const { return m_ppid; }
|
||||
|
||||
pid_t exec_tid() const { return m_exec_tid; }
|
||||
ThreadID exec_tid() const { return m_exec_tid; }
|
||||
|
||||
mode_t umask() const { return m_umask; }
|
||||
|
||||
@ -224,7 +224,7 @@ public:
|
||||
int sys$fstat(int fd, stat*);
|
||||
int sys$stat(Userspace<const Syscall::SC_stat_params*>);
|
||||
int sys$lseek(int fd, off_t, int whence);
|
||||
int sys$kill(pid_t pid, int sig);
|
||||
int sys$kill(pid_t pid_or_pgid, int sig);
|
||||
[[noreturn]] void sys$exit(int status);
|
||||
int sys$sigreturn(RegisterState& registers);
|
||||
pid_t sys$waitid(Userspace<const Syscall::SC_waitid_params*>);
|
||||
@ -263,7 +263,7 @@ public:
|
||||
int sys$getgroups(ssize_t, gid_t*);
|
||||
int sys$setgroups(ssize_t, const gid_t*);
|
||||
int sys$pipe(int pipefd[2], int flags);
|
||||
int sys$killpg(int pgrp, int sig);
|
||||
int sys$killpg(pid_t pgrp, int sig);
|
||||
int sys$seteuid(uid_t);
|
||||
int sys$setegid(gid_t);
|
||||
int sys$setuid(uid_t);
|
||||
@ -338,7 +338,7 @@ public:
|
||||
int sys$sendfd(int sockfd, int fd);
|
||||
int sys$recvfd(int sockfd);
|
||||
long sys$sysconf(int name);
|
||||
int sys$disown(pid_t);
|
||||
int sys$disown(ProcessID);
|
||||
|
||||
template<bool sockname, typename Params>
|
||||
int get_sock_or_peer_name(const Params&);
|
||||
@ -574,8 +574,8 @@ private:
|
||||
friend class Scheduler;
|
||||
friend class Region;
|
||||
|
||||
Process(Thread*& first_thread, const String& name, uid_t, gid_t, pid_t ppid, RingLevel, RefPtr<Custody> cwd = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
|
||||
static pid_t allocate_pid();
|
||||
Process(Thread*& first_thread, const String& name, uid_t, gid_t, ProcessID ppid, RingLevel, RefPtr<Custody> cwd = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
|
||||
static ProcessID allocate_pid();
|
||||
|
||||
Range allocate_range(VirtualAddress, size_t, size_t alignment = PAGE_SIZE);
|
||||
|
||||
@ -607,7 +607,7 @@ private:
|
||||
}
|
||||
KResultOr<String> get_syscall_path_argument(const Syscall::StringArgument&) const;
|
||||
|
||||
bool has_tracee_thread(int tracer_pid) const;
|
||||
bool has_tracee_thread(ProcessID tracer_pid) const;
|
||||
|
||||
RefPtr<PageDirectory> m_page_directory;
|
||||
|
||||
@ -616,7 +616,7 @@ private:
|
||||
|
||||
String m_name;
|
||||
|
||||
pid_t m_pid { 0 };
|
||||
ProcessID m_pid { 0 };
|
||||
pid_t m_sid { 0 };
|
||||
pid_t m_pgid { 0 };
|
||||
|
||||
@ -627,7 +627,7 @@ private:
|
||||
uid_t m_suid { 0 };
|
||||
gid_t m_sgid { 0 };
|
||||
|
||||
pid_t m_exec_tid { 0 };
|
||||
ThreadID m_exec_tid { 0 };
|
||||
FlatPtr m_load_offset { 0U };
|
||||
FlatPtr m_entry_eip { 0U };
|
||||
|
||||
@ -677,7 +677,7 @@ private:
|
||||
};
|
||||
RegionLookupCache m_region_lookup_cache;
|
||||
|
||||
pid_t m_ppid { 0 };
|
||||
ProcessID m_ppid { 0 };
|
||||
mode_t m_umask { 022 };
|
||||
|
||||
FixedArray<gid_t> m_extra_gids;
|
||||
@ -732,11 +732,12 @@ template<typename Callback>
|
||||
inline void Process::for_each_child(Callback callback)
|
||||
{
|
||||
ASSERT_INTERRUPTS_DISABLED();
|
||||
pid_t my_pid = pid();
|
||||
ProcessID my_pid = pid();
|
||||
ScopedSpinLock lock(g_processes_lock);
|
||||
for (auto* process = g_processes->head(); process;) {
|
||||
auto* next_process = process->next();
|
||||
if (process->ppid() == my_pid || process->has_tracee_thread(m_pid)) {
|
||||
// FIXME: PID/TID BUG
|
||||
if (process->ppid() == my_pid || process->has_tracee_thread(m_pid.value())) {
|
||||
if (callback(*process) == IterationDecision::Break)
|
||||
break;
|
||||
}
|
||||
@ -748,7 +749,7 @@ template<typename Callback>
|
||||
inline void Process::for_each_thread(Callback callback) const
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
pid_t my_pid = pid();
|
||||
ProcessID my_pid = pid();
|
||||
|
||||
if (my_pid == 0) {
|
||||
// NOTE: Special case the colonel process, since its main thread is not in the global thread table.
|
||||
@ -800,14 +801,14 @@ inline bool InodeMetadata::may_execute(const Process& process) const
|
||||
return may_execute(process.euid(), process.egid(), process.extra_gids());
|
||||
}
|
||||
|
||||
inline int Thread::pid() const
|
||||
inline ProcessID Thread::pid() const
|
||||
{
|
||||
return m_process->pid();
|
||||
}
|
||||
|
||||
inline const LogStream& operator<<(const LogStream& stream, const Process& process)
|
||||
{
|
||||
return stream << process.name() << '(' << process.pid() << ')';
|
||||
return stream << process.name() << '(' << process.pid().value() << ')';
|
||||
}
|
||||
|
||||
inline u32 Thread::effective_priority() const
|
||||
|
@ -61,7 +61,7 @@ void start(Process& process)
|
||||
executable_path() = process.executable()->absolute_path().impl();
|
||||
else
|
||||
executable_path() = {};
|
||||
s_pid = process.pid();
|
||||
s_pid = process.pid().value(); // FIXME: PID/TID INCOMPLETE
|
||||
|
||||
if (!s_profiling_buffer) {
|
||||
s_profiling_buffer = RefPtr<KBufferImpl>(KBuffer::create_with_size(8 * MB).impl()).leak_ref();
|
||||
|
@ -43,7 +43,7 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
if (params.pid == caller.pid())
|
||||
if (params.pid == caller.pid().value())
|
||||
return KResult(-EINVAL);
|
||||
|
||||
Thread* peer = nullptr;
|
||||
|
@ -136,7 +136,7 @@ Thread::WriteBlocker::WriteBlocker(const FileDescription& description)
|
||||
|
||||
timespec* Thread::WriteBlocker::override_timeout(timespec* timeout)
|
||||
{
|
||||
auto& description = blocked_description();
|
||||
auto& description = blocked_description();
|
||||
if (description.is_socket()) {
|
||||
auto& socket = *description.socket();
|
||||
if (socket.has_send_timeout()) {
|
||||
@ -227,7 +227,7 @@ bool Thread::SelectBlocker::should_unblock(Thread& thread)
|
||||
return false;
|
||||
}
|
||||
|
||||
Thread::WaitBlocker::WaitBlocker(int wait_options, pid_t& waitee_pid)
|
||||
Thread::WaitBlocker::WaitBlocker(int wait_options, ProcessID& waitee_pid)
|
||||
: m_wait_options(wait_options)
|
||||
, m_waitee_pid(waitee_pid)
|
||||
{
|
||||
@ -296,8 +296,7 @@ void Thread::consider_unblock(time_t now_sec, long now_usec)
|
||||
case Thread::Dying:
|
||||
/* don't know, don't care */
|
||||
return;
|
||||
case Thread::Blocked:
|
||||
{
|
||||
case Thread::Blocked: {
|
||||
ASSERT(m_blocker != nullptr);
|
||||
timespec now;
|
||||
now.tv_sec = now_sec,
|
||||
@ -378,7 +377,7 @@ bool Scheduler::pick_next()
|
||||
auto name = process.name();
|
||||
auto pid = process.pid();
|
||||
auto exit_status = Process::reap(process);
|
||||
dbg() << "Scheduler[" << Processor::current().id() << "]: Reaped unparented process " << name << "(" << pid << "), exit status: " << exit_status.si_status;
|
||||
dbg() << "Scheduler[" << Processor::current().id() << "]: Reaped unparented process " << name << "(" << pid.value() << "), exit status: " << exit_status.si_status;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
}
|
||||
@ -496,7 +495,7 @@ bool Scheduler::yield()
|
||||
bool Scheduler::donate_to(Thread* beneficiary, const char* reason)
|
||||
{
|
||||
ASSERT(beneficiary);
|
||||
|
||||
|
||||
// Set the m_in_scheduler flag before acquiring the spinlock. This
|
||||
// prevents a recursive call into Scheduler::invoke_async upon
|
||||
// leaving the scheduler lock.
|
||||
@ -685,8 +684,9 @@ void Scheduler::timer_tick(const RegisterState& regs)
|
||||
SmapDisabler disabler;
|
||||
auto backtrace = current_thread->raw_backtrace(regs.ebp, regs.eip);
|
||||
auto& sample = Profiling::next_sample_slot();
|
||||
sample.pid = current_thread->process().pid();
|
||||
sample.tid = current_thread->tid();
|
||||
// FIXME: PID/TID INCOMPLETE
|
||||
sample.pid = current_thread->process().pid().value();
|
||||
sample.tid = current_thread->tid().value();
|
||||
sample.timestamp = g_uptime;
|
||||
for (size_t i = 0; i < min(backtrace.size(), Profiling::max_stack_frame_count); ++i) {
|
||||
sample.frames[i] = backtrace[i];
|
||||
|
@ -48,13 +48,13 @@ void SharedBuffer::sanity_check(const char* what)
|
||||
if (found_refs != m_total_refs) {
|
||||
dbg() << what << " sanity -- SharedBuffer{" << this << "} id: " << m_shbuf_id << " has total refs " << m_total_refs << " but we found " << found_refs;
|
||||
for (const auto& ref : m_refs) {
|
||||
dbg() << " ref from pid " << ref.pid << ": refcnt " << ref.count;
|
||||
dbg() << " ref from pid " << ref.pid.value() << ": refcnt " << ref.count;
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedBuffer::is_shared_with(pid_t peer_pid) const
|
||||
bool SharedBuffer::is_shared_with(ProcessID peer_pid) const
|
||||
{
|
||||
LOCKER(shared_buffers().lock(), Lock::Mode::Shared);
|
||||
if (m_global)
|
||||
@ -102,7 +102,7 @@ void* SharedBuffer::ref_for_process_and_get_address(Process& process)
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
void SharedBuffer::share_with(pid_t peer_pid)
|
||||
void SharedBuffer::share_with(ProcessID peer_pid)
|
||||
{
|
||||
LOCKER(shared_buffers().lock());
|
||||
if (m_global)
|
||||
@ -146,7 +146,7 @@ void SharedBuffer::deref_for_process(Process& process)
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
void SharedBuffer::disown(pid_t pid)
|
||||
void SharedBuffer::disown(ProcessID pid)
|
||||
{
|
||||
LOCKER(shared_buffers().lock());
|
||||
for (size_t i = 0; i < m_refs.size(); ++i) {
|
||||
|
@ -36,12 +36,12 @@ namespace Kernel {
|
||||
class SharedBuffer {
|
||||
private:
|
||||
struct Reference {
|
||||
Reference(pid_t pid)
|
||||
Reference(ProcessID pid)
|
||||
: pid(pid)
|
||||
{
|
||||
}
|
||||
|
||||
pid_t pid;
|
||||
ProcessID pid;
|
||||
unsigned count { 0 };
|
||||
WeakPtr<Region> region;
|
||||
};
|
||||
@ -64,12 +64,12 @@ public:
|
||||
}
|
||||
|
||||
void sanity_check(const char* what);
|
||||
bool is_shared_with(pid_t peer_pid) const;
|
||||
bool is_shared_with(ProcessID peer_pid) const;
|
||||
void* ref_for_process_and_get_address(Process& process);
|
||||
void share_with(pid_t peer_pid);
|
||||
void share_with(ProcessID peer_pid);
|
||||
void share_globally() { m_global = true; }
|
||||
void deref_for_process(Process& process);
|
||||
void disown(pid_t pid);
|
||||
void disown(ProcessID pid);
|
||||
size_t size() const { return m_vmobject->size(); }
|
||||
void destroy_if_unused();
|
||||
void seal();
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
int Process::sys$disown(pid_t pid)
|
||||
int Process::sys$disown(ProcessID pid)
|
||||
{
|
||||
REQUIRE_PROMISE(proc);
|
||||
auto process = Process::from_pid(pid);
|
||||
|
@ -282,7 +282,8 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
|
||||
m_master_tls_size = master_tls_size;
|
||||
m_master_tls_alignment = master_tls_alignment;
|
||||
|
||||
m_pid = new_main_thread->tid();
|
||||
// FIXME: PID/TID BUG
|
||||
m_pid = new_main_thread->tid().value();
|
||||
new_main_thread->make_thread_specific_region({});
|
||||
new_main_thread->reset_fpu_state();
|
||||
|
||||
@ -296,7 +297,7 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
|
||||
tss.eip = m_entry_eip;
|
||||
tss.esp = new_userspace_esp;
|
||||
tss.cr3 = m_page_directory->cr3();
|
||||
tss.ss2 = m_pid;
|
||||
tss.ss2 = m_pid.value();
|
||||
|
||||
if (was_profiling)
|
||||
Profiling::did_exec(path);
|
||||
|
@ -95,7 +95,7 @@ pid_t Process::sys$fork(RegisterState& regs)
|
||||
}
|
||||
|
||||
child_first_thread->set_state(Thread::State::Skip1SchedulerPass);
|
||||
return child->pid();
|
||||
return child->pid().value();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ KResult Process::do_kill(Process& process, int signal)
|
||||
if (!is_superuser() && m_euid != process.m_uid && m_uid != process.m_uid)
|
||||
return KResult(-EPERM);
|
||||
if (process.is_ring0() && signal == SIGKILL) {
|
||||
klog() << "attempted to send SIGKILL to ring 0 process " << process.name().characters() << "(" << process.pid() << ")";
|
||||
klog() << "attempted to send SIGKILL to ring 0 process " << process.name().characters() << "(" << process.pid().value() << ")";
|
||||
return KResult(-EPERM);
|
||||
}
|
||||
if (signal != 0)
|
||||
@ -119,33 +119,34 @@ KResult Process::do_killself(int signal)
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
int Process::sys$kill(pid_t pid, int signal)
|
||||
int Process::sys$kill(pid_t pid_or_pgid, int signal)
|
||||
{
|
||||
if (pid == m_pid)
|
||||
if (pid_or_pgid == m_pid.value())
|
||||
REQUIRE_PROMISE(stdio);
|
||||
else
|
||||
REQUIRE_PROMISE(proc);
|
||||
|
||||
if (signal < 0 || signal >= 32)
|
||||
return -EINVAL;
|
||||
if (pid < -1) {
|
||||
if (pid == NumericLimits<i32>::min())
|
||||
if (pid_or_pgid < -1) {
|
||||
if (pid_or_pgid == NumericLimits<i32>::min())
|
||||
return -EINVAL;
|
||||
return do_killpg(-pid, signal);
|
||||
return do_killpg(-pid_or_pgid, signal);
|
||||
}
|
||||
if (pid == -1)
|
||||
if (pid_or_pgid == -1)
|
||||
return do_killall(signal);
|
||||
if (pid == m_pid) {
|
||||
if (pid_or_pgid == m_pid.value()) {
|
||||
return do_killself(signal);
|
||||
}
|
||||
ASSERT(pid_or_pgid >= 0);
|
||||
ScopedSpinLock lock(g_processes_lock);
|
||||
auto peer = Process::from_pid(pid);
|
||||
auto peer = Process::from_pid(pid_or_pgid);
|
||||
if (!peer)
|
||||
return -ESRCH;
|
||||
return do_kill(*peer, signal);
|
||||
}
|
||||
|
||||
int Process::sys$killpg(int pgrp, int signum)
|
||||
int Process::sys$killpg(pid_t pgrp, int signum)
|
||||
{
|
||||
REQUIRE_PROMISE(proc);
|
||||
if (signum < 1 || signum >= 32)
|
||||
|
@ -32,13 +32,13 @@ namespace Kernel {
|
||||
pid_t Process::sys$getpid()
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
return m_pid;
|
||||
return m_pid.value();
|
||||
}
|
||||
|
||||
pid_t Process::sys$getppid()
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
return m_ppid;
|
||||
return m_ppid.value();
|
||||
}
|
||||
|
||||
int Process::sys$set_process_icon(int icon_id)
|
||||
|
@ -44,7 +44,10 @@ int Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params*> user_params)
|
||||
return result.is_error() ? result.error() : result.value();
|
||||
}
|
||||
|
||||
bool Process::has_tracee_thread(int tracer_pid) const
|
||||
/**
|
||||
* "Does this process have a thread that is currently being traced by the provided process?"
|
||||
*/
|
||||
bool Process::has_tracee_thread(ProcessID tracer_pid) const
|
||||
{
|
||||
bool has_tracee = false;
|
||||
|
||||
|
@ -48,14 +48,15 @@ pid_t Process::sys$setsid()
|
||||
REQUIRE_PROMISE(proc);
|
||||
InterruptDisabler disabler;
|
||||
bool found_process_with_same_pgid_as_my_pid = false;
|
||||
Process::for_each_in_pgrp(pid(), [&](auto&) {
|
||||
// FIXME: PID/PGID ISSUE?
|
||||
Process::for_each_in_pgrp(pid().value(), [&](auto&) {
|
||||
found_process_with_same_pgid_as_my_pid = true;
|
||||
return IterationDecision::Break;
|
||||
});
|
||||
if (found_process_with_same_pgid_as_my_pid)
|
||||
return -EPERM;
|
||||
m_sid = m_pid;
|
||||
m_pgid = m_pid;
|
||||
m_sid = m_pid.value();
|
||||
m_pgid = m_pid.value();
|
||||
m_tty = nullptr;
|
||||
return m_sid;
|
||||
}
|
||||
@ -91,7 +92,7 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
||||
{
|
||||
REQUIRE_PROMISE(proc);
|
||||
ScopedSpinLock lock(g_processes_lock); // FIXME: Use a ProcessHandle
|
||||
pid_t pid = specified_pid ? specified_pid : m_pid;
|
||||
ProcessID pid = specified_pid ? ProcessID(specified_pid) : m_pid;
|
||||
if (specified_pgid < 0) {
|
||||
// The value of the pgid argument is less than 0, or is not a value supported by the implementation.
|
||||
return -EINVAL;
|
||||
@ -115,7 +116,8 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid;
|
||||
// FIXME: PID/PGID INCOMPLETE
|
||||
pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid.value();
|
||||
pid_t current_sid = get_sid_from_pgid(process->m_pgid);
|
||||
pid_t new_sid = get_sid_from_pgid(new_pgid);
|
||||
if (current_sid != new_sid) {
|
||||
|
@ -70,7 +70,7 @@ int Process::sys$shbuf_create(int size, void** buffer)
|
||||
int Process::sys$shbuf_allow_pid(int shbuf_id, pid_t peer_pid)
|
||||
{
|
||||
REQUIRE_PROMISE(shared_buffer);
|
||||
if (!peer_pid || peer_pid < 0 || peer_pid == m_pid)
|
||||
if (!peer_pid || peer_pid < 0 || ProcessID(peer_pid) == m_pid)
|
||||
return -EINVAL;
|
||||
LOCKER(shared_buffers().lock());
|
||||
auto it = shared_buffers().resource().find(shbuf_id);
|
||||
|
@ -87,7 +87,7 @@ int Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::S
|
||||
|
||||
thread->make_thread_specific_region({});
|
||||
thread->set_state(Thread::State::Runnable);
|
||||
return thread->tid();
|
||||
return thread->tid().value();
|
||||
}
|
||||
|
||||
void Process::sys$exit_thread(void* exit_value)
|
||||
@ -212,7 +212,7 @@ int Process::sys$get_thread_name(int tid, char* buffer, size_t buffer_size)
|
||||
int Process::sys$gettid()
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
return Thread::current()->tid();
|
||||
return Thread::current()->tid().value();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,9 +34,12 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
|
||||
ScopedSpinLock lock(g_processes_lock);
|
||||
if (idtype == P_PID && !Process::from_pid(id))
|
||||
return KResult(-ECHILD);
|
||||
// FIXME: Race: After 'lock' releases, the 'id' process might vanish.
|
||||
// If that is not a problem, why check for it?
|
||||
// If it is a problem, let's fix it! (Eventually.)
|
||||
}
|
||||
|
||||
pid_t waitee_pid;
|
||||
ProcessID waitee_pid { 0 };
|
||||
|
||||
// FIXME: WaitBlocker should support idtype/id specs directly.
|
||||
if (idtype == P_ALL) {
|
||||
@ -62,14 +65,15 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
|
||||
if (waitee_process->is_dead()) {
|
||||
return reap(*waitee_process);
|
||||
} else {
|
||||
auto* waitee_thread = Thread::from_tid(waitee_pid);
|
||||
// FIXME: PID/TID BUG
|
||||
auto* waitee_thread = Thread::from_tid(waitee_pid.value());
|
||||
if (!waitee_thread)
|
||||
return KResult(-ECHILD);
|
||||
ASSERT((options & WNOHANG) || waitee_thread->state() == Thread::State::Stopped);
|
||||
siginfo_t siginfo;
|
||||
memset(&siginfo, 0, sizeof(siginfo));
|
||||
siginfo.si_signo = SIGCHLD;
|
||||
siginfo.si_pid = waitee_process->pid();
|
||||
siginfo.si_pid = waitee_process->pid().value();
|
||||
siginfo.si_uid = waitee_process->uid();
|
||||
|
||||
switch (waitee_thread->state()) {
|
||||
|
@ -52,9 +52,10 @@ Thread::Thread(NonnullRefPtr<Process> process)
|
||||
{
|
||||
if (m_process->m_thread_count.fetch_add(1, AK::MemoryOrder::memory_order_acq_rel) == 0) {
|
||||
// First thread gets TID == PID
|
||||
m_tid = m_process->pid();
|
||||
m_tid = m_process->pid().value();
|
||||
} else {
|
||||
m_tid = Process::allocate_pid();
|
||||
// TODO: Use separate counter?
|
||||
m_tid = Process::allocate_pid().value();
|
||||
}
|
||||
#ifdef THREAD_DEBUG
|
||||
dbg() << "Created new thread " << m_process->name() << "(" << m_process->pid() << ":" << m_tid << ")";
|
||||
@ -721,7 +722,6 @@ void Thread::set_state(State new_state)
|
||||
m_wait_queue->dequeue(*this);
|
||||
m_wait_queue = nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (this != Thread::current() && is_finalizable()) {
|
||||
// Some other thread set this thread to Dying, notify the
|
||||
@ -859,7 +859,7 @@ void Thread::make_thread_specific_region(Badge<Process>)
|
||||
|
||||
const LogStream& operator<<(const LogStream& stream, const Thread& value)
|
||||
{
|
||||
return stream << value.process().name() << "(" << value.pid() << ":" << value.tid() << ")";
|
||||
return stream << value.process().name() << "(" << value.pid().value() << ":" << value.tid().value() << ")";
|
||||
}
|
||||
|
||||
Thread::BlockResult Thread::wait_on(WaitQueue& queue, const char* reason, timeval* timeout, Atomic<bool>* lock, Thread* beneficiary)
|
||||
@ -982,7 +982,7 @@ void Thread::reset_fpu_state()
|
||||
memcpy(m_fpu_state, &Processor::current().clean_fpu_state(), sizeof(FPUState));
|
||||
}
|
||||
|
||||
void Thread::start_tracing_from(pid_t tracer)
|
||||
void Thread::start_tracing_from(ProcessID tracer)
|
||||
{
|
||||
m_tracer = ThreadTracer::create(tracer);
|
||||
}
|
||||
|
@ -82,11 +82,11 @@ public:
|
||||
explicit Thread(NonnullRefPtr<Process>);
|
||||
~Thread();
|
||||
|
||||
static Thread* from_tid(int);
|
||||
static Thread* from_tid(pid_t);
|
||||
static void finalize_dying_threads();
|
||||
|
||||
int tid() const { return m_tid; }
|
||||
int pid() const;
|
||||
ThreadID tid() const { return m_tid; }
|
||||
ProcessID pid() const;
|
||||
|
||||
void set_priority(u32 p) { m_priority = p; }
|
||||
u32 priority() const { return m_priority; }
|
||||
@ -236,13 +236,13 @@ public:
|
||||
|
||||
class WaitBlocker final : public Blocker {
|
||||
public:
|
||||
WaitBlocker(int wait_options, pid_t& waitee_pid);
|
||||
WaitBlocker(int wait_options, ProcessID& waitee_pid);
|
||||
virtual bool should_unblock(Thread&) override;
|
||||
virtual const char* state_string() const override { return "Waiting"; }
|
||||
|
||||
private:
|
||||
int m_wait_options { 0 };
|
||||
pid_t& m_waitee_pid;
|
||||
ProcessID& m_waitee_pid;
|
||||
};
|
||||
|
||||
class SemiPermanentBlocker final : public Blocker {
|
||||
@ -512,7 +512,7 @@ public:
|
||||
static constexpr u32 default_userspace_stack_size = 4 * MB;
|
||||
|
||||
ThreadTracer* tracer() { return m_tracer.ptr(); }
|
||||
void start_tracing_from(pid_t tracer);
|
||||
void start_tracing_from(ProcessID tracer);
|
||||
void stop_tracing();
|
||||
void tracer_trap(const RegisterState&);
|
||||
|
||||
@ -533,7 +533,7 @@ private:
|
||||
|
||||
mutable RecursiveSpinLock m_lock;
|
||||
NonnullRefPtr<Process> m_process;
|
||||
int m_tid { -1 };
|
||||
ThreadID m_tid { -1 };
|
||||
TSS32 m_tss;
|
||||
Atomic<u32> m_cpu { 0 };
|
||||
u32 m_cpu_affinity { THREAD_AFFINITY_DEFAULT };
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
ThreadTracer::ThreadTracer(pid_t tracer_pid)
|
||||
ThreadTracer::ThreadTracer(ProcessID tracer_pid)
|
||||
: m_tracer_pid(tracer_pid)
|
||||
{
|
||||
}
|
||||
|
@ -35,9 +35,9 @@ namespace Kernel {
|
||||
|
||||
class ThreadTracer {
|
||||
public:
|
||||
static NonnullOwnPtr<ThreadTracer> create(pid_t tracer) { return make<ThreadTracer>(tracer); }
|
||||
static NonnullOwnPtr<ThreadTracer> create(ProcessID tracer) { return make<ThreadTracer>(tracer); }
|
||||
|
||||
pid_t tracer_pid() const { return m_tracer_pid; }
|
||||
ProcessID tracer_pid() const { return m_tracer_pid; }
|
||||
bool has_pending_signal(u32 signal) const { return m_pending_signals & (1 << (signal - 1)); }
|
||||
void set_signal(u32 signal) { m_pending_signals |= (1 << (signal - 1)); }
|
||||
void unset_signal(u32 signal) { m_pending_signals &= ~(1 << (signal - 1)); }
|
||||
@ -54,10 +54,10 @@ public:
|
||||
return m_regs.value();
|
||||
}
|
||||
|
||||
explicit ThreadTracer(pid_t);
|
||||
explicit ThreadTracer(ProcessID);
|
||||
|
||||
private:
|
||||
pid_t m_tracer_pid { -1 };
|
||||
ProcessID m_tracer_pid { -1 };
|
||||
|
||||
// This is a bitmap for signals that are sent from the tracer to the tracee
|
||||
// TODO: Since we do not currently support sending signals
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/DistinctNumeric.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
#define O_RDONLY (1 << 0)
|
||||
@ -320,6 +321,11 @@ typedef u32 gid_t;
|
||||
typedef u32 clock_t;
|
||||
typedef u32 socklen_t;
|
||||
typedef int pid_t;
|
||||
// Avoid interference with AK/Types.h and LibC/sys/types.h by defining *separate* names:
|
||||
TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ProcessID);
|
||||
TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ThreadID);
|
||||
TYPEDEF_DISTINCT_ORDERED_ID(pid_t, SessionID);
|
||||
TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ProcessGroupID);
|
||||
|
||||
struct tms {
|
||||
clock_t tms_utime;
|
||||
|
Loading…
Reference in New Issue
Block a user