membarrier(2) - wariua/manpages-ko GitHub Wiki

NAME

membarrier - μŠ€λ ˆλ“œ 집합에 λ©”λͺ¨λ¦¬ 배리어 μ£ΌκΈ°

SYNOPSIS

#include <linux/membarrier.h>

int membarrier(int cmd, int flags);

DESCRIPTION

membarrier() μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ 닀쀑 μ½”μ–΄ μ‹œμŠ€ν…œμ—μ„œ λ©”λͺ¨λ¦¬ μ ‘κ·Ό μˆœμ„œ μ œμ–΄μ— ν•„μš”ν•œ λ©”λͺ¨λ¦¬ 배리어 μΈμŠ€νŠΈλŸ­μ…˜μ˜ μ˜€λ²„ν—€λ“œλ₯Ό 쀄일 수 있게 ν•΄ μ€€λ‹€. ν•˜μ§€λ§Œ 이 μ‹œμŠ€ν…œ 호좜이 λ©”λͺ¨λ¦¬ 배리어보닀 무거우며, κ·Έλž˜μ„œ 효과적으둜 μ΄μš©ν•˜λ €λ©΄ λ©”λͺ¨λ¦¬ 배리어λ₯Ό 이 μ‹œμŠ€ν…œ 호좜둜 κ΅μ²΄ν•˜κΈ°λ§Œ ν•˜λ©΄ λ˜λŠ” 것이 μ•„λ‹ˆλΌ μ•„λž˜ μ„ΈλΆ€ λ‚΄μš©μ— λŒ€ν•œ 이해가 ν•„μš”ν•˜λ‹€.

λ©”λͺ¨λ¦¬ 배리어λ₯Ό μ‚¬μš©ν•  λ•Œ κ³ λ €ν•΄μ•Ό ν•˜λŠ” 것은 λ©”λͺ¨λ¦¬ 배리어에 항상 μƒλŒ€κ°€ λ˜λŠ” λ©”λͺ¨λ¦¬ 배리어 짝이 μžˆμ–΄μ•Ό ν•  μˆ˜λ„ 있고, μ•„ν‚€ν…μ²˜ λ©”λͺ¨λ¦¬ λͺ¨λΈμ—μ„œ 그런 λŒ€μ‘ 배리어λ₯Ό μš”κ΅¬ν•˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€λŠ” 점이닀.

λŒ€μ‘ 배리어 쀑 ν•œμͺ½(μ΄ν•˜ "λΉ λ₯Έ μͺ½")이 λ‹€λ₯Έ μͺ½(μ΄ν•˜ "느린 μͺ½")보닀 훨씬 자주 μ‹€ν–‰λ˜λŠ” κ²½μš°κ°€ μžˆλ‹€. 그런 κ²½μš°κ°€ membarrier()λ₯Ό μ‚¬μš©ν•  μ£Όμš” λŒ€μƒμ΄λ‹€. 핡심 μ•„μ΄λ””μ–΄λŠ” 그런 λŒ€μ‘ λ°°λ¦¬μ–΄μ—μ„œ λΉ λ₯Έ μͺ½ λ©”λͺ¨λ¦¬ 배리어λ₯Ό λ‹€μŒκ³Ό 같은 λ‹¨μˆœ 컴파일러 λ°°λ¦¬μ–΄λ‘œ κ΅μ²΄ν•˜κ³  느린 μͺ½ λ©”λͺ¨λ¦¬ 배리어λ₯Ό membarrier() 호좜둜 κ΅μ²΄ν•˜λŠ” 것이닀.

asm volatile ("" : : : "memory")

그러면 느린 μͺ½μ— μ˜€λ²„ν—€λ“œλ₯Ό λ”ν•˜κ³  λΉ λ₯Έ μͺ½μ—μ„œ μ˜€λ²„ν—€λ“œλ₯Ό μ—†μ• κ²Œ λ˜μ–΄ membarrier() 호좜 μ˜€λ²„ν—€λ“œκ°€ λΉ λ₯Έ μͺ½ μ„±λŠ₯ 이득을 μƒνšŒν•˜μ§€ μ•Šμ„ 만큼 느린 μͺ½μ΄ λ“œλ¬ΌκΈ°λ§Œ ν•˜λ‹€λ©΄ 결과적으둜 전체 μ„±λŠ₯이 μ˜¬λΌκ°€κ²Œ λœλ‹€.

cmd μΈμžλŠ” λ‹€μŒ 쀑 ν•˜λ‚˜μ΄λ‹€.

