Skip to content

Commit bf917a1

Browse files
committed
[libcpu-riscv]: [surpport SMP]: Fix the overflow issue of the spinlock's owner field
The owner field is of type unsigned short. When 0xffff is incremented by 1, it will wrap around to 0 and carry over, causing errors in the ticket field. Solution: When the owner field is 0xffff, simply set it to 0 manually. Signed-off-by: Mengchen Teng <teng_mengchen@163.com>
1 parent 9cdbc36 commit bf917a1

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

libcpu/risc-v/virt64/interrupt.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,20 @@ void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
158158
/* Ensure memory operations before unlock are visible before owner increment */
159159
__asm__ volatile("fence rw, rw" ::: "memory");
160160

161-
/* Increment owner (low 16 bits) to hand over lock to next ticket */
162-
rt_hw_atomic_add((volatile rt_atomic_t *)&lock->slock, (rt_atomic_t)1);
161+
/* Increment owner (low 16 bits) to hand over lock to next ticket.
162+
* Use an atomic load of the combined slock word and compare the low
163+
* 16-bit owner field.If owner would overflow (0xffff), clear the owner field
164+
* atomically by ANDing with 0xffff0000; otherwise increment owner by 1.
165+
*/
166+
if ((rt_hw_atomic_load((volatile rt_atomic_t *)&lock->slock) & (rt_atomic_t)0xffffUL) == (rt_atomic_t)0xffffUL)
167+
{
168+
/* Atomic clear owner (low 16 bits) when it overflows. Keep next ticket field. */
169+
rt_hw_atomic_and((volatile rt_atomic_t *)&lock->slock, (rt_atomic_t)0xffff0000UL);
170+
}
171+
else
172+
{
173+
rt_hw_atomic_add((volatile rt_atomic_t *)&lock->slock, (rt_atomic_t)1);
174+
}
163175

164176
// TODO: IPI interrupt to wake up other harts waiting for the lock
165177

0 commit comments

Comments
 (0)