611
|
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
|
617
|
17 #if ( __i386__ )
|
|
18
|
|
19 static ngx_inline void
|
|
20 ngx_cpuid(uint32_t i, uint32_t *buf)
|
|
21 {
|
|
22
|
|
23 /*
|
|
24 * we could not use %ebx as output parameter if gcc builds PIC,
|
|
25 * and we could not save %ebx on stack, because %esp is used,
|
|
26 * when the -fomit-frame-pointer optimization is specified.
|
|
27 */
|
|
28
|
|
29 __asm__ (
|
|
30
|
|
31 " mov %%ebx, %%esi; "
|
|
32
|
|
33 " cpuid; "
|
|
34 " mov %%eax, %0; "
|
|
35 " mov %%ebx, %1; "
|
|
36 " mov %%edx, %2; "
|
|
37 " mov %%ecx, %3; "
|
|
38
|
|
39 " mov %%esi, %%ebx; "
|
|
40
|
|
41 : "=m" (buf[0]), "=m" (buf[1]), "=m" (buf[2]), "=m" (buf[3])
|
|
42 : "a" (i)
|
|
43 : "ecx", "edx", "esi" );
|
|
44 }
|
|
45
|
|
46
|
|
47 #else /* __amd64__ */
|
|
48
|
|
49
|
611
|
50 static ngx_inline void
|
|
51 ngx_cpuid(uint32_t i, uint32_t *buf)
|
|
52 {
|
|
53 uint32_t eax, ebx, ecx, edx;
|
|
54
|
|
55 __asm__ (
|
|
56
|
|
57 "cpuid"
|
|
58
|
|
59 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) );
|
|
60
|
|
61 buf[0] = eax;
|
|
62 buf[1] = ebx;
|
|
63 buf[2] = edx;
|
|
64 buf[3] = ecx;
|
|
65 }
|
|
66
|
|
67
|
617
|
68 #endif
|
|
69
|
|
70
|
611
|
71 /* auto detect the L2 cache line size of modern and widespread CPUs */
|
|
72
|
|
73 void
|
|
74 ngx_cpuinfo(void)
|
|
75 {
|
|
76 u_char *vendor;
|
|
77 uint32_t vbuf[5], cpu[4];
|
|
78
|
|
79 vbuf[0] = 0;
|
|
80 vbuf[1] = 0;
|
|
81 vbuf[2] = 0;
|
|
82 vbuf[3] = 0;
|
|
83 vbuf[4] = 0;
|
|
84
|
|
85 ngx_cpuid(0, vbuf);
|
|
86
|
|
87 vendor = (u_char *) &vbuf[1];
|
|
88
|
|
89 if (vbuf[0] == 0) {
|
|
90 return;
|
|
91 }
|
|
92
|
|
93 ngx_cpuid(1, cpu);
|
|
94
|
|
95 if (ngx_strcmp(vendor, "GenuineIntel") == 0) {
|
|
96
|
|
97 switch (cpu[0] & 0xf00) {
|
|
98
|
|
99 /* Pentium */
|
|
100 case 5:
|
|
101 /* Pentium Pro, II, III */
|
|
102 case 6:
|
|
103 ngx_cacheline_size = 32;
|
|
104 break;
|
|
105
|
|
106 /*
|
|
107 * Pentium 4, although its cache line size is 64 bytes,
|
|
108 * it prefetches up to two cache lines during memory read
|
|
109 */
|
|
110 case 15:
|
|
111 ngx_cacheline_size = 128;
|
|
112 break;
|
|
113 }
|
|
114
|
|
115 } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) {
|
|
116 ngx_cacheline_size = 64;
|
|
117 }
|
|
118 }
|
|
119
|
|
120 #else
|
|
121
|
|
122
|
|
123 void
|
|
124 ngx_cpuinfo(void)
|
|
125 {
|
|
126 }
|
|
127
|
|
128
|
|
129 #endif
|