Skip to content

Add basic kernel locks#33

Open
theduccom wants to merge 19 commits intotrunkfrom
locking
Open

Add basic kernel locks#33
theduccom wants to merge 19 commits intotrunkfrom
locking

Conversation

@theduccom
Copy link

  • Adds a spinlock that disables interrupts
  • Adds a hartlock, which disables interrupts

theduccom and others added 13 commits August 3, 2025 15:10
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Copy link
Member

@remexre remexre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sleepy so did not apply filter; feel free to push back on these if i'm being too nit-picky

*
* Return: u32 1 if SIE bit in SSTATUS is set, 0 otherwise.
*/
static inline u32 get_irq_state(void) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not bool, and maybe a name like are_interrupts_enabled?

Comment on lines 14 to 27
static inline void irq_enable(void) {
u64 sstatus = csrr(RISCV64_CSR_SSTATUS);
csrw(RISCV64_CSR_SSTATUS, (sstatus | RISCV64_SSTATUS_SIE));
}

/**
* irq_disable - Disables interrupt requests.
*
* Masks the SIE (supervisor interrupt enable) flag in the SSTATUS CSR.
*/
static inline void irq_disable(void) {
u64 sstatus = csrr(RISCV64_CSR_SSTATUS);
csrw(RISCV64_CSR_SSTATUS, (sstatus & ~RISCV64_SSTATUS_SIE));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should probably use CSRS and CSRC, so that they're atomic. Right now, context switches can happen between the csrr and csrw. I think you'll need to add those helpers to arch/riscv64/insns.h -- should just be a find-and-replace on csrw.

*
* Disables interrupts to prevent the current thread from being moved
* to another hart. This does not provide mutual exclusion, nor does it
* prevent the thread from blocking. It only ensures that the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nor does it prevent the thread from blocking

Shouldn't it? Blocking operations should allow context-switching.

*
* Initializes a spinlock that disables interrupts.
*/
void initlock(struct spinlock *sp, const char *name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefix the names of these with spinlock_, since we're planning on having multiple kinds of locks; e.g. spinlock_init, spinlock_lock, spinlock_unlock? (_acquire/_release is fine too, but should be consistent with hartlock)

Comment on lines 22 to 23
while (__sync_lock_test_and_set(&sp->state, 1) != 0) {}
__sync_synchronize();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__sync functions are legacy per GCC docs; use stdatomic.h instead; using the right memory orderings probably actually helps performance in practice, too

#include "spinlock.h"

/* Returns 1 if thread is holding the specified spinlock */
u32 holding(struct spinlock *sp) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this return bool? should it be static?

#include "insns.h"
#include "types.h"

#define RISCV64_SSTATUS_SIE (1UL << 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer constexpr to #define (better typechecking and error reporting)

/* Returns 1 if thread is holding the specified spinlock */
u32 holding(struct spinlock *sp) {
struct hart_locals *hart = get_hart_locals();
return ((sp->state == 1) && (sp->hart == hart));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either make state atomic or use atomic load here

* was called. If interrupts were already disabled, they remain disabled.
*/
void hart_unlock(void);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_hart_locked would be nice-to-have for e.g. get_hart_locals to assert on

@@ -0,0 +1,40 @@
#ifndef UKO_OS_KERNEL__IRQ_H
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, didn't realize this was going to so closely correspond to what's in hartlock.c -- one thing you can do is to have an arch-independent foo.h, but put the .c under arch/

Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
@remexre remexre added the X: stale This issue or PR possibly no longer applies label Nov 9, 2025
@remexre
Copy link
Member

remexre commented Nov 9, 2025

@theduccom Do you think you'll have time to get this up-to-date and respond to the review feedback? I'm planning on doing #9 soon, and I'll need hartlocks by then.

Signed-off-by: theduccom <145524869+theduccom@users.noreply.github.com>
@theduccom theduccom requested a review from remexre November 13, 2025 01:53
@auctumnus auctumnus mentioned this pull request Jan 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

X: stale This issue or PR possibly no longer applies

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments