免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: zylthinking

娘的, 似乎犯错误了----技术帖 [复制链接]

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
发表于 2012-06-27 12:14 |显示全部楼层
回复 1# zylthinking


lkp 在不是 volatile 的情况下, 是不是不安全?

yes, it is unsafe.

关键是如果 *(lkp) = 0; 已经进入了 load/store unit, 则可以保证 ++n 至少在 load/store unit 内, 或者已经到了寄存器中???

另外, 如果另一个线程读 n 时, 产生的汇编应该是从内存读, 那么它怎么知道内存中某单元中的值已经在 load/store unit 中了?
似乎首先要确认的是 ++n 的结果在 load/store unit 中时, 写的目标到底是存储器还是寄存器;
如果是寄存器, 也就是 n 被优化到寄存器中了, 那么CPU 还能直接从 load/store unit 中读吗? 但如果不从其中读而直接读内存, 那读出的就是一个错误的值

if you define the lkp as a volatile value, it is not still a promble.
*(lkp) = 0;

this code has no problem.

to **:
3。我猜 不会当作 volatile 来对待
在不知道为 volatile 时就已经编译好了

i agree.

但link时应当报错,因为 volatile int n 和 int n 不应该弄成一样的名字

i am not agree with it.
"int n" or "volatile int n" has the same symbol name (both are "_n") in c.
but it is not the same in c++ (with type prefix);

论坛徽章:
0
发表于 2012-06-27 12:15 |显示全部楼层

  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. /*
  6. * The ppc assembler treats ";" as comment, so we have to use "\n".
  7. * The minus in "bne-" is a hint for the branch prediction unit that
  8. * this branch is unlikely to be taken.
  9. * The "1b" means the nearest backward label "1" and the "1f" means
  10. * the nearest forward label "1".
  11. *
  12. * The "b" means that the base registers can be used only, i.e.
  13. * any register except r0.  The r0 register always has a zero value and
  14. * could not be used in "addi  r0, r0, 1".
  15. * The "=&b" means that no input registers can be used.
  16. *
  17. * "sync"    read and write barriers
  18. * "isync"   read barrier, is faster than "sync"
  19. * "eieio"   write barrier, is faster than "sync"
  20. * "lwsync"  write barrier, is faster than "eieio" on ppc64
  21. */

  22. #if (NGX_PTR_SIZE == 8)

  23. static ngx_inline ngx_atomic_uint_t
  24. ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
  25.     ngx_atomic_uint_t set)
  26. {
  27.     ngx_atomic_uint_t  res, temp;

  28.     __asm__ volatile (

  29.     "    li      %0, 0       \n" /* preset "0" to "res"                      */
  30.     "    lwsync              \n" /* write barrier                            */
  31.     "1:                      \n"
  32.     "    ldarx   %1, 0, %2   \n" /* load from [lock] into "temp"             */
  33.                                  /*   and store reservation                  */
  34.     "    cmpd    %1, %3      \n" /* compare "temp" and "old"                 */
  35.     "    bne-    2f          \n" /* not equal                                */
  36.     "    stdcx.  %4, 0, %2   \n" /* store "set" into [lock] if reservation   */
  37.                                  /*   is not cleared                         */
  38.     "    bne-    1b          \n" /* the reservation was cleared              */
  39.     "    isync               \n" /* read barrier                             */
  40.     "    li      %0, 1       \n" /* set "1" to "res"                         */
  41.     "2:                      \n"

  42.     : "=&b" (res), "=&b" (temp)
  43.     : "b" (lock), "b" (old), "b" (set)
  44.     : "cc", "memory");

  45.     return res;
  46. }


  47. static ngx_inline ngx_atomic_int_t
  48. ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
  49. {
  50.     ngx_atomic_uint_t  res, temp;

  51.     __asm__ volatile (

  52.     "    lwsync              \n" /* write barrier                            */
  53.     "1:  ldarx   %0, 0, %2   \n" /* load from [value] into "res"             */
  54.                                  /*   and store reservation                  */
  55.     "    add     %1, %0, %3  \n" /* "res" + "add" store in "temp"            */
  56.     "    stdcx.  %1, 0, %2   \n" /* store "temp" into [value] if reservation */
  57.                                  /*   is not cleared                         */
  58.     "    bne-    1b          \n" /* try again if reservation was cleared     */
  59.     "    isync               \n" /* read barrier                             */

  60.     : "=&b" (res), "=&b" (temp)
  61.     : "b" (value), "b" (add)
  62.     : "cc", "memory");

  63.     return res;
  64. }


  65. #if (NGX_SMP)
  66. #define ngx_memory_barrier()                                                  \
  67.     __asm__ volatile ("isync  \n  lwsync  \n" ::: "memory")
  68. #else
  69. #define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
  70. #endif

  71. #else

  72. static ngx_inline ngx_atomic_uint_t
  73. ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
  74.     ngx_atomic_uint_t set)
  75. {
  76.     ngx_atomic_uint_t  res, temp;

  77.     __asm__ volatile (

  78.     "    li      %0, 0       \n" /* preset "0" to "res"                      */
  79.     "    eieio               \n" /* write barrier                            */
  80.     "1:                      \n"
  81.     "    lwarx   %1, 0, %2   \n" /* load from [lock] into "temp"             */
  82.                                  /*   and store reservation                  */
  83.     "    cmpw    %1, %3      \n" /* compare "temp" and "old"                 */
  84.     "    bne-    2f          \n" /* not equal                                */
  85.     "    stwcx.  %4, 0, %2   \n" /* store "set" into [lock] if reservation   */
  86.                                  /*   is not cleared                         */
  87.     "    bne-    1b          \n" /* the reservation was cleared              */
  88.     "    isync               \n" /* read barrier                             */
  89.     "    li      %0, 1       \n" /* set "1" to "res"                         */
  90.     "2:                      \n"

  91.     : "=&b" (res), "=&b" (temp)
  92.     : "b" (lock), "b" (old), "b" (set)
  93.     : "cc", "memory");

  94.     return res;
  95. }


  96. static ngx_inline ngx_atomic_int_t
  97. ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
  98. {
  99.     ngx_atomic_uint_t  res, temp;

  100.     __asm__ volatile (

  101.     "    eieio               \n" /* write barrier                            */
  102.     "1:  lwarx   %0, 0, %2   \n" /* load from [value] into "res"             */
  103.                                  /*   and store reservation                  */
  104.     "    add     %1, %0, %3  \n" /* "res" + "add" store in "temp"            */
  105.     "    stwcx.  %1, 0, %2   \n" /* store "temp" into [value] if reservation */
  106.                                  /*   is not cleared                         */
  107.     "    bne-    1b          \n" /* try again if reservation was cleared     */
  108.     "    isync               \n" /* read barrier                             */

  109.     : "=&b" (res), "=&b" (temp)
  110.     : "b" (value), "b" (add)
  111.     : "cc", "memory");

  112.     return res;
  113. }


  114. #if (NGX_SMP)
  115. #define ngx_memory_barrier()                                                  \
  116.     __asm__ volatile ("isync  \n  eieio  \n" ::: "memory")
  117. #else
  118. #define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
  119. #endif

  120. #endif


  121. #define ngx_cpu_pause()
