/*
* 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

  1. CPUID - Wikipedia

Nginx源码完全注释(5)core/ngx_cpuinfo.c的更多相关文章

  1. Nginx源码完全注释(6)core/murmurhash

    下面是摘自 Google Code 的 Murmurhash 开源项目主页上的 Murmurhash2,Nginx 就是采用的这个. uint32_t MurmurHash2 ( const void ...

  2. Nginx 源码完全注释(11)ngx_spinlock

    Nginx 是多进程模式的,一个 master 与多个 workers,一般工作在多核 CPU 上,所以自旋锁就是必须用到的.Nginx 中的自旋锁的定义,位于 ngx_spinlock.c 中,如下 ...

  3. Nginx 源码完全注释(10)ngx_radix_tree

    ngx_radix_tree.h // 未被使用的节点 #define NGX_RADIX_NO_VALUE (uintptr_t) -1 typedef struct ngx_radix_node_ ...

  4. Nginx源码完全注释(9)nginx.c: ngx_get_options

    本文分析 ngxin.c 中的 ngx_get_options 函数,其影响: nginx.c 中的: static ngx_uint_t ngx_show_help; static ngx_uint ...

  5. Nginx源码完全注释(8)ngx_errno.c

    errno.h中的strerror(int errno)可以确定指定的errno的错误的提示信息.在 Nginx 中,将所有错误提示信息预先存储在一个数组里,而预先确定这个数组的大小,是在自动化脚本中 ...

  6. Nginx源码完全注释(2)ngx_array.h / ngx_array.c

    数组头文件 ngx_array.h #include <ngx_config.h> #include <ngx_core.h> struct ngx_array_s { voi ...

  7. nginx源码完全注释(1)ngx_alloc.h / ngx_alloc.c

    首先看 ngx_alloc.h 文件,主要声明或宏定义了 ngx_alloc,ngx_calloc,ngx_memalign,ngx_free. /* * Copyright (C) Igor Sys ...

  8. 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 ...

  9. Nginx源码完全注释(4)ngx_queue.h / ngx_queue.c

    队列头文件ngx_queue.h #include <ngx_config.h> #include <ngx_core.h> #ifndef _NGX_QUEUE_H_INCL ...

随机推荐

  1. [LeetCode系列]3元素最近和问题的O(n^2)解法

    给定一个整数数组(长度不小于3) 和 一个目标值, 从数组中找出3个元素, 使得它们的和与目标值最接近, 返回这个和. 可以认为每个输入的组合都是只有唯一解的. 解法思路参考: Finding thr ...

  2. wordpress重力表单实时提醒功能教程(亲测可用)

    小七在写项目的时候遇到了一个需求:用户在填写完成表单的各个字段后要提交到后台,但是后台程序狗不能一直守着后台吧,程序狗也需要陪女朋友啊,好做一个即时提醒的功能吧,再也不担心用户提交的内容被错过了,第一 ...

  3. 浅谈ecmall插件机制

    插件是独立于原系统的程序模块,目的是在不修改原程序的情况下对系统进行扩展,便于修改和管理.目前web开发中大多是使用钩子形式来定义插件, 比较典型的有 wordpress, drupal系统 ecma ...

  4. Java NIO简单介绍(二)

    上一篇<NIO简单介绍(一)>中讲解了NIO中本地IO相关的内容,这篇重点介绍的NIO的非阻塞式网络通信 一.阻塞与非阻塞 传统的 IO 流都是阻塞式的.也就是说,当一个线程调用 read ...

  5. Python WebServer with MSSql

    今天尝试了一下在windows上用python来写web服务 我的环境是 win7(64位)+ python(2.7.11) 第一步需要安装pymssql 第二步需要安装tornado(web服务靠他 ...

  6. RK3288 制作内核开机logo

    安装工具 sudo apt-get install netpbm 1.制作图片 (1).图片为bmp格式 $ convert logo.bmp logo.png $ pngtopnm logo.png ...

  7. erlang异常处理备忘

    捕获所有异常得用_:_,看例子 try aa:bb() of Value -> Value catch _:_ -> "" end 如果单表达式不需要有返回值,直接异常 ...

  8. Arduino+A4988驱动两相四线步进电机

    先吐槽一下,在某宝买东西这么多年碰到的不靠谱的卖家也没这几天多.丝杆发短,42电机只有32大,碳杆上的鱼眼粘的没法再歪了还死紧……所以组装还得几天.于是先玩了一下DC-DC降压模块和A4988,规划了 ...

  9. python 文件操作的函数

    1. 文件操作的函数 open(文件名(路径), mode="?", encoding="字符集") 2. 模式: r, w, a, r+, w+, a+, r ...

  10. Hibernate学习4—关联关系一对多映射

    一.班级学生一对多映射实现(单向) Class 1 * Student 一对多 在学生多的一方,配置一的对象:   com.cy.model.Class: package com.cy.model; ...