mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
In preparation for the new mailbox IPC model, blocking threads needed an overhaul. The `wait_on_*` and `wake_on_*` methods are gone, and the `block()` and `wake()` calls on threads now pass a value between the waker and the blocked thread. As part of this change, the concept of signals on the base kobject class was removed, along with the queue of blocked threads waiting on any given object. Signals are now exclusively the domain of the event object type, and the new wait_queue utility class helps manage waiting threads when an object does actually need this functionality. In some cases (eg, logger) an event object is used instead of the lower-level wait_queue. Since this change has a lot of ramifications, this large commit includes the following additional changes: - The j6_object_wait, j6_object_wait_many, and j6_thread_pause syscalls have been removed. - The j6_event_clear syscall has been removed - events are "cleared" by reading them now. A new j6_event_wait syscall has been added to read events. - The generic close() method on kobject has been removed. - The on_no_handles() method on kobject now deletes the object by default, and needs to be overridden by classes that should not be. - The j6_system_bind_irq syscall now takes an event handle, as well as a signal that the IRQ should set on the event. IRQs will cause a waiting thread to be woken with the appropriate bit set. - Threads waking due to timeout is simplified to just having a wake_timeout() accessor that returns a timestamp. - The new wait_queue uses util::deque, which caused the disovery of two bugs in the deque implementation: empty deques could still have a single array allocated and thus return true for empty(), and new arrays getting allocated were not being zeroed first. - Exposed a new erase() method on util::map that takes a node pointer instead of a key, skipping lookup.
130 lines
4.0 KiB
C++
130 lines
4.0 KiB
C++
#pragma once
|
|
/// \file process.h
|
|
/// Definition of process kobject types
|
|
|
|
#include <j6/caps.h>
|
|
#include <util/map.h>
|
|
#include <util/vector.h>
|
|
|
|
#include "objects/handle.h"
|
|
#include "objects/kobject.h"
|
|
#include "page_table.h"
|
|
#include "vm_space.h"
|
|
|
|
namespace obj {
|
|
|
|
class process :
|
|
public kobject
|
|
{
|
|
public:
|
|
/// Capabilities on a newly constructed process handle
|
|
constexpr static j6_cap_t creation_caps = j6_cap_process_all;
|
|
|
|
/// Capabilities on a process to itself
|
|
constexpr static j6_cap_t self_caps = j6_cap_process_all;
|
|
|
|
/// Top of memory area where thread stacks are allocated
|
|
constexpr static uintptr_t stacks_top = 0x0000800000000000;
|
|
|
|
/// Size of userspace thread stacks
|
|
constexpr static size_t stack_size = 0x4000000; // 64MiB
|
|
|
|
/// Value that represents default priority
|
|
constexpr static uint8_t default_priority = 0xff;
|
|
|
|
/// Constructor.
|
|
process();
|
|
|
|
/// Destructor.
|
|
virtual ~process();
|
|
|
|
static constexpr kobject::type type = kobject::type::process;
|
|
|
|
/// Get the currently executing process.
|
|
static process & current();
|
|
|
|
/// Terminate this process.
|
|
/// \arg code The return code to exit with.
|
|
void exit(int32_t code);
|
|
|
|
/// Update internal bookkeeping about threads.
|
|
void update();
|
|
|
|
/// Get the process' virtual memory space
|
|
vm_space & space() { return m_space; }
|
|
|
|
/// Create a new thread in this process
|
|
/// \args rsp3 If non-zero, sets the ring3 stack pointer to this value
|
|
/// \args priority The new thread's scheduling priority
|
|
/// \returns The newly created thread object
|
|
thread * create_thread(uintptr_t rsp3 = 0, uint8_t priorty = default_priority);
|
|
|
|
/// Start tracking an object with a handle.
|
|
/// \args obj The object this handle refers to
|
|
/// \args caps The capabilities on this handle
|
|
/// \returns The new handle id for this object
|
|
j6_handle_t add_handle(kobject *obj, j6_cap_t caps);
|
|
|
|
/// Start tracking an object with a handle.
|
|
/// \args hnd An existing handle to copy into this process
|
|
/// \returns The new handle id for this object
|
|
j6_handle_t add_handle(const handle &hnd);
|
|
|
|
/// Stop tracking an object with a handle.
|
|
/// \args handle The handle that refers to the object
|
|
/// \returns True if the handle was removed
|
|
bool remove_handle(j6_handle_t handle);
|
|
|
|
/// Lookup an object for a handle
|
|
/// \args handle The handle to the object
|
|
/// \returns Pointer to the handle struct, or null if not found
|
|
handle * lookup_handle(j6_handle_t handle);
|
|
|
|
/// Get the list of handle ids this process owns
|
|
/// \arg handles Pointer to an array of handles to copy into
|
|
/// \arg len Size of the array
|
|
/// \returns Total number of handles (may be more than number copied)
|
|
size_t list_handles(j6_handle_t *handles, size_t len);
|
|
|
|
/// Inform the process of an exited thread
|
|
/// \args th The thread which has exited
|
|
/// \returns True if this thread ending has ended the process
|
|
bool thread_exited(thread *th);
|
|
|
|
/// Get the handle for this process to refer to itself
|
|
inline j6_handle_t self_handle() const { return m_self_handle; }
|
|
|
|
/// Get the process object that owns kernel threads and the
|
|
/// kernel address space
|
|
static process & kernel_process();
|
|
|
|
/// Create the special kernel process that owns kernel tasks
|
|
/// \arg pml4 The kernel-only pml4
|
|
/// \returns The kernel process object
|
|
static process * create_kernel_process(page_table *pml4);
|
|
|
|
protected:
|
|
/// Don't delete a process on no handles, the scheduler takes
|
|
/// care of that.
|
|
virtual void on_no_handles() override {}
|
|
|
|
private:
|
|
// This constructor is called by create_kernel_process
|
|
process(page_table *kpml4);
|
|
|
|
j6_handle_t m_self_handle;
|
|
int32_t m_return_code;
|
|
|
|
vm_space m_space;
|
|
|
|
util::vector<thread*> m_threads;
|
|
|
|
j6_handle_t m_next_handle;
|
|
util::map<j6_handle_t, handle> m_handles;
|
|
|
|
enum class state : uint8_t { running, exited };
|
|
state m_state;
|
|
};
|
|
|
|
} // namespace obj
|