191 lines
6.6 KiB
C
191 lines
6.6 KiB
C
/*
|
||
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
|
||
* Description: oal_spinlock.h 的头文件
|
||
* Author: Hisilicon
|
||
* Create: 2020-08-04
|
||
*/
|
||
|
||
#ifndef __OAL_SPINLOCK_H__
|
||
#define __OAL_SPINLOCK_H__
|
||
|
||
/*****************************************************************************
|
||
1 其他头文件包含
|
||
*****************************************************************************/
|
||
#include <linux/spinlock.h>
|
||
|
||
#ifdef __cplusplus
|
||
#if __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
#endif
|
||
|
||
/*****************************************************************************
|
||
2 宏定义
|
||
*****************************************************************************/
|
||
typedef spinlock_t oal_spinlock;
|
||
|
||
#define OAL_SPIN_LOCK_MAGIC_TAG (0xdead4ead)
|
||
typedef struct _oal_spin_lock_stru_ {
|
||
#ifdef CONFIG_SPIN_LOCK_MAGIC_DEBUG
|
||
hi_u32 magic;
|
||
hi_u32 reserved;
|
||
#endif
|
||
spinlock_t lock;
|
||
} oal_spin_lock_stru;
|
||
|
||
#ifdef CONFIG_SPIN_LOCK_MAGIC_DEBUG
|
||
#define oal_define_spinlock(x) oal_spin_lock_stru x = { \
|
||
.magic = OAL_SPIN_LOCK_MAGIC_TAG, \
|
||
.lock = __SPIN_LOCK_UNLOCKED(x)}
|
||
#else
|
||
#define oal_define_spinlock(x) oal_spin_lock_stru x = { \
|
||
.lock = __SPIN_LOCK_UNLOCKED(x)}
|
||
#endif
|
||
|
||
/* 函数指针,用来指向需要自旋锁保护的的函数 */
|
||
typedef hi_u32(*oal_irqlocked_func)(hi_void *);
|
||
|
||
/* inline 函数定义 */
|
||
/*****************************************************************************
|
||
功能描述 : 自旋锁初始化,把自旋锁设置为1(未锁状态)。
|
||
输入参数 : *pst_lock: 锁的地址
|
||
输出参数 : 无
|
||
返 回 值 :
|
||
*****************************************************************************/
|
||
static inline hi_void oal_spin_lock_init(oal_spin_lock_stru *pst_lock)
|
||
{
|
||
spin_lock_init(&pst_lock->lock);
|
||
#ifdef CONFIG_SPIN_LOCK_MAGIC_DEBUG
|
||
pst_lock->magic = OAL_SPIN_LOCK_MAGIC_TAG;
|
||
#endif
|
||
}
|
||
#define SPIN_LOCK_CONSTANT (32)
|
||
static inline hi_void oal_spin_lock_magic_bug(oal_spin_lock_stru *pst_lock)
|
||
{
|
||
#ifdef CONFIG_SPIN_LOCK_MAGIC_DEBUG
|
||
if (oal_unlikely((hi_u32)OAL_SPIN_LOCK_MAGIC_TAG != pst_lock->magic)) {
|
||
#ifdef CONFIG_PRINTK
|
||
/* spinlock never init or memory overwrite */
|
||
printk(KERN_EMERG "[E]SPIN_LOCK_BUG: spinlock:%p on CPU#%d, %s,magic:%08x should be %08x\n", pst_lock,
|
||
raw_smp_processor_id(), current->comm, pst_lock->magic, OAL_SPIN_LOCK_MAGIC_TAG);
|
||
print_hex_dump(KERN_EMERG, "spinlock_magic: ", DUMP_PREFIX_ADDRESS, 16, 1, /* 16:hex */
|
||
(hi_u8 *)((uintptr_t)pst_lock - SPIN_LOCK_CONSTANT),
|
||
SPIN_LOCK_CONSTANT + sizeof(oal_spin_lock_stru) + SPIN_LOCK_CONSTANT, true);
|
||
printk(KERN_EMERG"\n");
|
||
#endif
|
||
}
|
||
#else
|
||
hi_unref_param(pst_lock);
|
||
#endif
|
||
}
|
||
|
||
/*****************************************************************************
|
||
功能描述 : 自旋锁在软中断以及内核线程等核心态上下文环境下的加锁操作。如果
|
||
能够立即获得锁,它就马上返回,否则,它将自旋在那里,直到该自旋
|
||
锁的保持者释放,这时,它获得锁并返回。
|
||
输入参数 : *pst_lock:自旋锁地址
|
||
输出参数 : 无
|
||
返 回 值 :
|
||
*****************************************************************************/
|
||
static inline hi_void oal_spin_lock(oal_spin_lock_stru *pst_lock)
|
||
{
|
||
oal_spin_lock_magic_bug(pst_lock);
|
||
spin_lock(&pst_lock->lock);
|
||
}
|
||
|
||
/*****************************************************************************
|
||
功能描述 : Spinlock在内核线程等核心态上下文环境下的解锁操作。
|
||
输入参数 : *pst_lock:自旋锁地址
|
||
输出参数 : 无
|
||
返 回 值 :
|
||
*****************************************************************************/
|
||
static inline hi_void oal_spin_unlock(oal_spin_lock_stru *pst_lock)
|
||
{
|
||
oal_spin_lock_magic_bug(pst_lock);
|
||
spin_unlock(&pst_lock->lock);
|
||
}
|
||
|
||
/*****************************************************************************
|
||
功能描述 : 自旋锁在软中断以及内核线程等核心态上下文环境下的加锁操作。如果
|
||
能够立即获得锁,它就马上返回,否则,它将自旋在那里,直到该自旋
|
||
锁的保持者释放,这时,它获得锁并返回。
|
||
输入参数 : pst_lock:自旋锁地址
|
||
输出参数 : 无
|
||
返 回 值 :
|
||
*****************************************************************************/
|
||
static inline hi_void oal_spin_lock_bh(oal_spin_lock_stru *pst_lock)
|
||
{
|
||
oal_spin_lock_magic_bug(pst_lock);
|
||
spin_lock_bh(&pst_lock->lock);
|
||
}
|
||
|
||
/*****************************************************************************
|
||
功能描述 : Spinlock在软中断以及内核线程等核心态上下文环境下的解锁操作。
|
||
输入参数 : 无
|
||
输出参数 : 无
|
||
返 回 值 : hi_void
|
||
*****************************************************************************/
|
||
static inline hi_void oal_spin_unlock_bh(oal_spin_lock_stru *pst_lock)
|
||
{
|
||
oal_spin_lock_magic_bug(pst_lock);
|
||
spin_unlock_bh(&pst_lock->lock);
|
||
}
|
||
|
||
/*****************************************************************************
|
||
功能描述 : 获得自旋锁的同时获得保存标志寄存器的值,并且失效本地中断。
|
||
输入参数 : *pst_lock:自旋锁地址
|
||
pui_flags:标志寄存器
|
||
输出参数 : 无
|
||
返 回 值 :
|
||
*****************************************************************************/
|
||
static inline hi_void oal_spin_lock_irq_save(oal_spin_lock_stru *pst_lock, unsigned long *pui_flags)
|
||
{
|
||
oal_spin_lock_magic_bug(pst_lock);
|
||
spin_lock_irqsave(&pst_lock->lock, *pui_flags);
|
||
}
|
||
|
||
/*****************************************************************************
|
||
功能描述 : 释放自旋锁的同时,恢复标志寄存器的值,恢复本地中断。它与oal_sp-
|
||
in_lock_irq配对使用
|
||
输入参数 : *pst_lock:自旋锁地址
|
||
pui_flags:标志寄存器
|
||
输出参数 : 无
|
||
返 回 值 :
|
||
*****************************************************************************/
|
||
static inline hi_void oal_spin_unlock_irq_restore(oal_spin_lock_stru *pst_lock, unsigned long *pui_flags)
|
||
{
|
||
oal_spin_lock_magic_bug(pst_lock);
|
||
spin_unlock_irqrestore(&pst_lock->lock, *pui_flags);
|
||
}
|
||
|
||
/*****************************************************************************
|
||
功能描述 : 获取自旋锁,关闭中断,执行某个函数,完了之后再打开中断,释放自
|
||
旋锁。
|
||
输入参数 : *pst_lock:自旋锁地址
|
||
func:函数指针地址
|
||
*p_arg:函数参数
|
||
*pui_flags: 中断标志寄存器
|
||
输出参数 : 无
|
||
返 回 值 :
|
||
*****************************************************************************/
|
||
static inline hi_u32 oal_spin_lock_irq_exec(oal_spin_lock_stru *pst_lock, oal_irqlocked_func func,
|
||
hi_void *p_arg, unsigned long *pui_flags)
|
||
{
|
||
hi_u32 ul_rslt;
|
||
|
||
spin_lock_irqsave(&pst_lock->lock, *pui_flags);
|
||
ul_rslt = func(p_arg);
|
||
spin_unlock_irqrestore(&pst_lock->lock, *pui_flags);
|
||
|
||
return ul_rslt;
|
||
}
|
||
|
||
#ifdef __cplusplus
|
||
#if __cplusplus
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
#endif /* end of oal_spinlock.h */
|
||
|