免费注册 查看新帖 |

Chinaunix

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

[内核同步] ticket自旋锁中的__ticket_spin_trylock疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-06-14 18:55 |只看该作者 |倒序浏览
在TICKET自旋锁中,第086行的leal语句是作什么用的?对于该行不太清楚。整个代码的内容应大概流程应该当是:

1、tmp = lock->slock,判断Select == Owner,若不等给tmp = 0;若相同则执行第2步;
2、利用cmpxchgw比较原先slock的tmp 8~32位和当前slock的8~32位(即select)是否未发生变化。若相同则给slock->select++,tmp = 1,终止;已发生变化则tmp = 0,终止。



080 static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
081 {
082         int tmp, new;
083
084         asm volatile("movzwl %2, %0\n\t"
085                      "cmpb %h0,%b0\n\t"
086                      "leal 0x100(%" REG_PTR_MODE "0), %1\n\t"
087                      "jne 1f\n\t"
088                      LOCK_PREFIX "cmpxchgw %w1,%2\n\t"
089                      "1:"
090                      "sete %b1\n\t"
091                      "movzbl %b1,%0\n\t"
092                      : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
093                      :
094                      : "memory", "cc");
095
096         return tmp;
097 }

论坛徽章:
0
2 [报告]
发表于 2012-06-15 16:33 |只看该作者
本帖最后由 wenlujon 于 2012-06-15 16:53 编辑

将"next"字段增加1.

080 static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
081 {
082         int tmp, new;
083
084         asm volatile("movzwl %2, %0\n\t"                                                          // 将lock->slock放到本地变量tmp中
085                      "cmpb %h0,%b0\n\t"                                                               // 比较tmp的高8位和低8位,也就是"next"字段和"owner"字段,如果相等,ZF设置为1,否则ZF被设为0
086                      "leal 0x100(%" REG_PTR_MODE "0), %1\n\t"                             // 将tmp得高8位或上0x100,其实就是将其高8位加1的值放到本地变量new中
087                      "jne 1f\n\t"                                                                             // 判断ZF标志位,如果0(就是说85行的结果是不相等),跳到89行,否则执行下一句
088                      LOCK_PREFIX "cmpxchgw %w1,%2\n\t"                                    // 尝试去获取锁。比较lock->slock和eax是否相等(其实就是tmp,因为tmp是放到eax里面的),但是84行不是已经将lock->slock放到tmp里面了吗?为何这里还需要再次比较? 原因是从84行到这行的这段时间,这个lock->slock可能被其他的processor修改。如果相等了,将new(注意new的高8位在86行相对其原来的值已经增加1了)放到lock->slock,说白了,就是原子性的将lock->slock的高8位加1,这个时候,锁被获取到。同时设置ZF为1;如果不相等的话,说明锁被其他processor获取了,ZF被设置为0,lock->slock的值放到EAX。
                              
089                      "1:"                                                                                       //
090                      "sete %b1\n\t"                                                                      // 如果ZF为1,也就是说锁被获取了,将new的低8位设置为1;如果ZF为0,表明不能获取锁,将new的低8位设置为0
091                      "movzbl %b1,%0\n\t"                                                            // 将new的低8位放置在tmp,以返回给调用者
092                      : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
093                      :
094                      : "memory", "cc");
095
096         return tmp;
097 }


碰到这种汇编,一个好的办法就是自己写一段程序,然后用GDB跟一下,看一下每个寄存器的变化,以及内存的变化。当然,ticket spinlock的原理也要比较清楚。。。。。。


论坛徽章:
0
3 [报告]
发表于 2012-06-16 17:22 |只看该作者
回复 2# wenlujon


    嗯呐,~ 谢谢你了,讲的很清楚,尤其是写段汇编的建议,已经实践了~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP