Add _irqsave variant of spinlocks
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "sys/types.h"
|
||||
|
||||
#if defined(ARCH_AMD64)
|
||||
#include "sys/amd64/sys/spin.h"
|
||||
@@ -6,3 +7,5 @@
|
||||
|
||||
void spin_lock(spin_t *s);
|
||||
void spin_release(spin_t *s);
|
||||
void spin_lock_irqsave(spin_t *s, uintptr_t *irq);
|
||||
void spin_release_irqrestore(spin_t *s, uintptr_t *irq);
|
||||
|
||||
@@ -17,6 +17,7 @@ static struct thread t_idle[AMD64_MAX_SMP] = {0};
|
||||
void idle_func(uintptr_t id) {
|
||||
while (1) {
|
||||
kdebug("%d\n", id);
|
||||
asm volatile ("sti; hlt");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
.section .text
|
||||
.global spin_lock
|
||||
.global spin_release
|
||||
.global spin_lock_irqsave
|
||||
.global spin_release_irqrestore
|
||||
|
||||
// TODO: maybe add some tracing to this so I know
|
||||
// the locks that consume too much CPU time
|
||||
spin_lock_irqsave:
|
||||
pushfq
|
||||
popq %rax
|
||||
movq %rax, (%rsi)
|
||||
cli
|
||||
|
||||
spin_lock:
|
||||
// %rdi - spinlock
|
||||
lock bts $1, (%rdi)
|
||||
@@ -17,6 +25,13 @@ spin_lock:
|
||||
jnz 1b
|
||||
jmp spin_lock
|
||||
|
||||
spin_release_irqrestore:
|
||||
movq $0, (%rdi)
|
||||
testq $(1 << 9), (%rsi)
|
||||
jz 1f
|
||||
sti
|
||||
1:
|
||||
retq
|
||||
|
||||
spin_release:
|
||||
movq $0, (%rdi)
|
||||
|
||||
+3
-4
@@ -160,9 +160,8 @@ void debugf(int level, const char *f, ...) {
|
||||
}
|
||||
|
||||
void debugfv(int level, const char *fmt, va_list args) {
|
||||
// FIXME Problem: if this code gets interrupted while
|
||||
// inside the locked region, the CPU freezes
|
||||
spin_lock(&debug_spin);
|
||||
uintptr_t irq;
|
||||
spin_lock_irqsave(&debug_spin, &irq);
|
||||
|
||||
char c;
|
||||
union {
|
||||
@@ -295,6 +294,6 @@ void debugfv(int level, const char *fmt, va_list args) {
|
||||
++fmt;
|
||||
}
|
||||
|
||||
spin_release(&debug_spin);
|
||||
spin_release_irqrestore(&debug_spin, &irq);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user