MEMBARRIER_CMD_QUERY (λ¦¬λˆ…μŠ€ 4.3λΆ€ν„°)
지원 λͺ…λ Ή 집합을 μ§ˆμ˜ν•œλ‹€. 호좜 λ°˜ν™˜ 값은 지원 λͺ…λ Ήλ“€μ˜ λΉ„νŠΈ λ§ˆμŠ€ν¬μ΄λ‹€. MEMBARRIER_CMD_QUERY의 값은 0μ΄λ―€λ‘œ κ·Έ λΉ„νŠΈ λ§ˆμŠ€ν¬μ— ν¬ν•¨λ˜μ§€ μ•ŠλŠ”λ‹€. (membarrier()λ₯Ό μ œκ³΅ν•˜λŠ” μ»€λ„μ—μ„œ) 이 λͺ…령은 항상 μ§€μ›ν•œλ‹€.
MEMBARRIER_CMD_GLOBAL (λ¦¬λˆ…μŠ€ 4.16λΆ€ν„°)
membarrier() μ‹œμŠ€ν…œ 호좜 μ§„μž…κ³Ό λ°˜ν™˜ μ‚¬μ΄μ—μ„œ μ‹œμŠ€ν…œ μƒμ˜ λͺ¨λ“  ν”„λ‘œμ„ΈμŠ€μ˜ μŠ€λ ˆλ“œ λͺ¨λ‘κ°€ μ‚¬μš©μž 곡간 μ£Όμ†Œμ— λŒ€ν•œ λͺ¨λ“  λ©”λͺ¨λ¦¬ 접근이 ν”„λ‘œκ·Έλž¨ μˆœμ„œμ™€ μΌμΉ˜ν•˜λŠ” μƒνƒœλ₯Ό κ±°μΉ˜λ„λ‘ ν•œλ‹€. 이 λͺ…령은 μ‹œμŠ€ν…œμ˜ μŠ€λ ˆλ“œ λͺ¨λ‘λ₯Ό λŒ€μƒμœΌλ‘œ ν•œλ‹€.
MEMBARRIER_CMD_GLOBAL_EXPEDITED (λ¦¬λˆ…μŠ€ 4.16λΆ€ν„°)

MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED둜 미리 λ“±λ‘ν•œ ν”„λ‘œμ„ΈμŠ€ λͺ¨λ‘μ˜ μ‹€ν–‰ 쀑인 μŠ€λ ˆλ“œ λͺ¨λ‘μ—μ„œ λ©”λͺ¨λ¦¬ 배리어λ₯Ό μ‹€ν–‰ν•œλ‹€.

μ‹œμŠ€ν…œ 호좜 λ°˜ν™˜ μ‹œμ—, μ‹€ν–‰ 쀑인 μŠ€λ ˆλ“œ λͺ¨λ‘κ°€ μ‚¬μš©μž 곡간 μ£Όμ†Œμ— λŒ€ν•œ λͺ¨λ“  λ©”λͺ¨λ¦¬ 접근이 ν”„λ‘œκ·Έλž¨ μˆœμ„œμ™€ μΌμΉ˜ν•˜λŠ” μƒνƒœλ₯Ό μ‹œμŠ€ν…œ 호좜 μ§„μž…κ³Ό λ°˜ν™˜ μ‚¬μ΄μ—μ„œ κ±°μ³€λ‹€λŠ” 보μž₯을 호좜 μŠ€λ ˆλ“œκ°€ μ–»κ²Œ λœλ‹€. (μ‹€ν–‰ 쀑이 μ•„λ‹Œ μŠ€λ ˆλ“œλŠ” μ‹€μ§ˆμ μœΌλ‘œ 그런 μƒνƒœμ— μžˆλŠ” 것이닀.) MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED둜 미리 λ“±λ‘ν•œ ν”„λ‘œμ„ΈμŠ€μ˜ μŠ€λ ˆλ“œμ— λŒ€ν•΄μ„œλ§Œ 보μž₯이 이뀄진닀.

등둝은 배리어λ₯Ό λ°›μ•„λ“€μ΄κ² λ‹€λŠ” μ˜λ„μ— λŒ€ν•œ κ²ƒμ΄λ―€λ‘œ MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITEDλ₯Ό μ“΄ 적 μ—†λŠ” ν”„λ‘œμ„ΈμŠ€μ—μ„œ MEMBARRIER_CMD_GLOBAL_EXPEDITEDλ₯Ό ν˜ΈμΆœν•˜λŠ” 것이 μœ νš¨ν•˜λ‹€.

