diff --git a/src/kernel/lock/spinlock.c b/src/kernel/lock/spinlock.c index 36c20758fb887c58d5ad6af53a18b308fd357d84..4224515432b0e01e865cae75044519ee8c03826a 100644 --- a/src/kernel/lock/spinlock.c +++ b/src/kernel/lock/spinlock.c @@ -35,23 +35,54 @@ void pop_off(void) // 自选锁初始化 void spinlock_init(spinlock_t *lk, char *name) { - + lk->locked = 0; // 初始状态:未持有锁 + lk->name = name; // 设置锁的名称(用于调试) + lk->cpuid = -1; // 初始无持有者(-1表示未持有) } // 是否持有自旋锁 bool spinlock_holding(spinlock_t *lk) { - + // 比较当前CPU的ID与锁的持有者ID + return lk->cpuid == mycpu()->id; } // 获取自选锁 void spinlock_acquire(spinlock_t *lk) { + // 关闭中断(使用带计数的push_off,支持嵌套) + push_off(); + + // 断言:当前CPU未持有该锁(防止递归获取导致死锁) + assert(!spinlock_holding(lk), "spinlock_acquire: already holding lock %s\n", lk->name); + + // 原子操作:循环等待锁释放,获取成功后将locked设为1 + // __sync_lock_test_and_set 是GCC内置原子操作,返回旧值 + while (__sync_lock_test_and_set(&lk->locked, 1) != 0) + ; // 锁被占用时自旋等待 + // 内存屏障:确保锁获取后的操作不会被编译器/CPU重排到获取锁之前 + __sync_synchronize(); + + // 记录当前CPU为锁的持有者 + lk->cpuid = mycpu()->id; } // 释放自旋锁 void spinlock_release(spinlock_t *lk) { + // 断言:当前CPU必须持有该锁才能释放 + assert(spinlock_holding(lk), "spinlock_release: not holding lock %s\n", lk->name); + + // 清除持有者信息 + lk->cpuid = -1; + + // 内存屏障:确保释放锁前的操作不会被编译器/CPU重排到释放锁之后 + __sync_synchronize(); + + // 原子操作:释放锁(将locked设为0) + __sync_lock_release(&lk->locked); + // 恢复中断状态(与push_off对应,支持嵌套) + pop_off(); } \ No newline at end of file