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;
内核同步机制-自旋锁(spin_lock)
发布时间 2023-03-31 08:29:29作者: lydstory