"신속 처리(expedited)" λͺ…령은 κ·Έλ ‡μ§€ μ•Šμ€ λͺ…령보닀 빨리 μ™„λ£Œλœλ‹€. μ ˆλŒ€ 블둝 ν•˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ μΆ”κ°€ μ˜€λ²„ν—€λ“œλ₯Ό μœ λ°œν•˜λŠ” 단점이 μžˆλ‹€.

MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED (λ¦¬λˆ…μŠ€ 4.16λΆ€ν„°)
MEMBARRIER_CMD_GLOBAL_EXPEDITED λ©”λͺ¨λ¦¬ 배리어λ₯Ό λ°›μ•„λ“€μ΄λ €λŠ” ν”„λ‘œμ„ΈμŠ€μ˜ μ˜λ„λ₯Ό μ•Œλ¦°λ‹€.
MEMBARRIER_CMD_PRIVATE_EXPEDITED (λ¦¬λˆ…μŠ€ 4.14λΆ€ν„°)

호좜 μŠ€λ ˆλ“œμ™€ 같은 ν”„λ‘œμ„ΈμŠ€μ— μ†ν•œ μ‹€ν–‰ 쀑인 μŠ€λ ˆλ“œ κ°κ°μ—μ„œ λ©”λͺ¨λ¦¬ 배리어λ₯Ό μ‹€ν–‰ν•œλ‹€.

μ‹œμŠ€ν…œ 호좜 λ°˜ν™˜ μ‹œμ—, μ‹€ν–‰ 쀑인 ν˜•μ œμžλ§€ μŠ€λ ˆλ“œ λͺ¨λ‘κ°€ μ‚¬μš©μž 곡간 μ£Όμ†Œμ— λŒ€ν•œ λͺ¨λ“  λ©”λͺ¨λ¦¬ 접근이 ν”„λ‘œκ·Έλž¨ μˆœμ„œμ™€ μΌμΉ˜ν•˜λŠ” μƒνƒœλ₯Ό μ‹œμŠ€ν…œ 호좜 μ§„μž…κ³Ό λ°˜ν™˜ μ‚¬μ΄μ—μ„œ κ±°μ³€λ‹€λŠ” 보μž₯을 호좜 μŠ€λ ˆλ“œκ°€ μ–»κ²Œ λœλ‹€. (μ‹€ν–‰ 쀑이 μ•„λ‹Œ μŠ€λ ˆλ“œλŠ” μ‹€μ§ˆμ μœΌλ‘œ 그런 μƒνƒœμ— μžˆλŠ” 것이닀.) 호좜 μŠ€λ ˆλ“œμ™€ 같은 ν”„λ‘œμ„ΈμŠ€μ˜ μŠ€λ ˆλ“œμ— λŒ€ν•΄μ„œλ§Œ 보μž₯이 이뀄진닀.

"신속 처리" λͺ…령은 κ·Έλ ‡μ§€ μ•Šμ€ λͺ…령보닀 빨리 μ™„λ£Œλœλ‹€. μ ˆλŒ€ 블둝 ν•˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ μΆ”κ°€ μ˜€λ²„ν—€λ“œλ₯Ό μœ λ°œν•˜λŠ” 단점이 μžˆλ‹€.

ν”„λ‘œμ„ΈμŠ€λ³„ 신속 처리 λͺ…령을 μ‚¬μš©ν•˜λ €λŠ” ν”„λ‘œμ„ΈμŠ€λŠ” μ‚¬μš© 전에 κ·Έ μ˜λ„λ₯Ό 미리 μ•Œλ €μ•Ό ν•œλ‹€.

MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED (λ¦¬λˆ…μŠ€ 4.14λΆ€ν„°)
MEMBARRIER_CMD_PRIVATE_EXPEDITEDλ₯Ό μ‚¬μš©ν•˜λ €λŠ” ν”„λ‘œμ„ΈμŠ€μ˜ μ˜λ„λ₯Ό μ•Œλ¦°λ‹€.
MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE (λ¦¬λˆ…μŠ€ 4.16λΆ€ν„°)

