Nginx源码完全注释(5)core/ngx_cpuinfo.c
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#include <ngx_config.h>
#include <ngx_core.h>
// 如果 CPU 架构是 i386 或 amd64,并且编译器是 GNU Compiler 或 Intel Compiler,则定义 cngx_puid 函数
// 否则 ngx_cpuid 函数为空
#if (( __i386__ || __amd64__ ) && ( __GNUC__ || __INTEL_COMPILER ))
static ngx_inline void ngx_cpuid(uint32_t i, uint32_t *buf);
// i386 架构的 CPU,调用 CPU 指令 cpuid,获取 CPU 相关信息
#if ( __i386__ )
static ngx_inline void
ngx_cpuid(uint32_t i, uint32_t *buf)
{
/*
* we could not use %ebx as output parameter if gcc builds PIC,
* and we could not save %ebx on stack, because %esp is used,
* when the -fomit-frame-pointer optimization is specified.
*/
__asm__ (
" mov %%ebx, %%esi; "
" cpuid; "
" mov %%eax, (%1); "
" mov %%ebx, 4(%1); "
" mov %%edx, 8(%1); "
" mov %%ecx, 12(%1); "
" mov %%esi, %%ebx; "
: : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" );
}
// amd64 架构的 CPU,调用 CPU 指令 cpuid,获取 CPU 相关信息
#else /* __amd64__ */
static ngx_inline void
ngx_cpuid(uint32_t i, uint32_t *buf)
{
uint32_t eax, ebx, ecx, edx;
// 内联汇编,可以参见我此前的两篇博文
// 《GCC内联汇编(1)Get started》
// 《GCC内联汇编(2)GCC生成汇编代码简单实例》
__asm__ (
"cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) );
// 返回值在四个通用寄存器中,赋给 buf,又外部调用处使用
buf[0] = eax;
buf[1] = ebx;
buf[2] = edx;
buf[3] = ecx;
}
#endif
/* auto detect the L2 cache line size of modern and widespread CPUs */
void
ngx_cpuinfo(void)
{
// 存储厂商识别串,即 Vendor ID
u_char *vendor;
// vbuf 作为 EAX=0 时获取到的数据的 buffer
// cpu 作为 EAX=1 时获取到的 CPU 说明
// model 为后面根据 CPU 说明中的 Extended Model 和 Model 计算出来的值
uint32_t vbuf[5], cpu[4], model;
vbuf[0] = 0;
vbuf[1] = 0;
vbuf[2] = 0;
vbuf[3] = 0;
vbuf[4] = 0;
// cpuid 第0号功能(EAX=0),获取最大功能号和厂商识别串
// vbuf[0] 存储最大功能号
// vbuf[1], vbuf[2], vbuf[3] 存储厂商识别号
ngx_cpuid(0, vbuf);
vendor = (u_char *) &vbuf[1];
if (vbuf[0] == 0) {
return;
}
// cpuid 第1号功能(EAX=1),获取 CPU 说明
// 3:0 - Stepping
// 7:4 - Model
// 11:8 - Family
// 13:12 - Processor Type
// 19:16 - Extended Model
// 27:20 - Extended Family
ngx_cpuid(1, cpu);
// 如果厂商识别号为 Intel 的
if (ngx_strcmp(vendor, "GenuineIntel") == 0) {
// 根据 Intel CPU 的家族号来 switch
switch ((cpu[0] & 0xf00) >> 8) {
/* Pentium */
case 5:
ngx_cacheline_size = 32;
break;
/* Pentium Pro, II, III */
case 6:
// cacheline 是 32
ngx_cacheline_size = 32;
// 根据 Extended Model 和 Model,来确定该情况下的 cacheline
// 比如 Extended Model 为 0x1,Model 为 0xd,则 model 变量值为 0x1d0,大于 0xd0,满足 if
// 比如 Extended Model 为 0x0,Model 为 0xd,则 model 变量值为 0x0d0,等于 0xd0,满足 if
// 比如 Extended Model 为 0x0,Model 为 0xc,则 model 变量值为 0x0c0,小于 0xd0,不满足 if
model = ((cpu[0] & 0xf0000) >> 8) | (cpu[0] & 0xf0);
if (model >= 0xd0) {
/* Intel Core, Core 2, Atom */
ngx_cacheline_size = 64;
}
break;
/*
* Pentium 4, although its cache line size is 64 bytes,
* it prefetches up to two cache lines during memory read
*/
// cacheline 也是 64 位,只不过在读内存预取数据时会取两倍 cacheline 长度的东东
case 15:
ngx_cacheline_size = 128;
break;
}
// 如果厂商识别号为 AMD 的
} else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) {
ngx_cacheline_size = 64;
}
}
#else
void
ngx_cpuinfo(void)
{
}
#endif
Reference
Nginx源码完全注释(5)core/ngx_cpuinfo.c的更多相关文章
- Nginx源码完全注释(6)core/murmurhash
下面是摘自 Google Code 的 Murmurhash 开源项目主页上的 Murmurhash2,Nginx 就是采用的这个. uint32_t MurmurHash2 ( const void ...
- Nginx 源码完全注释(11)ngx_spinlock
Nginx 是多进程模式的,一个 master 与多个 workers,一般工作在多核 CPU 上,所以自旋锁就是必须用到的.Nginx 中的自旋锁的定义,位于 ngx_spinlock.c 中,如下 ...
- Nginx 源码完全注释(10)ngx_radix_tree
ngx_radix_tree.h // 未被使用的节点 #define NGX_RADIX_NO_VALUE (uintptr_t) -1 typedef struct ngx_radix_node_ ...
- Nginx源码完全注释(9)nginx.c: ngx_get_options
本文分析 ngxin.c 中的 ngx_get_options 函数,其影响: nginx.c 中的: static ngx_uint_t ngx_show_help; static ngx_uint ...
- Nginx源码完全注释(8)ngx_errno.c
errno.h中的strerror(int errno)可以确定指定的errno的错误的提示信息.在 Nginx 中,将所有错误提示信息预先存储在一个数组里,而预先确定这个数组的大小,是在自动化脚本中 ...
- Nginx源码完全注释(2)ngx_array.h / ngx_array.c
数组头文件 ngx_array.h #include <ngx_config.h> #include <ngx_core.h> struct ngx_array_s { voi ...
- nginx源码完全注释(1)ngx_alloc.h / ngx_alloc.c
首先看 ngx_alloc.h 文件,主要声明或宏定义了 ngx_alloc,ngx_calloc,ngx_memalign,ngx_free. /* * Copyright (C) Igor Sys ...
- Nginx源码完全注释(7)ngx_palloc.h/ngx_palloc.c
ngx_palloc.h /* * NGX_MAX_ALLOC_FROM_POOL should be (ngx_pagesize - 1), i.e. 4095 on x86. * On Windo ...
- Nginx源码完全注释(4)ngx_queue.h / ngx_queue.c
队列头文件ngx_queue.h #include <ngx_config.h> #include <ngx_core.h> #ifndef _NGX_QUEUE_H_INCL ...
随机推荐
- ballerina 学习九 Client endpoints
说白了就是连接外部服务的,可以是http jms websocket .... 简单例子 代码 import ballerina/http; import ballerina/log; endpoin ...
- webpack 图片资源处理
备注: css 引用图片资源 1. 安装loader yarn add file-loader --dev 2. 配置 const path = require("path"); ...
- python编程规范系列--建议08~18
本系列来自<编写高质量代码 改善python程序的91个建议>的读书笔记整理. 本章主要内容 建议8:利用assert语句来发现问题 建议9:数据交换值时不推荐使用中间交换变量 建议10 ...
- MySQL出现1030-Got error 28 from storage engine错误
Navicat for MySQL出现1030-Got error 28 from storage engine错误 刚刚还能用这会儿就用不了了,估计是磁盘空间不足引起的! 在根目录/下执行命令:d ...
- angular的指令独立作用域(以及$watch的使用)
在编写指令的时候,会有一个独立作用域的问题(scope),他默认的是 scope:false 不创建自己的作用域,直接使用的就是父级的作用域, 问题:容易出现全局的污染,是的指令的重复性使用回出现一些 ...
- linux(7)
第十七单元 Samba服务 [本节内容]1. 掌握samba的功能: samba是一个网络服务器,用于Linux和Windows之间共享文件.2. 掌握samba服务的启动.停止.重启service ...
- CRITICAL:yum.cli:Config Error: Error accessing file for config file:///etc/yum.conf
先试试yum install gcc , 1,下载最新的yum-3.2.28.tar.gz并解压 #wget http://yum.baseurl.org/download/3.2/yum-3.2. ...
- C#(.Net)中调用Sql sever汉字字符串显示为?问号
利用Sql语言,向数据库中导入‘C语’,结果在检查的时候,发现如上图所示. 网络上,很多人说是编码问题,但是都没给出具体的解决方案,最终用这种方法解决了! 把上图中需要储存汉字字符串的类型变为 nva ...
- bzoj2184: 任意图的匹配
Description 每天都要考,每天都要讲,大家注意力都集中不起来了,每天听解题报告时都有人交头接耳(也包括我,呵呵).这样做大大的影响的学习效率(可能吧).于是,有些好奇心重的同学就开始研究,怎 ...
- java代码--------编写0懂啊PI之间求随机数的方法
总结:其实每次运行,显示出来的结果个数是随机的. package com.mmm; //编写0到PI之间求随机数的方法 public class MEm { public static void ma ...