Nginx 소스 코드 완전 분석 nginx 자전거 자물쇠 ngxspinlock
void
ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
{
#if (NGX_HAVE_ATOMIC_OPS)
ngx_uint_t i, n;
for ( ;; ) {
// lock ,
// ngx_atomic_cmp_set ,
if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
return;
}
//
if (ngx_ncpu > 1) {
// ,
for (n = 1; n < spin; n <<= 1) {
for (i = 0; i < n; i++) {
ngx_cpu_pause();
}
if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
return;
}
}
}
ngx_sched_yield();
}
#else
#if (NGX_THREADS)
#error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
#endif
#endif
}
그 중에서 lock 이라는 성형 변수 로 자 물 쇠 를 표시 하 는데 필자 의 기계 (Darwin 12.0) 에서 다음 과 같이 정의 된다.
typedef volatile ngx_atomic_uint_t ngx_atomic_t;
다시 위 spinlock 의 소스 코드 분석 으로 돌아 가면 ngxncpu (CPU 의 핵심 수 를 나타 내 는 것) 가 1 개 이상, 즉 다 핵 CPU 를 초과 하면 대기 / 재 시도 해 야 합 니 다.예 를 들 어 spin 이 80 이면 처음으로 ngx 1 개 를 기다린다.cpu_pause () 작업 을 한 다음 잠 금 이 사용 가능 한 지 다시 확인 합 니 다.다음 라운드 마다 각각 2 개, 4 개, 8 개, 16 개, 32 개, 64 개 ngxcpu_pause () 조작 후 다시 시도 합 니 다.이 중간 과정 에서 자물쇠 가 풀 려 사용 할 수 있 는 상황 이 발생 하면 순환 이 중단 되 고 spinlock 함수 가 값 을 되 돌려 줍 니 다.재 시도 에 성공 하지 못 하면 ngx 를 실행 합 니 다.sched_yield, 그리고 위의 조작 을 반복 합 니 다.
그리고 그 중의 ngxatomic_cmp_set 함수 도 탐구 가치 가 있 습 니 다.Darwin 12.0 에 서 는 다음 과 같은 매크로 정의 가 있 습 니 다.
#define ngx_atomic_cmp_set(lock, old, new) \
OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)
제 친구 의 Linux 환경 (구체 적 으로 잊 어 버 렸 지만 x86) 은 다음 과 같 습 니 다.그 중의 내 연 어 셈 블 리 는 본 블 로그 내의 GCC 내 연 어 셈 블 리 의 두 편의 박문 을 참고 할 수 있다.그 중 SMP 는 버스 자물쇠 다.
static ngx_inline ngx_atomic_uint_t
ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
ngx_atomic_uint_t set)
{
u_char res;
__asm__ volatile (
NGX_SMP_LOCK
" cmpxchgl %3, %1; "
" sete %0; "
: "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
return res;
}
이 출력 은 res 로 eax 레지스터 에 저 장 됩 니 다.* lock (내장), old (eax 중), set (r 는 유 니 버 설 레지스터 를 표시 합 니 다.이렇게% 0 은 res,% 1 은 * lock,% 2 는 old,% 3 은 set 입 니 다.
* lock 과 old 가 같 으 면 이 또는 (cmpxchgl) 가 0 이면 ZF 는 1 이 고 sete 는 res (% 0) 의 값 을 1 로 설정 하고 되 돌려 줍 니 다.* lock 과 old 가 같 지 않 으 면 이화 치가 0 이 아니 기 때문에 ZF 가 0 이 아니면 sete 는 동작 을 수행 하지 않 습 니 다. 즉, res 값 이 0 이 고 ngx 를 호출 합 니 다.atomic_cmp_set 실패.
cmpxchgl 은 ZF (Zero Flag) 표지 위치 에 영향 을 줄 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.