Nginx 소스 코드 완전 주석 (11) ngxspinlock
6006 단어 nginx
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 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
간단! Certbot을 사용하여 웹 사이트를 SSL(HTTPS)화하는 방법초보자가 인프라 주위를 정돈하는 것은 매우 어렵습니다. 이번은 사이트를 간단하게 SSL화(HTTP에서 HTTPS통신)로 변경하는 방법을 소개합니다! 이번에는 소프트웨어 시스템 Nginx CentOS7 의 환경에서 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.