免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2936 | 回复: 7
打印 上一主题 下一主题

[内核同步] 请教一下自旋锁实现的问题 [复制链接]

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-07-04 16:24 |只看该作者 |倒序浏览
5可用积分
不好意思,身上实在是没分了,以后再补吧
体系结构arm,内核版本3.10.17,以下这段代码是arm中自旋锁的实现,网上资料太少了,实在没看懂这里是如何实现自旋锁的功能的
请懂的朋友帮帮忙,分确实少了,以后赚了分再给您,多谢

最好可以帮忙解释一下这段代码
static inline void arch_spin_lock(arch_spinlock_t *lock)
{
        unsigned long tmp;
        u32 newval;
        arch_spinlock_t lockval;

        __asm__ __volatile__(
"1:        ldrex        %0, [%3]\n"
"        add        %1, %0, %4\n"
"        strex        %2, %1, [%3]\n"
"        teq        %2, #0\n"
"        bne        1b"
        : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
        : "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
        : "cc");

        while (lockval.tickets.next != lockval.tickets.owner) {/*目测这里是在自旋忙等,可是这里使用的判断条件和上面没有关系啊*/
                wfe();
                lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner);
        }

        smp_mb();
}

最佳答案

查看完整内容

typedef struct { union { u32 slock; struct __raw_tickets {#ifdef __ARMEB__ u16 next; u16 owner;#else u16 owner; u16 next;#endif } tickets; };} arch_spinlock_t;static inline void arch_spin_lock(arch_spinlock_t *lock){ unsigned long tmp; u32 newval; arch_spinlock_t lockval; __asm__ __volatile__("1: ldrex %0, [%3]\n" " add %1, %0, %4\n" ...

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
2 [报告]
发表于 2014-07-04 16:24 |只看该作者
本帖最后由 arm-linux-gcc 于 2014-07-04 17:19 编辑

typedef struct {
        union {
                u32 slock;
                struct __raw_tickets {
#ifdef __ARMEB__
                        u16 next;
                        u16 owner;
#else
                        u16 owner;
                        u16 next;

#endif
                } tickets;
        };
} arch_spinlock_t;

static inline void arch_spin_lock(arch_spinlock_t *lock)
{
        unsigned long tmp;
        u32 newval;
        arch_spinlock_t lockval;

        __asm__ __volatile__(
"1:        ldrex        %0, [%3]\n"                                          
"        add        %1, %0, %4\n"                                      对next++
"        strex        %2, %1, [%3]\n"                           
"        teq        %2, #0\n"
"        bne        1b"
        : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
        : "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
        : "cc");

        while (lockval.tickets.next != lockval.tickets.owner) {
                wfe();
                lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner);           
        }

        smp_mb();
}

static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
        smp_mb();
        lock->tickets.owner++;             对owner++
        dsb_sev();                                
}

释放锁就会让owner++
持有锁就会让next++
用两个计数器分别来表示“释放次数”和“加锁次数
当owner和next数量相等时,才说明当前线程成功的持有了锁

用两个计数器是出于性能考虑,这样就可以保证不同的cpu core不用竞争同一个地址,原因:
在arch_spin_lock里面使用了一个局部变量,于是不同执行流中的arch_spin_lock/arch_spin_unlock就不会写同一个cache line,
也就是不需要与别的core上的arch_spin_lock/arch_spin_unlock流程去竞争同一个cache line,
避免了两个core相互将对方的cache line write invalid的问题,于是就避免了cache miss的问题,从而保证了性能









评分

参与人数 1可用积分 +6 收起 理由
Godbach + 6 赞一个!

查看全部评分

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
3 [报告]
发表于 2014-07-04 16:27 |只看该作者
回复 1# super皮波

请自行搜索  ticket spinlocks @  lwn.net

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
4 [报告]
发表于 2014-07-04 17:14 |只看该作者
可用积分到底是用来干嘛的啊?

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
5 [报告]
发表于 2014-07-04 17:17 |只看该作者
我感觉最大的用处就是可以参加竞拍
回复 4# arm-linux-gcc


   

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
6 [报告]
发表于 2014-07-04 17:18 |只看该作者
兄弟,多谢了,按照你的回帖在网上找了下资料,弄明白了,再次感谢
回复 3# asuka2001


   

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
7 [报告]
发表于 2014-07-04 17:44 |只看该作者
本帖最后由 asuka2001 于 2014-07-04 17:50 编辑

回复 2# arm-linux-gcc

两个计数器理解为:下一个人的“排队号”和当前的“呼叫号”更为确切些。

竞争锁就是去取这个排队号,然后把这个号原子性加1,防止其他人拿到和自己相同的排队号,然后坐等释放锁的人呼叫自己的排队号既可!

释放锁时将呼叫号加1,即当前持有锁的人已经服务完了,呼叫下一位排队等待的兄弟来拿锁!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP