Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.12 ]​[ nginx-1.16.0 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 
0011 
0012 #if (( __i386__ || __amd64__ ) && ( __GNUC__ || __INTEL_COMPILER ))
0013 
0014 
0015 static ngx_inline void ngx_cpuid(uint32_t i, uint32_t *buf);
0016 
0017 
0018 #if ( __i386__ )
0019 
0020 static ngx_inline void
0021 ngx_cpuid(uint32_t i, uint32_t *buf)
0022 {
0023 
0024     /*
0025      * we could not use %ebx as output parameter if gcc builds PIC,
0026      * and we could not save %ebx on stack, because %esp is used,
0027      * when the -fomit-frame-pointer optimization is specified.
0028      */
0029 
0030     __asm__ (
0031 
0032     "    mov    %%ebx, %%esi;  "
0033 
0034     "    cpuid;                "
0035     "    mov    %%eax, (%1);   "
0036     "    mov    %%ebx, 4(%1);  "
0037     "    mov    %%edx, 8(%1);  "
0038     "    mov    %%ecx, 12(%1); "
0039 
0040     "    mov    %%esi, %%ebx;  "
0041 
0042     : : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" );
0043 }
0044 
0045 
0046 #else /* __amd64__ */
0047 
0048 
0049 static ngx_inline void
0050 ngx_cpuid(uint32_t i, uint32_t *buf)
0051 {
0052     uint32_t  eax, ebx, ecx, edx;
0053 
0054     __asm__ (
0055 
0056         "cpuid"
0057 
0058     : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) );
0059 
0060     buf[0] = eax;
0061     buf[1] = ebx;
0062     buf[2] = edx;
0063     buf[3] = ecx;
0064 }
0065 
0066 
0067 #endif
0068 
0069 
0070 /* auto detect the L2 cache line size of modern and widespread CPUs */
0071 
0072 void
0073 ngx_cpuinfo(void)
0074 {
0075     u_char    *vendor;
0076     uint32_t   vbuf[5], cpu[4], model;
0077 
0078     vbuf[0] = 0;
0079     vbuf[1] = 0;
0080     vbuf[2] = 0;
0081     vbuf[3] = 0;
0082     vbuf[4] = 0;
0083 
0084     ngx_cpuid(0, vbuf);
0085 
0086     vendor = (u_char *) &vbuf[1];
0087 
0088     if (vbuf[0] == 0) {
0089         return;
0090     }
0091 
0092     ngx_cpuid(1, cpu);
0093 
0094     if (ngx_strcmp(vendor, "GenuineIntel") == 0) {
0095 
0096         switch ((cpu[0] & 0xf00) >> 8) {
0097 
0098         /* Pentium */
0099         case 5:
0100             ngx_cacheline_size = 32;
0101             break;
0102 
0103         /* Pentium Pro, II, III */
0104         case 6:
0105             ngx_cacheline_size = 32;
0106 
0107             model = ((cpu[0] & 0xf0000) >> 8) | (cpu[0] & 0xf0);
0108 
0109             if (model >= 0xd0) {
0110                 /* Intel Core, Core 2, Atom */
0111                 ngx_cacheline_size = 64;
0112             }
0113 
0114             break;
0115 
0116         /*
0117          * Pentium 4, although its cache line size is 64 bytes,
0118          * it prefetches up to two cache lines during memory read
0119          */
0120         case 15:
0121             ngx_cacheline_size = 128;
0122             break;
0123         }
0124 
0125     } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) {
0126         ngx_cacheline_size = 64;
0127     }
0128 }
0129 
0130 #else
0131 
0132 
0133 void
0134 ngx_cpuinfo(void)
0135 {
0136 }
0137 
0138 
0139 #endif