diff --git a/src/drivers/nulldrv/main.cpp b/src/drivers/nulldrv/main.cpp index e7abda6..d778bbe 100644 --- a/src/drivers/nulldrv/main.cpp +++ b/src/drivers/nulldrv/main.cpp @@ -131,7 +131,7 @@ main(int argc, const char **argv) _syscall_system_log("main thread closing endpoint"); - result = _syscall_endpoint_close(endp); + result = _syscall_object_close(endp); if (result != j6_status_ok) return result; diff --git a/src/include/j6/signals.h b/src/include/j6/signals.h index 9e5aa51..8eff049 100644 --- a/src/include/j6/signals.h +++ b/src/include/j6/signals.h @@ -4,24 +4,21 @@ // Signals 0-15 are common to all types #define j6_signal_no_handles (1ull << 0) +#define j6_signal_closed (1ull << 1) // Signals 16-47 are defined per-object-type // Process signals -#define j6_signal_process_exit (1ull << 16) // Thread signals -#define j6_signal_thread_exit (1ull << 16) // Channel signals -#define j6_signal_channel_closed (1ull << 16) -#define j6_signal_channel_can_send (1ull << 17) -#define j6_signal_channel_can_recv (1ull << 18) +#define j6_signal_channel_can_send (1ull << 16) +#define j6_signal_channel_can_recv (1ull << 17) // Endpoint signals -#define j6_signal_endpoint_closed (1ull << 16) -#define j6_signal_endpoint_can_send (1ull << 17) -#define j6_signal_endpoint_can_recv (1ull << 18) +#define j6_signal_endpoint_can_send (1ull << 16) +#define j6_signal_endpoint_can_recv (1ull << 17) // Signals 48-63 are user-defined signals #define j6_signal_user0 (1ull << 48) diff --git a/src/include/syscalls.inc b/src/include/syscalls.inc index b2a94b2..d483835 100644 --- a/src/include/syscalls.inc +++ b/src/include/syscalls.inc @@ -1,33 +1,30 @@ SYSCALL(0x00, system_log, const char *) SYSCALL(0x01, system_noop, void) +SYSCALL(0x08, object_koid, j6_handle_t, j6_koid_t *) SYSCALL(0x09, object_wait, j6_handle_t, j6_signal_t, j6_signal_t *) SYSCALL(0x0a, object_signal, j6_handle_t, j6_signal_t) +SYSCALL(0x0b, object_close, j6_handle_t) -SYSCALL(0x10, process_koid, j6_koid_t *) -SYSCALL(0x11, process_exit, int64_t) +SYSCALL(0x10, process_exit, int64_t) -SYSCALL(0x18, thread_koid, j6_koid_t *) -SYSCALL(0x19, thread_create, void *, j6_handle_t *) -SYSCALL(0x1a, thread_exit, int64_t) -SYSCALL(0x1b, thread_pause, void) -SYSCALL(0x1c, thread_sleep, uint64_t) +SYSCALL(0x18, thread_create, void *, j6_handle_t *) +SYSCALL(0x19, thread_exit, int64_t) +SYSCALL(0x1a, thread_pause, void) +SYSCALL(0x1b, thread_sleep, uint64_t) SYSCALL(0x20, channel_create, j6_handle_t *) -SYSCALL(0x21, channel_close, j6_handle_t) -SYSCALL(0x22, channel_send, j6_handle_t, size_t *, void *) -SYSCALL(0x23, channel_receive, j6_handle_t, size_t *, void *) +SYSCALL(0x21, channel_send, j6_handle_t, size_t *, void *) +SYSCALL(0x22, channel_receive, j6_handle_t, size_t *, void *) SYSCALL(0x28, endpoint_create, j6_handle_t *) -SYSCALL(0x29, endpoint_close, j6_handle_t) -SYSCALL(0x2a, endpoint_send, j6_handle_t, j6_tag_t, size_t, void *) -SYSCALL(0x2b, endpoint_receive, j6_handle_t, j6_tag_t *, size_t *, void *) -SYSCALL(0x2c, endpoint_sendrecv, j6_handle_t, j6_tag_t *, size_t *, void *) -SYSCALL(0x2d, endpoint_bind_irq, j6_handle_t, unsigned) +SYSCALL(0x29, endpoint_send, j6_handle_t, j6_tag_t, size_t, void *) +SYSCALL(0x2a, endpoint_receive, j6_handle_t, j6_tag_t *, size_t *, void *) +SYSCALL(0x2b, endpoint_sendrecv, j6_handle_t, j6_tag_t *, size_t *, void *) +SYSCALL(0x2c, endpoint_bind_irq, j6_handle_t, unsigned) SYSCALL(0x30, vma_create, j6_handle_t *, size_t, uint32_t) SYSCALL(0x31, vma_create_map, j6_handle_t *, size_t, uintptr_t, uint32_t) -SYSCALL(0x32, vma_close, j6_handle_t) -SYSCALL(0x33, vma_map, j6_handle_t, uintptr_t) -SYSCALL(0x34, vma_unmap, j6_handle_t) +SYSCALL(0x32, vma_map, j6_handle_t, uintptr_t) +SYSCALL(0x33, vma_unmap, j6_handle_t) SYSCALL(0x34, vma_resize, j6_handle_t, size_t *) diff --git a/src/kernel/objects/channel.cpp b/src/kernel/objects/channel.cpp index de34cf9..5f4fbdc 100644 --- a/src/kernel/objects/channel.cpp +++ b/src/kernel/objects/channel.cpp @@ -78,8 +78,8 @@ channel::dequeue(size_t *len, void *data) void channel::close() { + kobject::close(); g_kernel_buffers.return_buffer(m_data); - assert_signal(j6_signal_channel_closed); } void diff --git a/src/kernel/objects/channel.h b/src/kernel/objects/channel.h index 26d3529..5ce949f 100644 --- a/src/kernel/objects/channel.h +++ b/src/kernel/objects/channel.h @@ -37,10 +37,7 @@ public: /// Mark this channel as closed, all future calls to enqueue or /// dequeue messages will fail with j6_status_closed. - void close(); - - /// Check if this channel has been closed - inline bool closed() { return check_signal(j6_signal_channel_closed); } + virtual void close() override; protected: virtual void on_no_handles() override; diff --git a/src/kernel/objects/endpoint.cpp b/src/kernel/objects/endpoint.cpp index c3ac58f..bb232a9 100644 --- a/src/kernel/objects/endpoint.cpp +++ b/src/kernel/objects/endpoint.cpp @@ -10,14 +10,15 @@ endpoint::endpoint() : endpoint::~endpoint() { - if (!check_signal(j6_signal_endpoint_closed)) + if (!check_signal(j6_signal_closed)) close(); } void endpoint::close() { - assert_signal(j6_signal_endpoint_closed); + kobject::close(); + for (auto &data : m_blocked) { if (data.th) data.th->wake_on_result(this, j6_status_closed); diff --git a/src/kernel/objects/endpoint.h b/src/kernel/objects/endpoint.h index 690672b..99c910d 100644 --- a/src/kernel/objects/endpoint.h +++ b/src/kernel/objects/endpoint.h @@ -16,7 +16,7 @@ public: static constexpr kobject::type type = kobject::type::endpoint; /// Close the endpoint, waking all waiting processes with an error - void close(); + virtual void close() override; /// Check if the endpoint has space for a message to be sent inline bool can_send() const { return check_signal(j6_signal_endpoint_can_send); } diff --git a/src/kernel/objects/kobject.cpp b/src/kernel/objects/kobject.cpp index 017d940..b401ccf 100644 --- a/src/kernel/objects/kobject.cpp +++ b/src/kernel/objects/kobject.cpp @@ -61,6 +61,12 @@ kobject::notify_signal_observers() } } +void +kobject::close() +{ + assert_signal(j6_signal_closed); +} + void kobject::on_no_handles() { diff --git a/src/kernel/objects/kobject.h b/src/kernel/objects/kobject.h index 446d75c..852a741 100644 --- a/src/kernel/objects/kobject.h +++ b/src/kernel/objects/kobject.h @@ -3,6 +3,7 @@ /// Definition of base type for user-interactable kernel objects #include "j6/errors.h" +#include "j6/signals.h" #include "j6/types.h" #include "kutil/vector.h" @@ -76,6 +77,12 @@ public: /// Remove the given thread from the list of threads waiting on this object. inline void remove_blocked_thread(thread *t) { m_blocked_threads.remove_swap(t); } + /// Perform any cleanup actions necessary to mark this object closed + virtual void close(); + + /// Check if this object has been closed + inline bool closed() const { return check_signal(j6_signal_closed); } + protected: /// Interface for subclasses to handle when all handles are closed. Subclasses /// should either call the base version, or assert j6_signal_no_handles. diff --git a/src/kernel/objects/process.cpp b/src/kernel/objects/process.cpp index cc61d6f..7cdf6a3 100644 --- a/src/kernel/objects/process.cpp +++ b/src/kernel/objects/process.cpp @@ -1,4 +1,3 @@ -#include "j6/signals.h" #include "kutil/assert.h" #include "kutil/no_construct.h" #include "cpu.h" @@ -62,7 +61,7 @@ process::exit(unsigned code) thread->exit(code); } m_return_code = code; - assert_signal(j6_signal_process_exit); + close(); if (this == bsp_cpu_data.p) scheduler::get().schedule(); diff --git a/src/kernel/objects/thread.cpp b/src/kernel/objects/thread.cpp index 8c3528d..6a5b1ca 100644 --- a/src/kernel/objects/thread.cpp +++ b/src/kernel/objects/thread.cpp @@ -139,7 +139,7 @@ thread::exit(uint32_t code) m_return_code = code; set_state(state::exited); clear_state(state::ready); - assert_signal(j6_signal_thread_exit); + close(); schedule_if_current(this); } diff --git a/src/kernel/syscalls/channel.cpp b/src/kernel/syscalls/channel.cpp index b056c9d..9a5aedf 100644 --- a/src/kernel/syscalls/channel.cpp +++ b/src/kernel/syscalls/channel.cpp @@ -13,15 +13,6 @@ channel_create(j6_handle_t *handle) return j6_status_ok; } -j6_status_t -channel_close(j6_handle_t handle) -{ - channel *c = remove_handle(handle); - if (!c) return j6_err_invalid_arg; - c->close(); - return j6_status_ok; -} - j6_status_t channel_send(j6_handle_t handle, size_t *len, void *data) { diff --git a/src/kernel/syscalls/endpoint.cpp b/src/kernel/syscalls/endpoint.cpp index d07c3d4..6f83bc5 100644 --- a/src/kernel/syscalls/endpoint.cpp +++ b/src/kernel/syscalls/endpoint.cpp @@ -15,15 +15,6 @@ endpoint_create(j6_handle_t *handle) return j6_status_ok; } -j6_status_t -endpoint_close(j6_handle_t handle) -{ - endpoint *e = remove_handle(handle); - if (!e) return j6_err_invalid_arg; - e->close(); - return j6_status_ok; -} - j6_status_t endpoint_send(j6_handle_t handle, j6_tag_t tag, size_t len, void *data) { diff --git a/src/kernel/syscalls/helpers.h b/src/kernel/syscalls/helpers.h index 11cadb6..ff5caa3 100644 --- a/src/kernel/syscalls/helpers.h +++ b/src/kernel/syscalls/helpers.h @@ -3,6 +3,7 @@ /// Utility functions for use in syscall handler implementations #include "j6/types.h" +#include "objects/kobject.h" #include "objects/process.h" namespace syscalls { @@ -26,6 +27,13 @@ T * get_handle(j6_handle_t handle) return static_cast(o); } +template <> +inline kobject * get_handle(j6_handle_t handle) +{ + process &p = process::current(); + return p.lookup_handle(handle); +} + template T * remove_handle(j6_handle_t handle) { diff --git a/src/kernel/syscalls/object.cpp b/src/kernel/syscalls/object.cpp index fcdf7cb..4431302 100644 --- a/src/kernel/syscalls/object.cpp +++ b/src/kernel/syscalls/object.cpp @@ -3,18 +3,29 @@ #include "j6/types.h" #include "log.h" -#include "objects/process.h" #include "objects/thread.h" +#include "syscalls/helpers.h" namespace syscalls { +j6_status_t +object_koid(j6_handle_t handle, j6_koid_t *koid) +{ + if (koid == nullptr) + return j6_err_invalid_arg; + + kobject *obj = get_handle(handle); + if (!obj) + return j6_err_invalid_arg; + + *koid = obj->koid(); + return j6_status_ok; +} + j6_status_t object_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs) { - thread &th = thread::current(); - process &p = process::current(); - - kobject *obj = p.lookup_handle(handle); + kobject *obj = get_handle(handle); if (!obj) return j6_err_invalid_arg; @@ -24,6 +35,7 @@ object_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs) return j6_status_ok; } + thread &th = thread::current(); obj->add_blocked_thread(&th); th.wait_on_signals(obj, mask); @@ -40,8 +52,7 @@ object_signal(j6_handle_t handle, j6_signal_t signals) if ((signals & j6_signal_user_mask) != signals) return j6_err_invalid_arg; - process &p = process::current(); - kobject *obj = p.lookup_handle(handle); + kobject *obj = get_handle(handle); if (!obj) return j6_err_invalid_arg; @@ -49,4 +60,15 @@ object_signal(j6_handle_t handle, j6_signal_t signals) return j6_status_ok; } +j6_status_t +object_close(j6_handle_t handle) +{ + kobject *obj = get_handle(handle); + if (!obj) + return j6_err_invalid_arg; + + obj->close(); + return j6_status_ok; +} + } // namespace syscalls diff --git a/src/kernel/syscalls/process.cpp b/src/kernel/syscalls/process.cpp index 3cf1884..ca49d4f 100644 --- a/src/kernel/syscalls/process.cpp +++ b/src/kernel/syscalls/process.cpp @@ -6,16 +6,6 @@ namespace syscalls { -j6_status_t -process_koid(j6_koid_t *koid) -{ - if (koid == nullptr) - return j6_err_invalid_arg; - - *koid = process::current().koid(); - return j6_status_ok; -} - j6_status_t process_exit(int64_t status) { diff --git a/src/kernel/syscalls/thread.cpp b/src/kernel/syscalls/thread.cpp index 0b2f859..f1a0cad 100644 --- a/src/kernel/syscalls/thread.cpp +++ b/src/kernel/syscalls/thread.cpp @@ -7,16 +7,6 @@ namespace syscalls { -j6_status_t -thread_koid(j6_koid_t *koid) -{ - if (koid == nullptr) - return j6_err_invalid_arg; - - *koid = thread::current().koid(); - return j6_status_ok; -} - j6_status_t thread_create(void *rip, j6_handle_t *handle) { diff --git a/src/kernel/syscalls/vm_area.cpp b/src/kernel/syscalls/vm_area.cpp index b61eb59..8fa22c4 100644 --- a/src/kernel/syscalls/vm_area.cpp +++ b/src/kernel/syscalls/vm_area.cpp @@ -47,17 +47,6 @@ vma_unmap(j6_handle_t handle) return j6_status_ok; } -j6_status_t -vma_close(j6_handle_t handle) -{ - j6_status_t status = vma_unmap(handle); - if (status != j6_status_ok) - return status; - - remove_handle(handle); - return j6_status_ok; -} - j6_status_t vma_resize(j6_handle_t handle, size_t *size) {