12#include <abi-bits/wait.h>
48 default:
return "unknown";
58 default:
return "unknown";
64 static std::atomic<pid_t> next = 1;
74 this->
name = name_.
empty() ?
"<unknown>" : name_;
79 dEmph<process> <<
"special process " << (
void *)
this <<
" created";
81 else if (
parent ==
nullptr)
83 mos_panic(
"process %pp has no parent", (
void *)
this);
156 mos_panic(
"failed to create main thread for process %pp", proc);
159 proc->main_thread = thread.get();
188 mos_warn(
"process %pp has too many open files", process);
256 goto find_dead_child;
261 if (!target_proc_opt)
263 pr_warn(
"process %d does not exist", pid);
267 const auto target_proc = *target_proc_opt;
272 if (target_proc->exited)
281 pid = target_proc->pid;
283 *exit_code = target_proc->exit_status;
292 dInfo2<process> <<
"process " << proc <<
" exited with code " << exit_code <<
", signal " << sig;
295 mos_panic(
"init process terminated with code %d, signal %d", exit_code, sig);
297 for (
const auto &t : proc->thread_list)
326 proc->main_thread = t;
327 dInfo2<process> <<
"thread " << t <<
" is current thread, making it main thread";
332 size_t files_total = 0;
333 size_t files_closed = 0;
350 child->parent = proc->parent;
357 dInfo2<process> <<
"closed " << files_closed <<
"/" << files_total <<
" files owned by " << proc;
359 proc->exit_status = W_EXITCODE(exit_code, sig);
367 waitlist_wake(&proc->parent->signal_info.sigchild_waitlist, INT_MAX);
382 pr_info2(
" %3zd: %pvm, %s, %s", i, (
void *) map, typestr, forkmode);
385 mInfo <<
"total: " << i <<
" memory regions";
390 dInfo2<signal> <<
"registering signal handler for process " << process <<
", signal " << sig;
402#define do_print(fmt, name, item) sysfs_printf(f, "%-10s: " fmt "\n", name, item);
429#define stat_line(fmt) " %9s: " fmt "\n"
432 (
void *) &vmap->vmflags,
433 vmap->vmflags &
VM_USER ?
"user" :
"kernel",
434 vmap->vmflags &
VM_GLOBAL ?
" global" :
""
440 const auto name = vmap->io->name();
#define MOS_ASSERT_X(cond, msg,...)
#define MOS_UNREACHABLE()
#define mos_warn(fmt,...)
#define MOS_PROCESS_MAX_OPEN_FILES
constexpr bool empty() const
dentry_t * dentry_ref_up_to(dentry_t *dentry, dentry_t *root)
Increment the reference count of a dentry up to a given dentry.
void dentry_unref(dentry_t *dentry)
Decrement the reference count of a dentry.
long signal_send_to_process(Process *target, signal_t signal)
Send a signal to a process, an arbitrary thread will be chosen to receive the signal.
bool signal_has_pending(void)
Return true if there's a pending signal.
long signal_send_to_thread(Thread *target, signal_t signal)
Send a signal to a thread.
MOSAPI void linked_list_init(list_node_t *head_node)
Initialise a circular double linked list.
MOSAPI void list_node_append(list_node_t *head, list_node_t *item)
#define list_foreach(t, v, h)
Iterate over a list.
#define list_node(element)
Get the ‘list_node’ of a list element. This is exactly the reverse of ‘list_entry’ above.
MOSAPI bool list_is_empty(const list_node_t *head)
#define list_remove(element)
void mm_destroy_context(MMContext *table)
Destroy a user-mode platform-dependent page table.
MMContext * mm_create_context(void)
Create a user-mode platform-dependent page table.
void vmap_destroy(vmap_t *vmap)
Destroy a vmap object, and unmmap the region.
#define PROCESS_MAGIC_PROC
basic_string_view< char > string_view
#define mos_panic(fmt,...)
static void * memset(void *s, int c, size_t n)
#define pr_info2(fmt,...)
pid_t process_wait_for_pid(pid_t pid, u32 *exit_code, u32 flags)
void process_destroy(Process *proc)
static sysfs_item_t process_sysfs_items[]
IO * process_get_fd(Process *process, fd_t fd)
#define do_print(fmt, name, item)
Process * process_new(Process *parent, mos::string_view name, const stdio_t *ios)
const char * get_vmap_type_str(vmap_type_t type)
static bool process_sysfs_thread_stat(sysfs_file_t *f)
void process_dump_mmaps(const Process *proc)
static bool process_sysfs_process_stat(sysfs_file_t *f)
static pid_t new_process_id(void)
bool process_register_signal_handler(Process *process, signal_t sig, const sigaction_t *sigaction)
static bool process_sysfs_vmap_stat(sysfs_file_t *f)
void process_exit(Process *&&proc, u8 exit_code, signal_t sig)
std::optional< Process * > process_get(pid_t pid)
fd_t process_attach_ref_fd(Process *process, IO *file, FDFlags flags)
bool process_detach_fd(Process *process, fd_t fd)
const char * get_vmap_content_str(vmap_content_t content)
mos::HashMap< pid_t, Process * > ProcessTable
__nodiscard bool reschedule_for_waitlist(waitlist_t *waitlist)
#define spinlock_acquire(lock)
#define spinlock_release(lock)
static bool IsValid(const IO *io)
spinlock_t mm_lock
protects [pgd] and the [mmaps] list (the list itself, not the vmap_t objects)
static Process * New(Process *parent, mos::string_view name)
process_signal_info_t signal_info
signal handling info
dentry_t * working_directory
static bool IsValid(const Process *process)
Process(Private, Process *parent, mos::string_view name)
list_head children
list of children processes
fd_type files[MOS_PROCESS_MAX_OPEN_FILES]
spinlock_t state_lock
protects the thread state
sigaction_t handlers[SIGNAL_MAX_N]
signal handlers
A wrapper type for the standard I/O streams.
ssize_t sysfs_printf(sysfs_file_t *file, const char *fmt,...)
#define SYSFS_RO_ITEM(_name, _show_fn)
#define SYSFS_AUTOREGISTER(sysfs_name, sysfs_items)
void thread_destroy(Thread *thread)
mos::HashMap< tid_t, Thread * > thread_table
bool thread_wait_for_tid(tid_t tid)
PtrResult< Thread > thread_new(Process *owner, thread_mode mode, mos::string_view name, size_t stack_size, void *stack)
void thread_exit_locked(Thread *&&t)
void waitlist_init(waitlist_t *list)
size_t waitlist_wake(waitlist_t *list, size_t max_wakeups)
void waitlist_remove_me(waitlist_t *waitlist)