From 1446fc1748db7c1640eac40ef136a2775747b433 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 16 Sep 2021 17:55:09 +0200 Subject: [PATCH] all: overhaul switch/match syntax This changes the syntax of switch and match expressions following similar changes to harec et al. match (x) { case type => do_work(); yield 10; case x: type => process(x); yield 20; case => abort(); }; Signed-off-by: Drew DeVault Signed-off-by: Alexey Yerin Co-authored-by: Alexey Yerin --- io_uring/cqe.ha | 20 +++++++++++--------- io_uring/queue.ha | 18 ++++++++++++------ io_uring/register.ha | 85 ++++++++++++++++++++++++++++++----------------------- io_uring/setup.ha | 24 ++++++++++++++++-------- diff --git a/io_uring/cqe.ha b/io_uring/cqe.ha index 71054122cdd2ff57e0481b323e6599e1a4e2da95..8683c60ec652f756860fccaadc1fab73508dbbe9 100644 --- a/io_uring/cqe.ha +++ b/io_uring/cqe.ha @@ -13,12 +13,12 @@ // Waits until a CQE is available, then returns it. The caller must pass the // returned CQE to [[cqe_seen]] to advance the queue. export fn wait(ring: *io_uring) (*cqe | error) = { - return match (get_cqe(ring, 0, 1)) { - err: error => err, - cq: nullable *cqe => { - assert(cq != null); // XXX: Correct? - yield cq: *cqe; - }, + match (get_cqe(ring, 0, 1)) { + case err: error => + return err; + case cq: nullable *cqe => + assert(cq != null); // XXX: Correct? + return cq: *cqe; }; }; @@ -82,9 +82,11 @@ break; }; match (rt::io_uring_enter(ring.fd, - submit, wait, flags: uint, null)) { - err: rt::errno => return errors::errno(err), - n: uint => submit -= n, + submit, wait, flags: uint, null)) { + case err: rt::errno => + return errors::errno(err); + case n: uint => + submit -= n; }; }; return cq; diff --git a/io_uring/queue.ha b/io_uring/queue.ha index 82f5735ede4284f4dbc2a0ff1c9d015696d525d9..f3f33967b1303c93586858ab8103434f7e487151 100644 --- a/io_uring/queue.ha +++ b/io_uring/queue.ha @@ -18,9 +18,13 @@ }; // Returns the next available [[sqe]] for this [[io_uring]], or aborts the // program if the queue is full. -export fn must_get_sqe(ring: *io_uring) *sqe = match (get_sqe(ring)) { - null => abort("I/O queue full"), - sq: *sqe => sq, +export fn must_get_sqe(ring: *io_uring) *sqe = { + match (get_sqe(ring)) { + case null => + abort("I/O queue full"); + case sq: *sqe => + return sq; + }; }; fn needs_enter(ring: *io_uring, flags: *enter_flags) bool = { @@ -79,10 +83,12 @@ wait: uint, ) (uint | error) = { let flags: enter_flags = enter_flags::GETEVENTS; if (needs_enter(ring, &flags) || wait != 0) { - return match (rt::io_uring_enter(ring.fd, + match (rt::io_uring_enter(ring.fd, submitted, wait, flags, null)) { - err: rt::errno => errors::errno(err), - n: uint => n, + case err: rt::errno => + return errors::errno(err); + case n: uint => + return n; }; } else { return submitted; diff --git a/io_uring/register.ha b/io_uring/register.ha index 66204a2315f334fc2cf308d95060e21fe4243497..52e0c6dcc8dfb63f7c92391db031b7fadf28b04d 100644 --- a/io_uring/register.ha +++ b/io_uring/register.ha @@ -9,19 +9,21 @@ // anonymous, non-file-backed memory (e.g. the kind returned by alloc or // rt::mmap). export fn register_buffers(ring: *io_uring, iov: []rt::iovec) (void | error) = { assert(len(iov) <= types::UINT_MAX); - return match (rt::io_uring_register(ring.fd, regop::REGISTER_BUFFERS, + match (rt::io_uring_register(ring.fd, regop::REGISTER_BUFFERS, iov: *[*]rt::iovec, len(iov): uint)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; // Unregisters all fixed buffers associated with an [[io_uring]]. export fn unregister_buffers(ring: *io_uring) (void | error) = { - return match (rt::io_uring_register(ring.fd, + match (rt::io_uring_register(ring.fd, regop::UNREGISTER_BUFFERS, null, 0)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; @@ -30,10 +32,11 @@ // may be sparse, meaning that some are set to -1, to be updated later using // [[register_files_update]]. export fn register_files(ring: *io_uring, files: []int) (void | error) = { assert(len(files) <= types::UINT_MAX); - return match (rt::io_uring_register(ring.fd, regop::REGISTER_FILES, + match (rt::io_uring_register(ring.fd, regop::REGISTER_FILES, files: *[*]int, len(files): uint)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; @@ -44,48 +47,53 @@ ring: *io_uring, updates: []files_update, ) (void | error) = { assert(len(updates) <= types::UINT_MAX); - return match (rt::io_uring_register(ring.fd, regop::REGISTER_FILES_UPDATE, + match (rt::io_uring_register(ring.fd, regop::REGISTER_FILES_UPDATE, updates: *[*]files_update, len(updates): uint)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; // Unregisters all files associated with an [[io_uring]]. export fn unregister_files(ring: *io_uring) (void | error) = { - return match (rt::io_uring_register(ring.fd, + match (rt::io_uring_register(ring.fd, regop::UNREGISTER_FILES, null, 0)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; // Registers an eventfd(2) with this [[io_uring]] to be notified of completion // events. export fn register_eventfd(ring: *io_uring, fd: int) (void | error) = { - return match (rt::io_uring_register(ring.fd, + match (rt::io_uring_register(ring.fd, regop::REGISTER_EVENTFD, &fd, 1)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; // Similar to [[register_eventfd]], but only notifies of events which complet // asyncronously. export fn register_eventfd_async(ring: *io_uring, fd: int) (void | error) = { - return match (rt::io_uring_register(ring.fd, + match (rt::io_uring_register(ring.fd, regop::REGISTER_EVENTFD_ASYNC, &fd, 1)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; // Unregisters the eventfd(2) associated with this [[io_uring]]. export fn unregister_eventfd(ring: *io_uring) (void | error) = { - return match (rt::io_uring_register(ring.fd, + match (rt::io_uring_register(ring.fd, regop::UNREGISTER_EVENTFD, null, 0)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; @@ -104,20 +112,23 @@ // Registers the current process's credentials as a personality with an // [[io_uring]], returning an ID. Set the personality field of an [[sqe]] to use // that personality for an I/O submission. export fn register_personality(ring: *io_uring) int = { - return match (rt::io_uring_register(ring.fd, + match (rt::io_uring_register(ring.fd, regop::REGISTER_PERSONALITY, null, 0)) { - rt::errno => abort("Unexpected io_uring REGISTER_PERSONALITY error"), - i: int => i, + case rt::errno => + abort("Unexpected io_uring REGISTER_PERSONALITY error"); + case i: int => + return i; }; }; // Unregisters a personality previously configured with // [[register_personality]]. export fn unregister_personality(ring: *io_uring, id: int) (void | error) = { - return match (rt::io_uring_register(ring.fd, + match (rt::io_uring_register(ring.fd, regop::UNREGISTER_PERSONALITY, null, id: uint)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; @@ -125,10 +136,11 @@ // Enables submissions for an [[io_uring]] which was started in the disabled // state via [[setup_flags::R_DISABLED]]. Future access to this io_uring is // subject to any configured restrictions. export fn register_enable_rings(ring: *io_uring) (void | error) = { - return match (rt::io_uring_register(ring.fd, + match (rt::io_uring_register(ring.fd, regop::REGISTER_ENABLE_RINGS, null, 0)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; @@ -138,9 +150,10 @@ // accepted if the [[io_uring]] was set up in a disabled state via // [[setup_flags::R_DISABLED]]. export fn register_restrictions(ring: *io_uring, res: []restriction) (void | error) = { assert(len(res) < types::UINT_MAX); - return match (rt::io_uring_register(ring.fd, regop::REGISTER_RESTRICTIONS, + match (rt::io_uring_register(ring.fd, regop::REGISTER_RESTRICTIONS, res: *[*]restriction, len(res): uint)) { - err: rt::errno => errors::errno(err), - int => void, + case err: rt::errno => + return errors::errno(err); + case int => void; }; }; diff --git a/io_uring/setup.ha b/io_uring/setup.ha index 8bc747c9a1d92a06fb07b19c517fcb4654bea497..a60e433e9079e0b31a0057cd879cd7b384252d88 100644 --- a/io_uring/setup.ha +++ b/io_uring/setup.ha @@ -6,8 +6,10 @@ // desired flags, sq_thread_cpu, and sq_thread_idle parameters; the remaining // fields are initialized by the kernel. export fn setup(entries: u32, params: *params) (io_uring | error) = { const fd = match (rt::io_uring_setup(entries, params)) { - err: rt::errno => return errors::errno(err), - fd: int => fd, + case err: rt::errno => + return errors::errno(err); + case fd: int => + yield fd; }; let uring = io_uring { @@ -34,8 +36,10 @@ params.sq_off.array + entries * size(u32), rt::PROT_READ | rt::PROT_WRITE, rt::MAP_SHARED | rt::MAP_POPULATE, fd, OFF_SQ_RING)) { - err: rt::errno => return errors::errno(err), - ptr: *void => ptr, + case err: rt::errno => + return errors::errno(err); + case ptr: *void => + yield ptr; }; cq.ring_ptr = if (uring.features & features::SINGLE_MMAP == features::SINGLE_MMAP) { @@ -44,8 +48,10 @@ } else match (rt::mmap(null, cq.ring_sz, rt::PROT_READ | rt::PROT_WRITE, rt::MAP_SHARED | rt::MAP_POPULATE, fd, OFF_CQ_RING)) { - err: rt::errno => return errors::errno(err), - ptr: *void => ptr, + case err: rt::errno => + return errors::errno(err); + case ptr: *void => + yield ptr; }; const ring_ptr = sq.ring_ptr: uintptr; @@ -61,8 +67,10 @@ params.sq_entries * size(sqe), rt::PROT_READ | rt::PROT_WRITE, rt::MAP_SHARED | rt::MAP_POPULATE, fd, OFF_SQES)) { - err: rt::errno => return errors::errno(err), - ptr: *void => ptr: *[*]sqe, + case err: rt::errno => + return errors::errno(err); + case ptr: *void => + yield ptr: *[*]sqe; }; const ring_ptr = cq.ring_ptr: uintptr; -- 2.48.1