diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-07-07 13:22:53 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-11-11 00:08:15 +0100 |
| commit | 7861a52adf92a083bb2aed4c35f98d8035dce032 (patch) | |
| tree | 28cd3c40e4c878f730f5df3c1d93bdf91af490c3 /src/caio | |
| parent | 7fc48e9216ff809da5f8055a50b0be17628ef1df (diff) | |
| download | wnix-7861a52adf92a083bb2aed4c35f98d8035dce032.tar.gz | |
Setup project skeleton
Diffstat (limited to 'src/caio')
| -rw-r--r-- | src/caio/CMakeLists.txt | 23 | ||||
| -rw-r--r-- | src/caio/include/caio.h | 43 | ||||
| -rw-r--r-- | src/caio/private_include/caio/routines.h | 27 | ||||
| -rw-r--r-- | src/caio/private_include/caio/types.h | 46 | ||||
| -rw-r--r-- | src/caio/src/CMakeLists.txt | 27 | ||||
| -rw-r--r-- | src/caio/src/cache.c | 38 | ||||
| -rw-r--r-- | src/caio/src/close.c | 44 | ||||
| -rw-r--r-- | src/caio/src/eof.c | 25 | ||||
| -rw-r--r-- | src/caio/src/open.c | 79 | ||||
| -rw-r--r-- | src/caio/src/read.c | 154 | ||||
| -rw-r--r-- | src/caio/src/readdebugmsg.c | 170 | ||||
| -rw-r--r-- | src/caio/src/readnodebug.c | 152 | ||||
| -rw-r--r-- | src/caio/src/seek.c | 35 | ||||
| -rw-r--r-- | src/caio/src/set_caches.c | 78 | ||||
| -rw-r--r-- | src/caio/src/tell.c | 26 | ||||
| -rw-r--r-- | src/caio/src/write.c | 29 |
16 files changed, 996 insertions, 0 deletions
diff --git a/src/caio/CMakeLists.txt b/src/caio/CMakeLists.txt new file mode 100644 index 0000000..980d21b --- /dev/null +++ b/src/caio/CMakeLists.txt @@ -0,0 +1,23 @@ +# wnix, a Unix-like operating system for WebAssembly applications. +# Copyright (C) 2025 Xavier Del Campo Romero +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +add_library(caio) +add_subdirectory(src) +target_include_directories(caio PUBLIC include PRIVATE private_include) +target_link_libraries(caio PUBLIC aio fs state PRIVATE loop) +# Even if PRIVATE, there are cyclical dependencies among libraries that +# make LINK_INTERFACE_MULTIPLICITY to exceed its default value (2). +set_target_properties(caio PROPERTIES LINK_INTERFACE_MULTIPLICITY 3) diff --git a/src/caio/include/caio.h b/src/caio/include/caio.h new file mode 100644 index 0000000..284224a --- /dev/null +++ b/src/caio/include/caio.h @@ -0,0 +1,43 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef CAIO_H +#define CAIO_H + +#include <aio.h> +#include <stddef.h> + +struct caio_open +{ + const char *path; + int flags; + uid_t uid; + gid_t gid; +}; + +struct caio *caio_open(const struct caio_open *op, const struct aio_done *d); +int caio_set_caches(struct caio *a, size_t n); +int caio_read(struct caio *a, void *buf, size_t n, const struct aio_done *d); +int caio_write(struct caio *a, const void *buf, size_t n, + const struct aio_done *d); +int caio_seek(struct caio *a, off_t offset); +int caio_tell(const struct caio *a, off_t *offset); +int caio_eof(const struct caio *a); +int caio_close(struct caio *a); + +#endif diff --git a/src/caio/private_include/caio/routines.h b/src/caio/private_include/caio/routines.h new file mode 100644 index 0000000..a83043a --- /dev/null +++ b/src/caio/private_include/caio/routines.h @@ -0,0 +1,27 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef CAIO_ROUTINES_H +#define CAIO_ROUTINES_H + +#include <caio/types.h> +#include <sys/types.h> + +struct caio_cache *caio_cache(struct caio *a); + +#endif diff --git a/src/caio/private_include/caio/types.h b/src/caio/private_include/caio/types.h new file mode 100644 index 0000000..001a4d3 --- /dev/null +++ b/src/caio/private_include/caio/types.h @@ -0,0 +1,46 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef CAIO_TYPES_H +#define CAIO_TYPES_H + +#include <caio.h> +#include <aio.h> +#include <fs/fs.h> +#include <sys/types.h> +#include <stdbool.h> +#include <stddef.h> + +struct caio_cache +{ + off_t offset; + size_t available; + char buf[2048]; + struct caio_cache *prev, *next; +}; + +struct caio +{ + struct aio_done done; + struct aio *aio; + struct fs_fd fd; + struct caio_cache *caches; + off_t offset; +}; + +#endif diff --git a/src/caio/src/CMakeLists.txt b/src/caio/src/CMakeLists.txt new file mode 100644 index 0000000..91b95d4 --- /dev/null +++ b/src/caio/src/CMakeLists.txt @@ -0,0 +1,27 @@ +# wnix, a Unix-like operating system for WebAssembly applications. +# Copyright (C) 2025 Xavier Del Campo Romero +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +target_sources(caio PRIVATE + cache.c + close.c + eof.c + open.c + read.c + seek.c + set_caches.c + tell.c + write.c +) diff --git a/src/caio/src/cache.c b/src/caio/src/cache.c new file mode 100644 index 0000000..edd462c --- /dev/null +++ b/src/caio/src/cache.c @@ -0,0 +1,38 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/routines.h> +#include <caio/types.h> +#include <sys/types.h> +#include <stddef.h> + +struct caio_cache *caio_cache(struct caio *const a) +{ + for (struct caio_cache *c = a->caches; c; c = c->next) + { + const off_t offset = a->offset; + + if (c->available + && offset >= c->offset + && offset < c->offset + sizeof c->buf) + return c; + } + + return NULL; +} diff --git a/src/caio/src/close.c b/src/caio/src/close.c new file mode 100644 index 0000000..253aaa7 --- /dev/null +++ b/src/caio/src/close.c @@ -0,0 +1,44 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/types.h> +#include <aio.h> +#include <fs/fs.h> +#include <stdlib.h> + +int caio_close(struct caio *const caio) +{ + if (!caio) + return 0; + else + aio_free(caio->aio); + + for (struct caio_cache *c = caio->caches; c;) + { + struct caio_cache *const next = c->next; + + free(c); + c = next; + } + + aio_close(&caio->fd); + free(caio); + /* TODO */ + return -1; +} diff --git a/src/caio/src/eof.c b/src/caio/src/eof.c new file mode 100644 index 0000000..a631546 --- /dev/null +++ b/src/caio/src/eof.c @@ -0,0 +1,25 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/types.h> + +int caio_eof(const struct caio *const a) +{ + return a->offset >= a->fd.size; +} diff --git a/src/caio/src/open.c b/src/caio/src/open.c new file mode 100644 index 0000000..c12432c --- /dev/null +++ b/src/caio/src/open.c @@ -0,0 +1,79 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/types.h> +#include <aio.h> +#include <loop.h> +#include <fs/fs.h> +#include <stdlib.h> + +static int done(const enum state state, void *const args) +{ + struct caio *const a = args; + const struct aio_done *const d = &a->done; + + if (loop_rm_aio(a->aio)) + return -1; + + aio_free(a->aio); + a->aio = NULL; + return d->f ? d->f(state, d->args) : 0; +} + +struct caio *caio_open(const struct caio_open *op, + const struct aio_done *const d) +{ + struct aio *aio = NULL; + struct caio *const ret = malloc(sizeof *ret); + + if (!ret) + goto failure; + + const struct fs_open aio_op = + { + .flags = op->flags, + .path = op->path, + .uid = op->uid, + .gid = op->gid, + .fd = &ret->fd, + }; + + const struct aio_done dd = + { + .f = done, + .args = ret + }; + + *ret = (const struct caio){0}; + + if (caio_set_caches(ret, 1) + || !(aio = aio_open(&aio_op, &dd)) + || loop_add_aio(aio)) + goto failure; + else if (d) + ret->done = *d; + + ret->aio = aio; + return ret; + +failure: + aio_free(aio); + free(ret); + return NULL; +} diff --git a/src/caio/src/read.c b/src/caio/src/read.c new file mode 100644 index 0000000..e1e85b6 --- /dev/null +++ b/src/caio/src/read.c @@ -0,0 +1,154 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/routines.h> +#include <caio/types.h> +#include <aio.h> +#include <fs/fs.h> +#include <loop.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +static int done(const enum state s, void *const args) +{ + struct caio *const a = args; + const struct aio_done *const d = &a->done; + + if (loop_rm_aio(a->aio)) + return -1; + + aio_free(a->aio); + a->aio = NULL; + return d->f ? d->f(s, d->args) : 0; +} + +static size_t read_cache(struct caio *const a, struct caio_cache *const c, + void *const buf, size_t n) +{ + char *p = buf; + size_t i = a->offset % sizeof c->buf; + + while (i < c->available && n) + { + *p++ = c->buf[i++]; + n--; + } + + const size_t ret = p - (const char *)buf; + + a->offset += ret; + return ret; +} + +static size_t getrem(const struct caio *const a) +{ + const struct fs_fd *const fd = &a->fd; + const off_t n = fd->size - fd->offset; + const size_t sz = sizeof a->caches->buf / sizeof *a->caches->buf; + + return n < sz ? n : sz; +} + +static struct caio_cache *rotate(struct caio *const a) +{ + const struct fs_fd *const fd = &a->fd; + long long maxdiff = LLONG_MAX; + struct caio_cache *ret = a->caches; + + for (struct caio_cache *c = a->caches; c; c = c->next) + { + if (!c->available) + return c; + + const long long diff = (long long)c->offset - (long long)fd->offset, + adiff = llabs(diff); + + if (adiff < maxdiff) + { + maxdiff = adiff; + ret = c; + } + } + + return ret; +} + +static int setup_cache(struct caio *const a, const struct aio_done *const d) +{ + const size_t rem = getrem(a); + + if (!rem) + return 0; + + struct aio *aio = NULL; + struct caio_cache *const c = rotate(a); + const struct fs_read r = + { + .fd = &a->fd, + .buf = c->buf, + .n = rem + }; + + const struct aio_done dd = + { + .f = done, + .args = a + }; + + const off_t offset = (a->offset / sizeof c->buf) * sizeof c->buf; + + a->fd.offset = offset; + + if (!(aio = aio_read(&r, &dd)) || loop_add_aio(aio)) + goto failure; + else if (d) + a->done = *d; + else + a->done = (const struct aio_done){0}; + + a->aio = aio; + c->offset = offset; + c->available = rem; + return 0; + +failure: + aio_free(aio); + return -1; +} + +int caio_read(struct caio *const a, void *const buf, const size_t n, + const struct aio_done *const d) +{ + if (a->offset >= a->fd.size) + return 0; + + struct caio_cache *const c = caio_cache(a); + + if (c) + { + const size_t cr = read_cache(a, c, buf, n); + + if (cr) + return cr; + } + + return setup_cache(a, d); +} diff --git a/src/caio/src/readdebugmsg.c b/src/caio/src/readdebugmsg.c new file mode 100644 index 0000000..11493ba --- /dev/null +++ b/src/caio/src/readdebugmsg.c @@ -0,0 +1,170 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/routines.h> +#include <caio/types.h> +#include <aio.h> +#include <fs/fs.h> +#include <loop.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + + +#include <drv/ps1/bios.h> +static int done(const enum state s, void *const args) +{ + struct caio *const a = args; + const struct aio_done *const d = &a->done; + + if (loop_rm_aio(a->aio)) + return -1; + + aio_free(a->aio); + a->aio = NULL; + Printf("finished preparing cache\n"); + return d->f ? d->f(s, d->args) : 0; +} + +static size_t read_cache(struct caio *const a, struct caio_cache *const c, + void *const buf, size_t n) +{ + char *p = buf; + size_t i = a->offset % sizeof c->buf, start = i; + unsigned char checksum = 0; + + while (i < c->available && n) + { + const unsigned char b = c->buf[i++]; + + *p++ = b; + checksum += b; + n--; + } + + const size_t ret = p - (const char *)buf; + + if (ret) + Printf("%s: read %lu bytes from cache %p (offset=%lu, bytes [%lu-%lu], chk=%#x)\n", + __func__, (unsigned long)ret, (void *)c, + (unsigned long)a->offset, (unsigned long)start, (unsigned long)i - 1, + (unsigned)checksum); + + a->offset += ret; + return ret; +} + +static size_t getrem(const struct caio *const a) +{ + const struct fs_fd *const fd = &a->fd; + const off_t n = fd->size - fd->offset; + const size_t sz = sizeof a->caches->buf / sizeof *a->caches->buf; + + return n < sz ? n : sz; +} + +static struct caio_cache *rotate(struct caio *const a) +{ + const struct fs_fd *const fd = &a->fd; + long long maxdiff = LLONG_MAX; + struct caio_cache *ret = a->caches; + + for (struct caio_cache *c = a->caches; c; c = c->next) + { + if (!c->available) + return c; + + const long long diff = (long long)c->offset - (long long)fd->offset, + adiff = llabs(diff); + + if (adiff < maxdiff) + { + maxdiff = adiff; + ret = c; + } + } + + return ret; +} + +static int setup_cache(struct caio *const a, const struct aio_done *const d) +{ + const size_t rem = getrem(a); + + if (!rem) + return 0; + + struct aio *aio = NULL; + struct caio_cache *const c = rotate(a); + const struct fs_read r = + { + .fd = &a->fd, + .buf = c->buf, + .n = rem + }; + + const struct aio_done dd = + { + .f = done, + .args = a + }; + + const off_t offset = (a->offset / sizeof c->buf) * sizeof c->buf; + + a->fd.offset = offset; + + if (!(aio = aio_read(&r, &dd)) || loop_add_aio(aio)) + goto failure; + else if (d) + a->done = *d; + else + a->done = (const struct aio_done){0}; + + a->aio = aio; + c->offset = offset; + c->available = rem; + Printf("%s: setting up cache %p with offset %lu, fd->offset=%lu and %lu bytes\n", + __func__, (void *)c, (unsigned long)c->offset, (unsigned long)a->fd.offset, + (unsigned long)c->available); + return 0; + +failure: + aio_free(aio); + return -1; +} + +int caio_read(struct caio *const a, void *const buf, const size_t n, + const struct aio_done *const d) +{ + if (a->offset >= a->fd.size) + return 0; + + struct caio_cache *const c = caio_cache(a); + + if (c) + { + const size_t cr = read_cache(a, c, buf, n); + + if (cr) + return cr; + } + + return setup_cache(a, d); +} diff --git a/src/caio/src/readnodebug.c b/src/caio/src/readnodebug.c new file mode 100644 index 0000000..ed8187e --- /dev/null +++ b/src/caio/src/readnodebug.c @@ -0,0 +1,152 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/routines.h> +#include <caio/types.h> +#include <aio.h> +#include <fs/fs.h> +#include <loop.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +static int done(const enum state s, void *const args) +{ + struct caio *const a = args; + const struct aio_done *const d = &a->done; + + if (loop_rm_aio(a->aio)) + return -1; + + aio_free(a->aio); + a->aio = NULL; + return d->f ? d->f(s, d->args) : 0; +} + +static size_t read_cache(struct caio *const a, struct caio_cache *const c, + void *const buf, size_t n) +{ + char *p = buf; + size_t i = a->offset % sizeof c->buf; + + while (i < c->available && n) + { + *p++ = c->buf[i++]; + n--; + } + + const size_t ret = p - (const char *)buf; + + a->offset += ret; + return ret; +} + +static size_t getrem(const struct caio *const a) +{ + const struct fs_fd *const fd = &a->fd; + const off_t n = fd->size - fd->offset; + const size_t sz = sizeof a->caches->buf / sizeof *a->caches->buf; + + return n < sz ? n : sz; +} + +static struct caio_cache *rotate(struct caio *const a) +{ + const struct fs_fd *const fd = &a->fd; + long long maxdiff = LLONG_MAX; + struct caio_cache *ret = a->caches; + + for (struct caio_cache *c = a->caches; c; c = c->next) + { + const long long diff = c->available ? + (long long)c->offset - (long long)fd->offset : 0, + adiff = llabs(diff); + + if (adiff < maxdiff) + { + maxdiff = adiff; + ret = c; + } + } + + return ret; +} + +static int setup_cache(struct caio *const a, const struct aio_done *const d) +{ + const size_t rem = getrem(a); + + if (!rem) + return 0; + + struct aio *aio = NULL; + struct caio_cache *const c = rotate(a); + const struct fs_read r = + { + .fd = &a->fd, + .buf = c->buf, + .n = rem + }; + + const struct aio_done dd = + { + .f = done, + .args = a + }; + + const off_t offset = (a->offset / sizeof c->buf) * sizeof c->buf; + + a->fd.offset = offset; + + if (!(aio = aio_read(&r, &dd)) || loop_add_aio(aio)) + goto failure; + else if (d) + a->done = *d; + else + a->done = (const struct aio_done){0}; + + a->aio = aio; + c->offset = offset; + c->available = rem; + return 0; + +failure: + aio_free(aio); + return -1; +} + +int caio_read(struct caio *const a, void *const buf, const size_t n, + const struct aio_done *const d) +{ + if (a->offset >= a->fd.size) + return 0; + + struct caio_cache *const c = caio_cache(a); + + if (c) + { + const size_t cr = read_cache(a, c, buf, n); + + if (cr) + return cr; + } + + return setup_cache(a, d); +} diff --git a/src/caio/src/seek.c b/src/caio/src/seek.c new file mode 100644 index 0000000..1c0848d --- /dev/null +++ b/src/caio/src/seek.c @@ -0,0 +1,35 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/routines.h> +#include <caio/types.h> +#include <sys/types.h> + +int caio_seek(struct caio *const a, const off_t offset) +{ + struct fs_fd *const fd = &a->fd; + const off_t page = offset / sizeof a->caches->buf; + + a->offset = offset; + + if (!caio_cache(a)) + fd->offset = page * sizeof a->caches->buf; + + return 0; +} diff --git a/src/caio/src/set_caches.c b/src/caio/src/set_caches.c new file mode 100644 index 0000000..dfdd562 --- /dev/null +++ b/src/caio/src/set_caches.c @@ -0,0 +1,78 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/types.h> +#include <errno.h> +#include <stdlib.h> + +int caio_set_caches(struct caio *const a, const size_t n) +{ + struct caio_cache *c, *prev = NULL; + size_t i; + + if (!n) + { + errno = EINVAL; + return -1; + } + + for (i = 0, c = a->caches; i < n; i++) + { + if (!c) + { + struct caio_cache *const nc = malloc(sizeof *nc); + + if (!nc) + return -1; + + *nc = (const struct caio_cache){0}; + + if (!a->caches) + a->caches = nc; + else if (prev) + { + prev->next = nc; + nc->prev = prev; + } + + prev = nc; + } + else + { + prev = c; + c = c->next; + } + } + + for (i = 0, c = a->caches; c; i++) + { + struct caio_cache *const next = c->next; + + if (i >= n) + { + c->prev = c->next; + c->next = c->prev; + free(c); + } + + c = next; + } + + return 0; +} diff --git a/src/caio/src/tell.c b/src/caio/src/tell.c new file mode 100644 index 0000000..7bfb63a --- /dev/null +++ b/src/caio/src/tell.c @@ -0,0 +1,26 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/types.h> + +int caio_tell(const struct caio *const a, off_t *const offset) +{ + *offset = a->offset; + return 0; +} diff --git a/src/caio/src/write.c b/src/caio/src/write.c new file mode 100644 index 0000000..55ac558 --- /dev/null +++ b/src/caio/src/write.c @@ -0,0 +1,29 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <caio.h> +#include <caio/types.h> +#include <aio.h> +#include <fs/fs.h> + +int caio_write(struct caio *const caio, const void *const buf, const size_t n, + const struct aio_done *d) +{ + /* TODO */ + return -1; +} |
