From: falcovorbis <fal...@us...> - 2024-09-23 04:40:42
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 93519b5546411b0d6a723f74884753056212ff97 (commit) from fe20ac49efbf6424aa6375e6dbd9c294b5f35bb4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 93519b5546411b0d6a723f74884753056212ff97 Author: Paul Cercueil <pa...@cr...> Date: Mon Sep 23 06:40:24 2024 +0200 Scoped IRQ disable (#765) * irq: Add irq_disable_scoped() This macro will disable interrupts, similarly to irq_disable(), with the difference that the interrupt state will automatically be restored once the execution exits the functional block in which the macro was called. Signed-off-by: Paul Cercueil <pa...@cr...> * thread: Use irq_disable_scoped() Factorize code by using the new irq_disable_scoped() macro. Signed-off-by: Paul Cercueil <pa...@cr...> * net: Use irq_disable_scoped() Factorize code by using the new irq_disable_scoped() macro. Signed-off-by: Paul Cercueil <pa...@cr...> * exports: Use irq_disable_scoped() Factorize code by using the new irq_disable_scoped() macro. Signed-off-by: Paul Cercueil <pa...@cr...> --------- Signed-off-by: Paul Cercueil <pa...@cr...> ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/include/arch/irq.h | 19 ++++ kernel/exports/library.c | 9 +- kernel/net/net_dhcp.c | 5 +- kernel/net/net_tcp.c | 5 +- kernel/net/net_thd.c | 10 +-- kernel/thread/cond.c | 24 ++--- kernel/thread/genwait.c | 27 ++---- kernel/thread/mutex.c | 111 +++++++++++------------ kernel/thread/rwsem.c | 145 ++++++++++++------------------- kernel/thread/sem.c | 19 ++-- kernel/thread/thread.c | 27 ++---- kernel/thread/worker.c | 15 +--- 12 files changed, 164 insertions(+), 252 deletions(-) diff --git a/kernel/arch/dreamcast/include/arch/irq.h b/kernel/arch/dreamcast/include/arch/irq.h index f9bcdbf8..8b47a5e9 100644 --- a/kernel/arch/dreamcast/include/arch/irq.h +++ b/kernel/arch/dreamcast/include/arch/irq.h @@ -434,6 +434,25 @@ int irq_init(void); */ void irq_shutdown(void); +/** \cond */ +static inline void __irq_scoped_cleanup(int *state) { + irq_restore(*state); +} + +#define ___irq_disable_scoped(l) \ + int __scoped_irq_##l __attribute__((cleanup(__irq_scoped_cleanup))) = irq_disable() + +#define __irq_disable_scoped(l) ___irq_disable_scoped(l) +/** \endcond */ + +/** \brief Disable interrupts with scope management. + + This macro will disable interrupts, similarly to irq_disable(), with the + difference that the interrupt state will automatically be restored once the + execution exits the functional block in which the macro was called. +*/ +#define irq_disable_scoped() __irq_disable_scoped(__LINE__) + __END_DECLS #endif /* __ARCH_IRQ_H */ diff --git a/kernel/exports/library.c b/kernel/exports/library.c index 22db0a3c..0b602296 100644 --- a/kernel/exports/library.c +++ b/kernel/exports/library.c @@ -107,11 +107,10 @@ klibrary_t *library_by_libid(libid_t libid) { /* Library shell creation and deletion */ klibrary_t * library_create(int flags) { - int oldirq = 0; klibrary_t * np; libid_t libid; - oldirq = irq_disable(); + irq_disable_scoped(); np = NULL; /* Get a new library id */ @@ -135,7 +134,6 @@ klibrary_t * library_create(int flags) { } } - irq_restore(oldirq); return np; } @@ -200,18 +198,15 @@ uint32 library_get_version(klibrary_t * lib) { /*****************************************************************************/ klibrary_t * library_lookup(const char * name) { - int old; klibrary_t * lib; - old = irq_disable(); + irq_disable_scoped(); LIST_FOREACH(lib, &library_list, list) { if(!strcasecmp(lib->lib_get_name(), name)) break; } - irq_restore(old); - if(!lib) errno = ENOENT; diff --git a/kernel/net/net_dhcp.c b/kernel/net/net_dhcp.c index 572df741..064a8964 100644 --- a/kernel/net/net_dhcp.c +++ b/kernel/net/net_dhcp.c @@ -392,7 +392,8 @@ static void net_dhcp_renew(void) { static void net_dhcp_bind(dhcp_pkt_t *pkt, int len) { uint32 tmp = ntohl(pkt->yiaddr); - uint32 old = irq_disable(); + + irq_disable_scoped(); /* Bind the IP address first */ net_default_dev->ip_addr[0] = (tmp >> 24) & 0xFF; @@ -476,8 +477,6 @@ static void net_dhcp_bind(dhcp_pkt_t *pkt, int len) { } state = DHCP_STATE_BOUND; - - irq_restore(old); } static void net_dhcp_thd(void *obj) { diff --git a/kernel/net/net_tcp.c b/kernel/net/net_tcp.c index f4902d61..866aed78 100644 --- a/kernel/net/net_tcp.c +++ b/kernel/net/net_tcp.c @@ -2971,14 +2971,13 @@ int net_tcp_init(void) { void net_tcp_shutdown(void) { struct tcp_sock *i, *tmp; - int old; /* Kill the thread and make sure we can grab the lock */ if(thd_cb_id >= 0) net_thd_del_callback(thd_cb_id); /* Disable IRQs so we can kill the sockets in peace... */ - old = irq_disable(); + irq_disable_scoped(); /* Clean up existing sockets */ i = LIST_FIRST(&tcp_socks); @@ -3006,6 +3005,4 @@ void net_tcp_shutdown(void) { /* Remove us from fs_socket and clean up the semaphore */ fs_socket_proto_remove(&proto); - - irq_restore(old); } diff --git a/kernel/net/net_thd.c b/kernel/net/net_thd.c index a270a651..8e5f571e 100644 --- a/kernel/net/net_thd.c +++ b/kernel/net/net_thd.c @@ -55,7 +55,6 @@ static void *net_thd_thd(void *data) { } int net_thd_add_callback(void (*cb)(void *), void *data, uint64 timeout) { - int old; struct thd_cb *newcb; /* Allocate space for the new callback and set it up. */ @@ -73,33 +72,30 @@ int net_thd_add_callback(void (*cb)(void *), void *data, uint64 timeout) { newcb->nextrun = timer_ms_gettime64() + timeout; /* Disable interrupts, insert, and re-enable interrupts */ - old = irq_disable(); + irq_disable_scoped(); + TAILQ_INSERT_TAIL(&cbs, newcb, thds); - irq_restore(old); return newcb->cbid; } int net_thd_del_callback(int cbid) { - int old; struct thd_cb *cb; /* Disable interrupts so we can search without fear of anything changing underneath us. */ - old = irq_disable(); + irq_disable_scoped(); /* See if we can find the callback requested. */ TAILQ_FOREACH(cb, &cbs, thds) { if(cb->cbid == cbid) { TAILQ_REMOVE(&cbs, cb, thds); free(cb); - irq_restore(old); return 0; } } /* We didn't find it, punt. */ - irq_restore(old); return -1; } diff --git a/kernel/thread/cond.c b/kernel/thread/cond.c index 979b317f..dc8ffa01 100644 --- a/kernel/thread/cond.c +++ b/kernel/thread/cond.c @@ -58,7 +58,7 @@ int cond_destroy(condvar_t *cv) { } int cond_wait_timed(condvar_t *cv, mutex_t *m, int timeout) { - int old, rv; + int rv; if(irq_inside_int()) { dbglog(DBG_WARNING, "cond_wait: called inside interrupt\n"); @@ -66,12 +66,11 @@ int cond_wait_timed(condvar_t *cv, mutex_t *m, int timeout) { return -1; } - old = irq_disable(); + irq_disable_scoped(); if(m->type < MUTEX_TYPE_NORMAL || m->type > MUTEX_TYPE_RECURSIVE || !mutex_is_locked(m)) { errno = EINVAL; - irq_restore(old); return -1; } @@ -88,9 +87,6 @@ int cond_wait_timed(condvar_t *cv, mutex_t *m, int timeout) { /* Re-lock our mutex */ mutex_lock(m); - /* Ok, ready to return */ - irq_restore(old); - return rv; } @@ -99,27 +95,19 @@ int cond_wait(condvar_t *cv, mutex_t *m) { } int cond_signal(condvar_t *cv) { - int old, rv = 0; - - old = irq_disable(); + irq_disable_scoped(); /* Wake one thread who's waiting, if any */ genwait_wake_one(cv); - irq_restore(old); - - return rv; + return 0; } int cond_broadcast(condvar_t *cv) { - int old, rv = 0; - - old = irq_disable(); + irq_disable_scoped(); /* Wake all threads who are waiting */ genwait_wake_all(cv); - irq_restore(old); - - return rv; + return 0; } diff --git a/kernel/thread/genwait.c b/kernel/thread/genwait.c index da50dbb2..b5c8fa4f 100644 --- a/kernel/thread/genwait.c +++ b/kernel/thread/genwait.c @@ -68,7 +68,6 @@ static kthread_t * tq_next(void) { } int genwait_wait(void * obj, const char * mesg, int timeout, void (*callback)(void *)) { - int old, rv; kthread_t * me; /* Twiddle interrupt state */ @@ -77,7 +76,7 @@ int genwait_wait(void * obj, const char * mesg, int timeout, void (*callback)(vo return -1; } - old = irq_disable(); + irq_disable_scoped(); /* Prepare us for sleep */ me = thd_current; @@ -99,11 +98,7 @@ int genwait_wait(void * obj, const char * mesg, int timeout, void (*callback)(vo TAILQ_INSERT_TAIL(&slpque[LOOKUP(obj)], me, thdq); /* Block us until we're signaled */ - rv = thd_block_now(&me->context); - - irq_restore(old); - - return rv; + return thd_block_now(&me->context); } /* Removes a thread from its wait queue; assumes ints are disabled. */ @@ -131,10 +126,10 @@ static void genwait_unqueue(kthread_t * thd) { int genwait_wake_cnt(void * obj, int cntmax, int err) { kthread_t * t, * nt; struct slpquehead * qp; - int cnt, old; + int cnt; /* Twiddle interrupt state */ - old = irq_disable(); + irq_disable_scoped(); /* Find the queue */ qp = &slpque[LOOKUP(obj)]; @@ -168,9 +163,6 @@ int genwait_wake_cnt(void * obj, int cntmax, int err) { } } - /* Re-fix IRQs */ - irq_restore(old); - return cnt; } @@ -193,10 +185,9 @@ void genwait_wake_all_err(void *obj, int err) { int genwait_wake_thd(void *obj, kthread_t *thd, int err) { kthread_t *t, *nt; struct slpquehead *qp; - int old, rv = 0; /* Twiddle interrupt state */ - old = irq_disable(); + irq_disable_scoped(); /* Find the queue */ qp = &slpque[LOOKUP(obj)]; @@ -221,15 +212,11 @@ int genwait_wake_thd(void *obj, kthread_t *thd, int err) { } /* We found it, so we're done... */ - rv = 1; - break; + return 1; } } - /* Re-fix IRQs */ - irq_restore(old); - - return rv; + return 0; } void genwait_check_timeouts(uint64 tm) { diff --git a/kernel/thread/mutex.c b/kernel/thread/mutex.c index c8f84735..38abc2ed 100644 --- a/kernel/thread/mutex.c +++ b/kernel/thread/mutex.c @@ -52,31 +52,28 @@ int mutex_init(mutex_t *m, int mtype) { } int mutex_destroy(mutex_t *m) { - int rv = 0, old; - - old = irq_disable(); + irq_disable_scoped(); if(m->type < MUTEX_TYPE_NORMAL || m->type > MUTEX_TYPE_RECURSIVE) { errno = EINVAL; - rv = -1; + return -1; } - else if(m->count) { + + if(m->count) { /* Send an error if its busy */ errno = EBUSY; - rv = -1; - } - else { - /* Set it to an invalid type of mutex */ - m->type = -1; + return -1; } + /* Set it to an invalid type of mutex */ + m->type = -1; + /* If the mutex was created with the deprecated mutex_create(), free it. */ if(m->dynamic) { free(m); } - irq_restore(old); - return rv; + return 0; } int mutex_lock(mutex_t *m) { @@ -92,7 +89,7 @@ int mutex_lock_irqsafe(mutex_t *m) { int mutex_lock_timed(mutex_t *m, int timeout) { uint64_t deadline = 0; - int old, rv = 0; + int rv = 0; if((rv = irq_inside_int())) { dbglog(DBG_WARNING, "%s: called inside an interrupt with code: " @@ -108,7 +105,7 @@ int mutex_lock_timed(mutex_t *m, int timeout) { return -1; } - old = irq_disable(); + irq_disable_scoped(); if(m->type < MUTEX_TYPE_NORMAL || m->type > MUTEX_TYPE_RECURSIVE) { errno = EINVAL; @@ -160,7 +157,6 @@ int mutex_lock_timed(mutex_t *m, int timeout) { } } - irq_restore(old); return rv; } @@ -169,10 +165,9 @@ int mutex_is_locked(mutex_t *m) { } int mutex_trylock(mutex_t *m) { - int old, rv = 0; kthread_t *thd = thd_current; - old = irq_disable(); + irq_disable_scoped(); /* If we're inside of an interrupt, pick a special value for the thread that would otherwise be impossible... */ @@ -181,49 +176,46 @@ int mutex_trylock(mutex_t *m) { if(m->type < MUTEX_TYPE_NORMAL || m->type > MUTEX_TYPE_RECURSIVE) { errno = EINVAL; - rv = -1; + return -1; } + /* Check if the lock is held by some other thread already */ - else if(m->count && m->holder != thd) { + if(m->count && m->holder != thd) { errno = EAGAIN; - rv = -1; + return -1; } - else { - m->holder = thd; - - switch(m->type) { - case MUTEX_TYPE_NORMAL: - case MUTEX_TYPE_OLDNORMAL: - case MUTEX_TYPE_ERRORCHECK: - if(m->count) { - errno = EDEADLK; - rv = -1; - } - else { - m->count = 1; - } - break; - case MUTEX_TYPE_RECURSIVE: - if(m->count == INT_MAX) { - errno = EAGAIN; - rv = -1; - } - else { - ++m->count; - } - break; - } + m->holder = thd; + + switch(m->type) { + case MUTEX_TYPE_NORMAL: + case MUTEX_TYPE_OLDNORMAL: + case MUTEX_TYPE_ERRORCHECK: + if(m->count) { + errno = EDEADLK; + return -1; + } + + m->count = 1; + break; + + case MUTEX_TYPE_RECURSIVE: + if(m->count == INT_MAX) { + errno = EAGAIN; + return -1; + } + + ++m->count; + break; } - irq_restore(old); - return rv; + return 0; } static int mutex_unlock_common(mutex_t *m, kthread_t *thd) { - int old, rv = 0, wakeup = 0; + int wakeup = 0; - old = irq_disable(); + irq_disable_scoped(); switch(m->type) { case MUTEX_TYPE_NORMAL: @@ -236,21 +228,21 @@ static int mutex_unlock_common(mutex_t *m, kthread_t *thd) { case MUTEX_TYPE_ERRORCHECK: if(m->holder != thd) { errno = EPERM; - rv = -1; - } ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |