diff options
-rw-r--r-- | lib/libc/include/unistd.h | 3 | ||||
-rw-r--r-- | lib/libc/src/unistd/getpid.c | 43 | ||||
-rw-r--r-- | sys/dev/cons/cons.c | 70 | ||||
-rw-r--r-- | sys/fs/devfs.c | 33 | ||||
-rw-r--r-- | sys/include/dev/cons/cons.h | 6 | ||||
-rw-r--r-- | sys/include/fs/devfs.h | 2 | ||||
-rw-r--r-- | sys/include/sys/devstat.h | 46 | ||||
-rw-r--r-- | sys/include/sys/mutex.h | 52 | ||||
-rw-r--r-- | sys/include/sys/syscall.h | 2 | ||||
-rw-r--r-- | sys/kern/kern_sched.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_synch.c | 62 | ||||
-rw-r--r-- | sys/kern/kern_syscall.c | 2 |
12 files changed, 322 insertions, 1 deletions
diff --git a/lib/libc/include/unistd.h b/lib/libc/include/unistd.h index 8c82eb8..01c4abc 100644 --- a/lib/libc/include/unistd.h +++ b/lib/libc/include/unistd.h @@ -52,6 +52,9 @@ int close(int fd); int access(const char *path, int mode); off_t lseek(int fildes, off_t offset, int whence); +pid_t getpid(void); +pid_t getppid(void); + __END_DECLS #endif /* !_UNISTD_H */ diff --git a/lib/libc/src/unistd/getpid.c b/lib/libc/src/unistd/getpid.c new file mode 100644 index 0000000..5770495 --- /dev/null +++ b/lib/libc/src/unistd/getpid.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/syscall.h> +#include <unistd.h> + +pid_t +getpid(void) +{ + return syscall(SYS_getpid); +} + +pid_t +getppid(void) +{ + return syscall(SYS_getppid); +} diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c index 2cef071..9921ff8 100644 --- a/sys/dev/cons/cons.c +++ b/sys/dev/cons/cons.c @@ -343,6 +343,7 @@ cons_fast_putch(struct cons_screen *scr, char c) static int dev_write(dev_t dev, struct sio_txn *sio, int flags) { + cons_attach(); cons_putstr(&g_root_scr, sio->buf, sio->len); cons_flush(&g_root_scr); return sio->len; @@ -372,6 +373,7 @@ dev_read(dev_t dev, struct sio_txn *sio, int flags) return -EAGAIN; } + cons_attach(); spinlock_acquire(&g_root_scr.lock); for (;;) { /* Buffer too small */ @@ -468,6 +470,69 @@ ctl_feat_write(struct ctlfs_dev *cdp, struct sio_txn *sio) } /* + * Detach the currently running process from the + * console. + */ +int +cons_detach(void) +{ + struct cons_screen *scr; + + scr = &g_root_scr; + if (scr->atproc == NULL) { + return 0; + } + if (scr->atproc_lock == NULL) { + return 0; + } + + scr = &g_root_scr; + scr->atproc = NULL; + mutex_release(scr->atproc_lock); + return 0; +} + +/* + * Attach the current process to the + * console. + */ +int +cons_attach(void) +{ + struct cons_screen *scr; + struct proc *td, *atproc; + + td = this_td(); + if (td == NULL) { + return -1; + } + + scr = &g_root_scr; + if (scr->atproc_lock == NULL) { + return 0; + } + + scr = &g_root_scr; + atproc = scr->atproc; + + if (atproc != NULL) { + if (atproc->pid == td->pid) { + return 0; + } + + /* + * Do not release this here as we want + * any other process that tries to attach + * to wait. + */ + mutex_acquire(scr->atproc_lock, 0); + } + + scr->atproc = td; + return 0; +} + +/* * Reset console color. */ void @@ -556,6 +621,8 @@ cons_init(void) g_root_scr.nrows = fbdev.height / FONT_HEIGHT; g_root_scr.ncols = fbdev.width / FONT_WIDTH; g_root_scr.fbdev = fbdev; + g_root_scr.atproc = NULL; + g_root_scr.atproc_lock = NULL; memset(&g_root_scr.lock, 0, sizeof(g_root_scr.lock)); cons_init_bufs(&g_root_scr); SHOW_CURSOR(&g_root_scr); @@ -578,6 +645,9 @@ cons_expose(void) return; } + /* Init the attached proc mutex lock */ + g_root_scr.atproc_lock = mutex_new("console0"); + /* Register the device here */ major = dev_alloc_major(); dev = dev_alloc(major); diff --git a/sys/fs/devfs.c b/sys/fs/devfs.c index 293ee0a..3bd1b11 100644 --- a/sys/fs/devfs.c +++ b/sys/fs/devfs.c @@ -31,6 +31,7 @@ #include <sys/vnode.h> #include <sys/errno.h> #include <sys/stat.h> +#include <sys/syslog.h> #include <sys/mount.h> #include <sys/device.h> #include <fs/devfs.h> @@ -38,6 +39,7 @@ #include <string.h> struct devfs_node { + struct devstat stat; char *name; uint8_t is_block : 1; mode_t mode; @@ -180,6 +182,7 @@ static int devfs_read(struct vnode *vp, struct sio_txn *sio) { struct devfs_node *dnp; + struct devstat *statp; void *devsw; if ((dnp = vp->data) == NULL) @@ -190,6 +193,9 @@ devfs_read(struct vnode *vp, struct sio_txn *sio) if (!dnp->is_block) return cdevsw_read(devsw, dnp->dev, sio); + statp = &dnp->stat; + ++statp->nreads; + /* Block device */ return bdevsw_read(devsw, dnp->dev, sio); } @@ -198,6 +204,7 @@ static int devfs_write(struct vnode *vp, struct sio_txn *sio) { struct devfs_node *dnp; + struct devstat *statp; void *devsw; if ((dnp = vp->data) == NULL) @@ -209,6 +216,9 @@ devfs_write(struct vnode *vp, struct sio_txn *sio) return cdevsw_write(devsw, dnp->dev, sio); } + statp = &dnp->stat; + ++statp->nwrites; + /* Block device */ return bdevsw_write(devsw, dnp->dev, sio); } @@ -233,6 +243,24 @@ devfs_init(struct fs_info *fip) return 0; } +int +devfs_devstat(struct vnode *vp, struct devstat *res) +{ + struct devfs_node *dnp; + + if ((dnp = vp->data) == NULL) { + return -EIO; + } + + /* Not supported on char devices */ + if (!dnp->is_block) { + return -ENOTSUP; + } + + *res = dnp->stat; + return 0; +} + /* * Create an entry within devfs. * @@ -245,6 +273,7 @@ int devfs_create_entry(const char *name, devmajor_t major, dev_t dev, mode_t mode) { struct devfs_node *dnp; + struct devstat *statp; size_t name_len; dnp = dynalloc(sizeof(*dnp)); @@ -258,6 +287,10 @@ devfs_create_entry(const char *name, devmajor_t major, dev_t dev, mode_t mode) return -ENOMEM; } + statp = &dnp->stat; + statp->nwrites = 0; + statp->nreads = 0; + memcpy(dnp->name, name, name_len); dnp->name[name_len] = '\0'; dnp->is_block = ISSET(mode, S_IFBLK) ? 1 : 0; diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h index aa9d8e3..c82c3c5 100644 --- a/sys/include/dev/cons/cons.h +++ b/sys/include/dev/cons/cons.h @@ -32,6 +32,8 @@ #include <sys/types.h> #include <sys/spinlock.h> +#include <sys/proc.h> +#include <sys/mutex.h> #include <sys/console.h> #include <dev/video/fbdev.h> #include <dev/cons/consvar.h> @@ -49,6 +51,8 @@ struct cons_screen { struct fbdev fbdev; struct ansi_state ansi_s; struct console_feat feat; /* Features */ + struct proc *atproc; /* Attached proc */ + struct mutex *atproc_lock; uint32_t fg; uint32_t bg; @@ -72,6 +76,8 @@ void cons_update_color(struct cons_screen *scr, uint32_t fg, uint32_t bg); void cons_clear_scr(struct cons_screen *scr, uint32_t bg); void cons_reset_color(struct cons_screen *scr); void cons_reset_cursor(struct cons_screen *scr); +int cons_attach(void); +int cons_detach(void); int cons_putch(struct cons_screen *scr, char c); int cons_putstr(struct cons_screen *scr, const char *s, size_t len); diff --git a/sys/include/fs/devfs.h b/sys/include/fs/devfs.h index 012c2eb..51b0b45 100644 --- a/sys/include/fs/devfs.h +++ b/sys/include/fs/devfs.h @@ -33,9 +33,11 @@ #include <sys/vnode.h> #include <sys/types.h> #include <sys/device.h> +#include <sys/devstat.h> extern const struct vops g_devfs_vops; int devfs_create_entry(const char *name, devmajor_t major, dev_t dev, mode_t mode); +int devfs_devstat(struct vnode *vp, struct devstat *res); #endif /* !_FS_DEVFS_H_ */ diff --git a/sys/include/sys/devstat.h b/sys/include/sys/devstat.h new file mode 100644 index 0000000..91af30f --- /dev/null +++ b/sys/include/sys/devstat.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_DEVSTAT_H_ +#define _SYS_DEVSTAT_H_ + +#include <sys/types.h> + +/* + * Stats for block devices + * + * @nwrites: Number of writes total + * @nreads: Number of reads total + */ +struct devstat { + size_t nwrites; + size_t nreads; +}; + +#endif /* !_SYS_DEVSTAT_H_ */ diff --git a/sys/include/sys/mutex.h b/sys/include/sys/mutex.h new file mode 100644 index 0000000..8a4d50a --- /dev/null +++ b/sys/include/sys/mutex.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_MUTEX_H_ +#define _SYS_MUTEX_H_ + +#include <sys/types.h> +#include <vm/dynalloc.h> + +#define MUTEX_NAME_LEN 32 + +#if defined(_KERNEL) + +struct mutex { + char name[MUTEX_NAME_LEN]; + volatile uint8_t lock; +}; + +struct mutex *mutex_new(const char *name); +void mutex_free(struct mutex *mtx); + +int mutex_acquire(struct mutex *mtx, int flags); +void mutex_release(struct mutex *mtx); + +#endif /* _KERNEL */ +#endif /* !_SYS_MUTEX_H_ */ diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h index 08bd989..3650e7a 100644 --- a/sys/include/sys/syscall.h +++ b/sys/include/sys/syscall.h @@ -54,6 +54,8 @@ #define SYS_lseek 13 #define SYS_sleep 14 #define SYS_inject 15 +#define SYS_getpid 16 +#define SYS_getppid 17 #if defined(_KERNEL) /* Syscall return value and arg type */ diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index ec5592e..774ba71 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -34,6 +34,7 @@ #include <sys/param.h> #include <sys/syslog.h> #include <sys/atomic.h> +#include <dev/cons/cons.h> #include <machine/frame.h> #include <machine/cpu.h> #include <machine/cdefs.h> @@ -221,6 +222,7 @@ sched_switch(struct trapframe *tf) ci = this_cpu(); td = ci->curtd; + cons_detach(); if (td != NULL) { if (td->pid == 0) diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 57b27d0..497aff7 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -28,12 +28,16 @@ */ #include <sys/types.h> +#include <sys/mutex.h> #include <sys/systm.h> #include <sys/errno.h> +#include <sys/sched.h> #include <sys/atomic.h> #include <sys/syslog.h> #include <sys/spinlock.h> +#include <machine/cdefs.h> #include <dev/timer.h> +#include <string.h> #define pr_trace(fmt, ...) kprintf("synch: " fmt, ##__VA_ARGS__) #define pr_error(...) pr_trace(__VA_ARGS__) @@ -80,7 +84,9 @@ spinlock_usleep(struct spinlock *lock, size_t usec_max) void spinlock_acquire(struct spinlock *lock) { - while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE)); + while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE)) { + md_pause(); + } } /* @@ -136,3 +142,57 @@ sysrel(void) { spinlock_release(&__syslock); } + +/* + * Create a new mutex lock object + */ +struct mutex * +mutex_new(const char *name) +{ + struct mutex *mtx; + size_t namelen; + + mtx = dynalloc(sizeof(*mtx)); + if (mtx == NULL) { + return NULL; + } + + mtx->lock = 0; + namelen = strlen(name); + + /* Don't overflow the name buffer */ + if (namelen >= MUTEX_NAME_LEN) { + namelen = MUTEX_NAME_LEN - 1; + } + + memcpy(mtx->name, name, namelen); + return mtx; +} + +/* + * Acquire a mutex + * + * @mtx: Mutex to acquire + * @flags: Optional flags + */ +int +mutex_acquire(struct mutex *mtx, int flags) +{ + while (__atomic_test_and_set(&mtx->lock, __ATOMIC_ACQUIRE)) { + sched_yield(); + } + + return 0; +} + +void +mutex_release(struct mutex *mtx) +{ + __atomic_clear(&mtx->lock, __ATOMIC_RELEASE); +} + +void +mutex_free(struct mutex *mtx) +{ + dynfree(mtx); +} diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index 292fa56..739dd7f 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -54,6 +54,8 @@ scret_t(*g_sctab[])(struct syscall_args *) = { sys_lseek, /* SYS_lseek */ sys_sleep, /* SYS_sleep */ sys_inject, /* SYS_inject */ + sys_getpid, /* SYS_getpid */ + sys_getppid /* SYS_getppid */ }; const size_t MAX_SYSCALLS = NELEM(g_sctab); |