MEMBARRIER_CMD_PRIVATE_EXPEDITEDμ—μ„œ κΈ°μˆ ν•œ λ©”λͺ¨λ¦¬ μˆœμ„œ 보μž₯에 λ”ν•΄μ„œ, μ‹œμŠ€ν…œ 호좜 λ°˜ν™˜ μ‹œμ— μ‹€ν–‰ 쀑인 ν˜•μ œμžλ§€ μŠ€λ ˆλ“œ λͺ¨λ‘κ°€ μ½”μ–΄ 직렬화 μΈμŠ€νŠΈλŸ­μ…˜μ„ μ‹€ν–‰ν–ˆλ‹€λŠ” 보μž₯을 호좜 μŠ€λ ˆλ“œκ°€ μ–»κ²Œ λœλ‹€. 호좜 μŠ€λ ˆλ“œμ™€ 같은 ν”„λ‘œμ„ΈμŠ€μ˜ μŠ€λ ˆλ“œμ— λŒ€ν•΄μ„œλ§Œ 이 보μž₯이 이뀄진닀.

"신속 처리" λͺ…령은 κ·Έλ ‡μ§€ μ•Šμ€ λͺ…령보닀 빨리 μ™„λ£Œλœλ‹€. μ ˆλŒ€ 블둝 ν•˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ μΆ”κ°€ μ˜€λ²„ν—€λ“œλ₯Ό μœ λ°œν•˜λŠ” 단점이 μžˆλ‹€.

ν”„λ‘œμ„ΈμŠ€λ³„ 신속 처리 μ½”μ–΄ 동기화 λͺ…령을 μ‚¬μš©ν•˜λ €λŠ” ν”„λ‘œμ„ΈμŠ€λŠ” μ‚¬μš© 전에 κ·Έ μ˜λ„λ₯Ό 미리 μ•Œλ €μ•Ό ν•œλ‹€.

MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE (λ¦¬λˆ…μŠ€ 4.16λΆ€ν„°)
MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_COREλ₯Ό μ‚¬μš©ν•˜λ €λŠ” ν”„λ‘œμ„ΈμŠ€μ˜ μ˜λ„λ₯Ό μ•Œλ¦°λ‹€.
MEMBARRIER_CMD_SHARED (λ¦¬λˆ…μŠ€ 4.3λΆ€ν„°)
헀더 ν•˜μœ„ ν˜Έν™˜μ„±μ„ μœ„ν•΄ μ‘΄μž¬ν•˜λŠ” MEMBARRIER_CMD_GLOBAL의 별칭이닀.

flags μΈμžλŠ” ν˜„μž¬ μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©° 0으둜 μ§€μ •ν•΄μ•Ό ν•œλ‹€.

각 λŒ€μƒ μŠ€λ ˆλ“œμ—μ„œ ν”„λ‘œκ·Έλž¨ μˆœμ„œλ‘œ μˆ˜ν–‰λ˜λŠ” λͺ¨λ“  λ©”λͺ¨λ¦¬ 접근은 membarrier()에 λŒ€ν•΄μ„œ μˆœμ„œκ°€ μ§€μΌœμ§„λ‹€κ³ (ordered) 보μž₯λœλ‹€.

배리어 μ „ν›„λ‘œ ν”„λ‘œκ·Έλž¨ μˆœμ„œμ— 따라 λ©”λͺ¨λ¦¬ 접근을 μˆ˜ν–‰ν•˜κ²Œ κ°•μ œν•˜λŠ” 컴파일러 배리어λ₯Ό 의미둠적 barrier()둜 λ‚˜νƒ€λ‚΄κ³  배리어 μ „ν›„λ‘œ μ™„μ „ν•œ λ©”λͺ¨λ¦¬ μ ‘κ·Ό μˆœμ„œλ₯Ό κ°•μ œν•˜λŠ” λͺ…μ‹œμ  λ©”λͺ¨λ¦¬ 배리어λ₯Ό smp_mb()둜 λ‚˜νƒ€λ‚Έλ‹€λ©΄, barrier(), membarrier(), smp_mb()의 각 μŒμ— λŒ€ν•œ λ‹€μŒ μˆœμ„œ ν…Œμ΄λΈ”μ„ μ–»λŠ”λ‹€. OλŠ” μˆœμ„œκ°€ μ§€μΌœμ§€λŠ” 것이고 XλŠ” μˆœμ„œκ°€ μ§€μΌœμ§€μ§€ μ•ŠλŠ” 것이닀.

barrier() smp_mb() membarrier()
barrier() X X O
smp_mb() X O O
membarrier() O O O

RETURN VALUE