复制代码
楼上的各位高人,帮偶解释一下吧,一直没搞懂,看起来正好和此楼主题有关系的。

论坛徽章:
0
发表于 2012-06-27 12:15 |显示全部楼层
回复 19# 塑料袋


    对。包含我。

论坛徽章:
0
发表于 2012-06-27 12:16 |显示全部楼层
回复 20# 塑料袋


    此楼上下都是笨蛋。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
发表于 2012-06-27 12:21 |显示全部楼层
又有一个相关的问题, 关于编译器的:
*(lkp) = 0 这样形式的代码, 会优化 lkp 对应的变量为寄存器吗

论坛徽章:
0
发表于 2012-06-27 12:24 |显示全部楼层
回复 25# zylthinking


得看具体编译器的具体版本。


此楼上下都是笨蛋,包含此楼。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
发表于 2012-06-27 12:24 |显示全部楼层
塑料袋 发表于 2012-06-27 12:08
是的,所以smp_mb()在单核情况下,展开为__asm__ __volatile(:::"memory")


*(lkp) = 0 这样形式的代码, 会优化 lkp 对应的变量为寄存器吗
如果答案是否, 那么 unlock 也就需要内存栅栏了

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
发表于 2012-06-27 12:24 |显示全部楼层
本帖最后由 folklore 于 2012-06-27 12:26 编辑

回复 25# zylthinking


    set lkip to volatile, and the answer is no.

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
发表于 2012-06-27 12:26 |显示全部楼层
nilgod 发表于 2012-06-27 12:24
回复 25# zylthinking


你打算向我们灌输什么观点? 绿衣白裙春旭路??? 敌得过我儿子一笑吗???????

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
发表于 2012-06-27 12:27 |显示全部楼层
folklore 发表于 2012-06-27 12:24
回复 25# zylthinking


如果不是 volatile 呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP