架构系统相关的代码(amd64, Linux)
相关定义
typedef int64_t ngx_atomic_int_t;
typedef uint64_t ngx_atomic_uint_t;
typedef volatile ngx_atomic_uint_t ngx_atomic_t;
#define NGX_HAVE_ATOMIC_OPS 1
#include "ngx_gcc_atomic_amd64.h"
ngx_gcc_atomic_amd64.h
#define NGX_SMP_LOCK "lock;"
嵌入式汇编函数
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 lock指令
" cmpxchgq %3, %1; " cmpxchg的意思是比较ax寄存器的值(old的值)和lock的值,如果相等(0 = 0),set的值(1)覆盖lock,zf置1
ax=1,返回1,加锁成功
如果不等(ax 1 != 0 lock),old = 1的情况,lock的值(0)覆盖ax寄存器,zf清0,cmpxchgq是64位
lock == 0,才会调这个函数,cmpxchgq可理解为相等交换并返回1
" sete %0; " 设置ax寄存器的值为zf
: "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
ax寄存器的值赋给res返回,输入内存变量lock,old放入寄存器ax中,set放在任意寄存器
可能改变的值,cc(CPU标志寄存器 ),memory
return res;
}
static ngx_inline ngx_atomic_int_t
ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
{
__asm__ volatile (
NGX_SMP_LOCK
" xaddq %0, %1; " add + value的值放到add存放的寄存器中
: "+r" (add) : "m" (*value) : "cc", "memory");
add可以放到任意寄存器,输出add,输入内存变量value,
return add;
}
#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")空
#define ngx_cpu_pause() __asm__ ("pause")
公用的宏
#define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1)) 只尝试获取一次锁
#define ngx_unlock(lock) *(lock) = 0
函数void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);得不到锁就等待
ngx_uint_t i, n;
for ( ;; ) {
if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) { ax的值和lock的值相同,都是0,value覆盖lock,并返回1
return;
}
if (ngx_ncpu > 1) {多核
for (n = 1; n < spin; n <<= 1) {n = 1, 2, 4...
for (i = 0; i < n; i++) {
ngx_cpu_pause();
}
if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
return;
}
}
}
ngx_sched_yield(); //sched_yield()放弃当前的执行机会,等待下次调度
}
相关定义
typedef int64_t ngx_atomic_int_t;
typedef uint64_t ngx_atomic_uint_t;
typedef volatile ngx_atomic_uint_t ngx_atomic_t;
#define NGX_HAVE_ATOMIC_OPS 1
#include "ngx_gcc_atomic_amd64.h"
ngx_gcc_atomic_amd64.h
#define NGX_SMP_LOCK "lock;"
嵌入式汇编函数
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 lock指令
" cmpxchgq %3, %1; " cmpxchg的意思是比较ax寄存器的值(old的值)和lock的值,如果相等(0 = 0),set的值(1)覆盖lock,zf置1
ax=1,返回1,加锁成功
如果不等(ax 1 != 0 lock),old = 1的情况,lock的值(0)覆盖ax寄存器,zf清0,cmpxchgq是64位
lock == 0,才会调这个函数,cmpxchgq可理解为相等交换并返回1
" sete %0; " 设置ax寄存器的值为zf
: "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
ax寄存器的值赋给res返回,输入内存变量lock,old放入寄存器ax中,set放在任意寄存器
可能改变的值,cc(CPU标志寄存器 ),memory
return res;
}
static ngx_inline ngx_atomic_int_t
ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
{
__asm__ volatile (
NGX_SMP_LOCK
" xaddq %0, %1; " add + value的值放到add存放的寄存器中
: "+r" (add) : "m" (*value) : "cc", "memory");
add可以放到任意寄存器,输出add,输入内存变量value,
return add;
}
#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")空
#define ngx_cpu_pause() __asm__ ("pause")
公用的宏
#define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1)) 只尝试获取一次锁
#define ngx_unlock(lock) *(lock) = 0
函数void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);得不到锁就等待
ngx_uint_t i, n;
for ( ;; ) {
if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) { ax的值和lock的值相同,都是0,value覆盖lock,并返回1
return;
}
if (ngx_ncpu > 1) {多核
for (n = 1; n < spin; n <<= 1) {n = 1, 2, 4...
for (i = 0; i < n; i++) {
ngx_cpu_pause();
}
if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
return;
}
}
}
ngx_sched_yield(); //sched_yield()放弃当前的执行机会,等待下次调度
}