内核同步机制-自旋锁(spin_lock)

发布时间 2023-03-31 08:29:29作者: lydstory
typedef struct spinlock {
	union {
		struct raw_spinlock rlock; //自旋锁的核心成员是和raw_spinlock锁。
 
#ifdef CONFIG_DEBUG_LOCK_ALLOC //如果打开次配置,会增加调试信息存储
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
		struct {
			u8 __padding[LOCK_PADSIZE];
			struct lockdep_map dep_map;
		};
#endif
	};
} spinlock_t;
 
//这里如果打开的CONFIG_PREEMPT_RT开始,spinlock会被转化成rt_mutex,实时内核需要注意这里会睡眠
/* PREEMPT_RT kernels map spinlock to rt_mutex */
#include <linux/rtmutex.h>
typedef struct spinlock {
        struct rt_mutex_base    lock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
        struct lockdep_map      dep_map;
#endif
} spinlock_t;
 
 
 
typedef struct raw_spinlock {
        arch_spinlock_t raw_lock; /*该成员变量是自旋锁数据类型的核心,
它展开后实质上是一个Volatile unsigned类型的变量。具体的锁定过程与它密切
相关,该变量依赖于内核选项CONFIG_SMP*/
#ifdef CONFIG_DEBUG_SPINLOCK
        unsigned int magic, owner_cpu; //所拥有者所在的CPU
        void *owner; //锁的持有者
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
        struct lockdep_map dep_map; //调试使用,定义一个锁对象
#endif
} raw_spinlock_t;
 
typedef struct  {  volatile int counter;  }  atomic_t; 
/*x86/arm64 arch_spinlock_t数据结构,val是一个32位原子类型整数;
与二个16位的locked_pending(0-15) tail(16-31)共享内存;同时
与四个8位的locked(0-7), pending(8-15),2位idx + 14位cpu共享内存,
函数中具体通过掩码和位偏移来确定,可以看下文掩码相关详解*/
 
|     cpu    |idx|pending locked |-->小端
|     tail       |locked_pending |
|               val              | 
31---------------15--------------0
typedef struct qspinlock {
	union {
		atomic_t val;
 
		/*
		 * By using the whole 2nd least significant byte for the
		 * pending bit, we can allow better optimization of the lock
		 * acquisition for the pending bit holder.
		 */
#ifdef __LITTLE_ENDIAN
		struct {
			u8	locked; //可以理解为最优先持锁标志,即当unlock之后只有这个位的CPU最先持锁,也只会有1和0
			u8	pending; //用来表示这个锁是否被人持有,只会有1和0两种情况,即1被人持有,0无人持锁
		};
		struct {
			u16	locked_pending;//由locked 和 pending构成
			u16	tail;//由idx CPU构成,用来标识等待队列最后一个节点
		};
#else
		struct {
			u16	tail; 
			u16	locked_pending;
		};
		struct {
			u8	reserved[2];
			u8	pending;
			u8	locked;
		};
#endif
	};
} arch_spinlock_t;
 
 
/*arm arch_spinlock_t 数据结构slock是一个32位无符号整数,与无符号16位整数owner
 和 next共享内存空间,owner占低16位(0-15),next占高16(16-31)数据分布*/
|      next     |     owner     |
|              slock            | 
----------------15---------------
typedef struct {
	union {
		u32 slock;
		struct __raw_tickets {
#ifdef __ARMEB__
			u16 next;
			u16 owner;
#else
			u16 owner;
			u16 next;
#endif
		} tickets;
	};
} arch_spinlock_t;

  https://blog.csdn.net/hzj_001/article/details/125860225