From 4d8e2f135d659697337f8d4a33fec60cd475f0dc Mon Sep 17 00:00:00 2001 From: Christoph Muellner Date: Tue, 6 Apr 2021 03:53:54 +0200 Subject: 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 Reviewed-by: Anup Patel Reviewed-by: Xiang W --- include/sbi/riscv_locks.h | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'include/sbi/riscv_locks.h') diff --git a/include/sbi/riscv_locks.h b/include/sbi/riscv_locks.h index faa9676..492935f 100644 --- a/include/sbi/riscv_locks.h +++ b/include/sbi/riscv_locks.h @@ -2,26 +2,37 @@ * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Western Digital Corporation or its affiliates. - * - * Authors: - * Anup Patel + * Copyright (c) 2021 Christoph Müllner */ #ifndef __RISCV_LOCKS_H__ #define __RISCV_LOCKS_H__ +#include + +#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 __SPIN_LOCK_UNLOCKED \ + (spinlock_t) { 0, 0 } -#define __RISCV_SPIN_UNLOCKED 0 +#define SPIN_LOCK_INIT(x) \ + x = __SPIN_LOCK_UNLOCKED -#define SPIN_LOCK_INIT(x) (x).lock = __RISCV_SPIN_UNLOCKED +#define SPIN_LOCK_INITIALIZER \ + __SPIN_LOCK_UNLOCKED -#define SPIN_LOCK_INITIALIZER \ - { \ - .lock = __RISCV_SPIN_UNLOCKED, \ - } +#define DEFINE_SPIN_LOCK(x) \ + spinlock_t SPIN_LOCK_INIT(x) int spin_lock_check(spinlock_t *lock); -- cgit v1.2.3