성곡 μ‹œ MEMBARRIER_CMD_QUERY λ™μž‘μ€ 지원 λͺ…λ Ήλ“€μ˜ λΉ„νŠΈ 마슀크λ₯Ό λ°˜ν™˜ν•˜λ©°, MEMBARRIER_CMD_GLOBAL, MEMBARRIER_CMD_GLOBAL_EXPEDITED, MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, MEMBARRIER_CMD_PRIVATE_EXPEDITED, MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE λ™μž‘μ€ 0을 λ°˜ν™˜ν•œλ‹€. 였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•˜λ©° errnoλ₯Ό 적절히 μ„€μ •ν•œλ‹€.

ν•œ λͺ…령에 λŒ€ν•΄μ„œ flagsλ₯Ό 0으둜 μ„€μ • μ‹œ 이 μ‹œμŠ€ν…œ 호좜이 μž¬λΆ€νŒ… λ•ŒκΉŒμ§€ 항상 같은 값을 λ°˜ν™˜ν•œλ‹€κ³  보μž₯λœλ‹€. 즉, 같은 인자둜 ν•˜λŠ” 이후 호좜이 같은 κ²°κ³Όλ₯Ό λ‚³λŠ”λ‹€. λ”°λΌμ„œ flagsλ₯Ό 0으둜 μ„€μ • μ‹œ 첫 번째 membarrier() ν˜ΈμΆœμ—μ„œλ§Œ 였λ₯˜ μ²˜λ¦¬κ°€ ν•„μš”ν•˜λ‹€.

ERRORS

EINVAL
cmdκ°€ μœ νš¨ν•˜μ§€ μ•Šκ±°λ‚˜, flagsκ°€ 0이 μ•„λ‹ˆκ±°λ‚˜, CPU λ§€κ°œλ³€μˆ˜ nohz_full이 μ„€μ •λ˜μ–΄μ„œ MEMBARRIER_CMD_GLOBAL λͺ…령이 λΉ„ν™œμ„±ν™”λ˜μ–΄ μžˆκ±°λ‚˜, MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE 및 MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE λͺ…령이 μ•„ν‚€ν…μ²˜μ— κ΅¬ν˜„λ˜μ–΄ μžˆμ§€ μ•Šλ‹€.
ENOSYS
membarrier() μ‹œμŠ€ν…œ 호좜이 이 컀널에 κ΅¬ν˜„λ˜μ–΄ μžˆμ§€ μ•Šλ‹€.
EPERM
ν˜„μž¬ ν”„λ‘œμ„ΈμŠ€κ°€ ν”„λ‘œμ„ΈμŠ€λ³„ 신속 처리 λͺ…λ Ή μ‚¬μš©μ— μ•žμ„œ μ‹ κ³ λ₯Ό ν•˜μ§€ μ•Šμ•˜λ‹€.

VERSIONS

λ¦¬λˆ…μŠ€ 4.3μ—μ„œ membarrier() μ‹œμŠ€ν…œ 호좜이 μΆ”κ°€λ˜μ—ˆλ‹€.

CONFORMING TO

membarrier()λŠ” λ¦¬λˆ…μŠ€ μ „μš©μ΄λ‹€.

NOTES

λ©”λͺ¨λ¦¬ λͺ¨λΈμ΄ μ•½ν•œ μˆœμ„œ(weakly-ordered)인 μ•„ν‚€ν…μ²˜μ—μ„œ μΈμŠ€νŠΈλŸ­μ…˜ μ„ΈνŠΈμ— λ©”λͺ¨λ¦¬ 배리어 μΈμŠ€νŠΈλŸ­μ…˜μ΄ ν¬ν•¨λ˜μ–΄ μžˆλ‹€. λ‹€λ₯Έ μ½”μ–΄ μƒμ˜ λŒ€μ‘ν•˜λŠ” 배리어에 λŒ€ν•΄μ„œ 배리어 μ „ λ©”λͺ¨λ¦¬ μ ‘κ·Όκ³Ό 배리어 ν›„ λ©”λͺ¨λ¦¬ μ ‘κ·Όμ˜ μˆœμ„œλ₯Ό μ§€μΌœ μ€€λ‹€. 예λ₯Ό λ“€μ–΄ μ €μž₯ fence둜 μˆœμ„œλ₯Ό μœ μ§€ν•˜λŠ” μ €μž₯듀에 λŒ€ν•΄μ„œ 적재 fenceκ°€ 펜슀 μ „ μ μž¬μ™€ 펜슀 ν›„ 적재의 μˆœμ„œλ₯Ό μœ μ§€ν•  수 μžˆλ‹€.

