forked from Mirrors/opensbi
lib: sbi: Replace test-and-set locks by ticket locks
Replace the test-and-set spinlock implementation with ticket locks in order to get fairness (in form of FIFO order). The implementation uses a 32-bit wide struct, which consists of two 16-bit counters (owner and next). This is inspired by similar spinlock implementations on other architectures. This allows that the code works for both, RV32 and RV64. Signed-off-by: Christoph Muellner <cmuellner@linux.com> Reviewed-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Xiang W <wxjstz@126.com>
This commit is contained in:

committed by
Anup Patel

parent
d0e406fa44
commit
4d8e2f135d
@@ -2,26 +2,37 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
|
||||
*
|
||||
* Authors:
|
||||
* Anup Patel <anup.patel@wdc.com>
|
||||
* Copyright (c) 2021 Christoph Müllner <cmuellner@linux.com>
|
||||
*/
|
||||
|
||||
#ifndef __RISCV_LOCKS_H__
|
||||
#define __RISCV_LOCKS_H__
|
||||
|
||||
#include <sbi/sbi_types.h>
|
||||
|
||||
#define TICKET_SHIFT 16
|
||||
|
||||
typedef struct {
|
||||
volatile long lock;
|
||||
} spinlock_t;
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
u16 next;
|
||||
u16 owner;
|
||||
#else
|
||||
u16 owner;
|
||||
u16 next;
|
||||
#endif
|
||||
} __aligned(4) spinlock_t;
|
||||
|
||||
#define __RISCV_SPIN_UNLOCKED 0
|
||||
#define __SPIN_LOCK_UNLOCKED \
|
||||
(spinlock_t) { 0, 0 }
|
||||
|
||||
#define SPIN_LOCK_INIT(x) (x).lock = __RISCV_SPIN_UNLOCKED
|
||||
#define SPIN_LOCK_INIT(x) \
|
||||
x = __SPIN_LOCK_UNLOCKED
|
||||
|
||||
#define SPIN_LOCK_INITIALIZER \
|
||||
{ \
|
||||
.lock = __RISCV_SPIN_UNLOCKED, \
|
||||
}
|
||||
#define SPIN_LOCK_INITIALIZER \
|
||||
__SPIN_LOCK_UNLOCKED
|
||||
|
||||
#define DEFINE_SPIN_LOCK(x) \
|
||||
spinlock_t SPIN_LOCK_INIT(x)
|
||||
|
||||
int spin_lock_check(spinlock_t *lock);
|
||||
|
||||
|
Reference in New Issue
Block a user