[問題] atomic 運算

看板C_and_CPP作者 (冰淇淋乾杯)時間15年前 (2010/12/26 21:54), 編輯推噓2(2021)
留言23則, 7人參與, 最新討論串1/1
最近在用pthread之間溝通問題的時候,會用到一些atomic的function 像是__sync_add_and_fetch 或是 __sync_lock_test_and_set之類的 而我實際去gcc底下翻出他底層的code implement如下: static inline long __kernel_cmpxchg (int oldval, int newval, int *mem) { register unsigned long lws_mem asm("r26") = (unsigned long) (mem); register long lws_ret asm("r28"); register long lws_errno asm("r21"); register int lws_old asm("r25") = oldval; register int lws_new asm("r24") = newval; asm volatile ( "ble 0xb0(%%sr2, %%r0) \n\t" "ldi %5, %%r20 \n\t" : "=r" (lws_ret), "=r" (lws_errno), "=r" (lws_mem), "=r" (lws_old), "=r" (lws_new) : "i" (LWS_CAS), "2" (lws_mem), "3" (lws_old), "4" (lws_new) : "r1", "r20", "r22", "r23", "r29", "r31", "memory" ); if (__builtin_expect (lws_errno == -EFAULT || lws_errno == -ENOSYS, 0)) ABORT_INSTRUCTION; /* If the kernel LWS call succeeded (lws_errno == 0), lws_ret contains the old value from memory. If this value is equal to OLDVAL, the new value was written to memory. If not, return -EBUSY. */ if (!lws_errno && lws_ret != oldval) lws_errno = -EBUSY; return lws_errno; } 是一段用inline asm寫成的function,我是看得懂code的內容 可是我看不出來他是如何作到atomic的部份,是volatile的關係嗎? volatile的意思是說不要對這段code做任何最佳化,以及移動的動作 可是我不知道他是否具有atomic的功能 還請各位解惑一下,謝謝 -- -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.118.9.54 ※ 編輯: septemhill 來自: 122.118.9.54 (12/26 21:56)

12/26 22:07, , 1F
你是在問 x86 還是? 因為這看起來像 arm...
12/26 22:07, 1F

12/26 22:09, , 2F
這是linux上的code,x86的
12/26 22:09, 2F

12/26 22:10, , 3F
我是在gcc-4.5底下找到這段code的
12/26 22:10, 3F

12/26 23:27, , 4F
arm +1
12/26 23:27, 4F

12/26 23:48, , 5F
arm 只有到 r15 阿XD
12/26 23:48, 5F

12/26 23:48, , 6F
喔對了 在這邊 volatile 是告訴 compiler 這段 code
12/26 23:48, 6F

12/26 23:48, , 7F
有動到記憶體內容
12/26 23:48, 7F

12/27 00:02, , 8F
5.44 Built-in functions for atomic memory access
12/27 00:02, 8F

12/27 01:37, , 9F
只好google了一下原po地code發現那是PA-RISC用的
12/27 01:37, 9F

12/27 01:38, , 10F
整段code看下來是一個滿標準的test & set implementatio
12/27 01:38, 10F

12/27 01:39, , 11F
註解好像也有說為什麼不需要/沒有ISA提供的test-and-set
12/27 01:39, 11F

12/27 10:10, , 12F
有動到memory這個部份,是因為第三個optional的原因
12/27 10:10, 12F

12/27 10:11, , 13F
這個部份我明白了,所以說這是他造成atomic的主因嗎?
12/27 10:11, 13F

12/27 10:11, , 14F
因為我對第三個optional的理解只有說,在此段asm中
12/27 10:11, 14F

12/27 10:12, , 15F
會動到的register、memory,讓其他程式不要存取而已
12/27 10:12, 15F

12/27 10:12, , 16F
因此並不是很明白是否還有其他的用途
12/27 10:12, 16F

12/27 17:56, , 17F
從comments,加上"ble 0xb0(%sr2,%r0)"這樣的asm看來
12/27 17:56, 17F

12/27 17:57, , 18F
PA跟ARM一樣,是使用kernel helper來做到atomic exchange的
12/27 17:57, 18F

12/27 17:58, , 19F
這個linux-atomic.c裡的__kernel_cmpxchg只是個
12/27 17:58, 19F

12/27 17:59, , 20F
fast syscall的wrapper, "LWS"跟PA google一下, 就是
12/27 17:59, 20F

12/27 18:00, , 21F
"Light-Weight Syscall"的縮寫, 只是啟動方式跟ARM略有不同
12/27 18:00, 21F

12/27 18:01, , 22F
也就說你要看的atomics的implementation,要去追kernel src
12/27 18:01, 22F

12/27 18:02, , 23F
不過可能到kernel裡也是有特殊指令完成它,可能看到的也不多
12/27 18:02, 23F
文章代碼(AID): #1D5qahtM (C_and_CPP)