ν”„λ‘œκ·Έλž¨ μˆœμ„œλž€ ν”„λ‘œκ·Έλž¨ μ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œμ—μ„œ μΈμŠ€νŠΈλŸ­μ…˜μ΄ λ°°μΉ˜λ˜λŠ” μˆœμ„œμ΄λ‹€.

membarrier()κ°€ μœ μš©ν•  수 μžˆλŠ” 경우둜 Read-Copy-Update λΌμ΄λΈŒλŸ¬λ¦¬λ‚˜ κ°€λΉ„μ§€ 컬렉터 κ΅¬ν˜„ 등이 μžˆλ‹€.

EXAMPLE

"fast_path()"λ₯Ό 맀우 자주 μ‹€ν–‰ν•˜κ³  "slow_path()"λ₯Ό λ“œλ¬Όκ²Œ μ‹€ν–‰ν•˜λŠ” 닀쀑 μŠ€λ ˆλ“œ μ‘μš©μ„ κ°€μ •ν•  λ•Œ λ‹€μŒκ³Ό 같은 (x86용) μ½”λ“œλ₯Ό membarrier()λ₯Ό 쓰도둝 λ³€ν˜•ν•  수 μžˆλ‹€.

#include <stdlib.h>

static volatile int a, b;

static void
fast_path(int *read_b)
{
    a = 1;
    asm volatile ("mfence" : : : "memory");
    *read_b = b;
}

static void
slow_path(int *read_a)
{
    b = 1;
    asm volatile ("mfence" : : : "memory");
    *read_a = a;
}

int
main(int argc, char **argv)
{
    int read_a, read_b;

    /*
     * μ‹€μ œ μ‘μš©μ—μ„œλŠ” fast_path()와 slow_path()λ₯Ό
     * λ‹€λ₯Έ μŠ€λ ˆλ“œμ—μ„œ ν˜ΈμΆœν•˜κ²Œ 됨. μ˜ˆμ‹œ ν”„λ‘œκ·Έλž¨μ„
     * 짧게 λ§Œλ“€κΈ° μœ„ν•΄ main()μ—μ„œ ν˜ΈμΆœν•¨.
     */

    slow_path(&read_a);
    fast_path(&read_b);

    /*
     * read_b == 0이면 read_a == 1이고
     * read_a == 0이면 read_b == 1.
     */

    if (read_b == 0 && read_a == 0)
        abort();

    exit(EXIT_SUCCESS);
}

μœ„ μ½”λ“œλ₯Ό membarrier()λ₯Ό 쓰도둝 λ³€ν˜•ν•˜λ©΄ λ‹€μŒμ΄ λœλ‹€.

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/membarrier.h>

static volatile int a, b;

static int
membarrier(int cmd, int flags)
{
    return syscall(__NR_membarrier, cmd, flags);
}

static int
init_membarrier(void)
{
    int ret;

    /* membarrier() μ§€μ›ν•˜λŠ”μ§€ 확인 */

    ret = membarrier(MEMBARRIER_CMD_QUERY, 0);
    if (ret < 0) {
        perror("membarrier");
        return -1;
    }

    if (!(ret & MEMBARRIER_CMD_GLOBAL)) {
        fprintf(stderr,
            "membarrier does not support MEMBARRIER_CMD_GLOBAL\n");
        return -1;
    }

    return 0;
}

static void
fast_path(int *read_b)
{
    a = 1;
    asm volatile ("" : : : "memory");
    *read_b = b;
}

static void
slow_path(int *read_a)
{
    b = 1;
    membarrier(MEMBARRIER_CMD_GLOBAL, 0);
    *read_a = a;
}

int
main(int argc, char **argv)
{
    int read_a, read_b;

    if (init_membarrier())
        exit(EXIT_FAILURE);

    /*
     * μ‹€μ œ μ‘μš©μ—μ„œλŠ” fast_path()와 slow_path()λ₯Ό
     * λ‹€λ₯Έ μŠ€λ ˆλ“œμ—μ„œ ν˜ΈμΆœν•˜κ²Œ 됨. μ˜ˆμ‹œ ν”„λ‘œκ·Έλž¨μ„
     * 짧게 λ§Œλ“€κΈ° μœ„ν•΄ main()μ—μ„œ ν˜ΈμΆœν•¨.
     */

    slow_path(&read_a);
    fast_path(&read_b);

    /*
     * read_b == 0이면 read_a == 1이고
     * read_a == 0이면 read_b == 1.
     */

    if (read_b == 0 && read_a == 0)
        abort();

    exit(EXIT_SUCCESS);
}

2018-04-30

⚠️ **GitHub.com Fallback** ⚠️