@cmpxchgWeak
@cmpxchgWeak
약한(weak) 원자적 compare-and-exchange(비교-교환) 연산을 수행하는 내장 함수예요. 현재 값이 기대한 값과 같으면 null을 돌려주고, 달라지면 실제 저장된 값을 돌려줘요. 말 그대로 다음 코드를 "원자적(atomic)으로 만들었다"고 보면 돼요 — 다만 이 코드가 다 보여주듯 항상 성공하는 건 아니라는 점이 핵심이에요.
본문
@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T
이 함수는 약한 원자적 compare-and-exchange 연산을 수행해요. 현재 값이 주어진 기대값과 같으면 null을 돌려주죠. 다음 코드의 원자적 버전이라고 보면 돼요:
fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T {
const old_value = ptr.*;
if (old_value == expected_value and usuallyTrueButSometimesFalse()) {
ptr.* = new_value;
return null;
} else {
return old_value;
}
}
예제의 usuallyTrueButSometimesFalse()가 은근히 중요한데, 이게 "약함"의 정체예요. 실제 값은 기대값과 같아도 가끔은 (드물게) 교환을 안 하고 실패를 돌려줄 수 있어요.
그래서 cmpxchg를 재시도(retry) 루프 안에서 쓴다면, 이 드물게 나는 실패는 전혀 문제가 되지 않아요. 그런 상황에서는 cmpxchgWeak가 더 나은 선택이에요 — 기계어 명령으로 훨씬 효율적으로 구현될 수 있거든요. 다만 더 강한 보장이 필요하다면 @cmpxchgStrong을 쓰세요.
제약 조건:
T는 포인터,bool, 정수, enum, 또는 packed struct여야 해요.@typeInfo(@TypeOf(ptr)).pointer.alignment가>= @sizeOf(T)여야 해요.AtomicOrder는@import("std").lang.AtomicOrder로 찾을 수 있어요.