160
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
|
4 */
|
|
5
|
|
6
|
|
7 #include <ngx_config.h>
|
|
8 #include <ngx_core.h>
|
|
9
|
|
10
|
|
11 #if (( __i386__ || __amd64__ ) && ( __GNUC__ || __INTEL_COMPILER ))
|
|
12
|
|
13
|
|
14 static ngx_inline void ngx_cpuid(uint32_t i, uint32_t *buf);
|
|
15
|
|
16
|
|
17 static ngx_inline void
|
|
18 ngx_cpuid(uint32_t i, uint32_t *buf)
|
|
19 {
|
|
20 uint32_t eax, ebx, ecx, edx;
|
|
21
|
|
22 __asm__ (
|
|
23
|
|
24 "cpuid"
|
|
25
|
|
26 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) );
|
|
27
|
|
28 buf[0] = eax;
|
|
29 buf[1] = ebx;
|
|
30 buf[2] = edx;
|
|
31 buf[3] = ecx;
|
|
32 }
|
|
33
|
|
34
|
|
35 /* auto detect the L2 cache line size of modern and widespread CPUs */
|
|
36
|
|
37 void
|
|
38 ngx_cpuinfo(void)
|
|
39 {
|
|
40 u_char *vendor;
|
|
41 uint32_t vbuf[5], cpu[4];
|
|
42
|
|
43 vbuf[0] = 0;
|
|
44 vbuf[1] = 0;
|
|
45 vbuf[2] = 0;
|
|
46 vbuf[3] = 0;
|
|
47 vbuf[4] = 0;
|
|
48
|
|
49 ngx_cpuid(0, vbuf);
|
|
50
|
|
51 vendor = (u_char *) &vbuf[1];
|
|
52
|
|
53 if (vbuf[0] == 0) {
|
|
54 return;
|
|
55 }
|
|
56
|
|
57 ngx_cpuid(1, cpu);
|
|
58
|
|
59 if (ngx_strcmp(vendor, "GenuineIntel") == 0) {
|
|
60
|
|
61 switch (cpu[0] & 0xf00) {
|
|
62
|
|
63 /* Pentium */
|
|
64 case 5:
|
|
65 /* Pentium Pro, II, III */
|
|
66 case 6:
|
|
67 ngx_cacheline_size = 32;
|
|
68 break;
|
|
69
|
|
70 /*
|
|
71 * Pentium 4, although its cache line size is 64 bytes,
|
|
72 * it prefetches up to two cache lines during memory read
|
|
73 */
|
|
74 case 15:
|
|
75 ngx_cacheline_size = 128;
|
|
76 break;
|
|
77 }
|
|
78
|
|
79 } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) {
|
|
80 ngx_cacheline_size = 64;
|
|
81 }
|
|
82 }
|
|
83
|
|
84 #else
|
|
85
|
|
86
|
|
87 void
|
|
88 ngx_cpuinfo(void)
|
|
89 {
|
|
90 }
|
|
91
|
|
92
|
|
93 #endif
|