首页 / NGINX / Nginx中的原子操作
Nginx中的原子操作
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Nginx中的原子操作,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2870字,纯文字阅读大概需要5分钟。
内容图文
![Nginx中的原子操作](/upload/InfoBanner/zyjiaocheng/154/8c7fbbd48b684be1adcf86e6c80bd516.jpg)
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) { if (*lock == old) { *lock = set; return 1; } return 0; }
static ngx_inline ngx_atomic_int_t ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) { ngx_atomic_int_t old; old = *value; *value += add; return old; }
在支持原子操作上的处理器(以x86为例):
#define NGX_SMP_LOCK "lock;" /* * "cmpxchgl r, [m]": * * if (eax == [m]) { * zf = 1; * [m] = r; * } else { * zf = 0; * eax = [m]; * } * * * The "r" means the general register. * The "=a" and "a" are the %eax register. * Although we can return result in any register, we use "a" because it is * used in cmpxchgl anyway. The result is actually in %al but not in %eax, * however, as the code is inlined gcc can test %al as well as %eax, * and icc adds "movzbl %al, %eax" by itself. * * The "cc" means that flags were changed. */ 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; }
/* * "xaddl r, [m]": * * temp = [m]; * [m] += r; * r = temp; * * * The "+r" means the general register. * The "cc" means that flags were changed. */ static ngx_inline ngx_atomic_int_t ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) { ngx_atomic_uint_t old; __asm__ volatile ( NGX_SMP_LOCK " xaddl %2, %1; " : "=a" (old) : "m" (*value), "a" (add) : "cc", "memory"); return old; }
自旋锁:
/* old "as" does not support "pause" opcode */ #define ngx_cpu_pause() __asm__ (".byte 0xf3, 0x90") #define ngx_sched_yield() sched_yield() 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 ( ;; ) { 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(); }
信号:
ngx_int_t ngx_init_signals(ngx_log_t *log) { ngx_signal_t *sig; struct sigaction sa; for (sig = signals; sig->signo != 0; sig++) { ngx_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = sig->handler; sigemptyset(&sa.sa_mask); if (sigaction(sig->signo, &sa, NULL) == -1) { #if (NGX_VALGRIND) ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "sigaction(%s) failed, ignored", sig->signame); #else ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "sigaction(%s) failed", sig->signame); return NGX_ERROR; #endif } } return NGX_OK; }
以上就介绍了Nginx中的原子操作,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。
内容总结
以上是互联网集市为您收集整理的Nginx中的原子操作全部内容,希望文章能够帮你解决Nginx中的原子操作所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。