Mercurial > hg > nginx
annotate src/core/ngx_cpuinfo.c @ 9331:dbf76fdd109f default tip
release-1.27.4 tag
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 03 Sep 2024 13:11:25 +0300 |
parents | d286426eab1a |
children |
rev | line source |
---|---|
611 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
611 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 | |
11 | |
9315
d286426eab1a
Support for Clang with "-fgnuc-version=0".
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
12 #if (( __i386__ || __amd64__ ) \ |
d286426eab1a
Support for Clang with "-fgnuc-version=0".
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
13 && ( __GNUC__ || __clang__ || __INTEL_COMPILER )) |
611 | 14 |
15 | |
16 static ngx_inline void ngx_cpuid(uint32_t i, uint32_t *buf); | |
17 | |
18 | |
617 | 19 #if ( __i386__ ) |
20 | |
21 static ngx_inline void | |
22 ngx_cpuid(uint32_t i, uint32_t *buf) | |
23 { | |
24 | |
25 /* | |
26 * we could not use %ebx as output parameter if gcc builds PIC, | |
27 * and we could not save %ebx on stack, because %esp is used, | |
28 * when the -fomit-frame-pointer optimization is specified. | |
29 */ | |
30 | |
31 __asm__ ( | |
32 | |
33 " mov %%ebx, %%esi; " | |
34 | |
35 " cpuid; " | |
651 | 36 " mov %%eax, (%1); " |
37 " mov %%ebx, 4(%1); " | |
38 " mov %%edx, 8(%1); " | |
39 " mov %%ecx, 12(%1); " | |
617 | 40 |
41 " mov %%esi, %%ebx; " | |
42 | |
651 | 43 : : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" ); |
617 | 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; | |
2613
b863be280d3b
update cpuid for Core 2 and Atom
Igor Sysoev <igor@sysoev.ru>
parents:
1872
diff
changeset
|
77 uint32_t vbuf[5], cpu[4], model; |
611 | 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 | |
1871
9afb84c7cc61
fix cache line size for Pentium 4
Igor Sysoev <igor@sysoev.ru>
parents:
651
diff
changeset
|
97 switch ((cpu[0] & 0xf00) >> 8) { |
611 | 98 |
99 /* Pentium */ | |
100 case 5: | |
1872
8e88522cb6da
detect L2 cache line size for Intel Core
Igor Sysoev <igor@sysoev.ru>
parents:
1871
diff
changeset
|
101 ngx_cacheline_size = 32; |
8e88522cb6da
detect L2 cache line size for Intel Core
Igor Sysoev <igor@sysoev.ru>
parents:
1871
diff
changeset
|
102 break; |
8e88522cb6da
detect L2 cache line size for Intel Core
Igor Sysoev <igor@sysoev.ru>
parents:
1871
diff
changeset
|
103 |
611 | 104 /* Pentium Pro, II, III */ |
105 case 6: | |
106 ngx_cacheline_size = 32; | |
1872
8e88522cb6da
detect L2 cache line size for Intel Core
Igor Sysoev <igor@sysoev.ru>
parents:
1871
diff
changeset
|
107 |
2613
b863be280d3b
update cpuid for Core 2 and Atom
Igor Sysoev <igor@sysoev.ru>
parents:
1872
diff
changeset
|
108 model = ((cpu[0] & 0xf0000) >> 8) | (cpu[0] & 0xf0); |
b863be280d3b
update cpuid for Core 2 and Atom
Igor Sysoev <igor@sysoev.ru>
parents:
1872
diff
changeset
|
109 |
b863be280d3b
update cpuid for Core 2 and Atom
Igor Sysoev <igor@sysoev.ru>
parents:
1872
diff
changeset
|
110 if (model >= 0xd0) { |
b863be280d3b
update cpuid for Core 2 and Atom
Igor Sysoev <igor@sysoev.ru>
parents:
1872
diff
changeset
|
111 /* Intel Core, Core 2, Atom */ |
1872
8e88522cb6da
detect L2 cache line size for Intel Core
Igor Sysoev <igor@sysoev.ru>
parents:
1871
diff
changeset
|
112 ngx_cacheline_size = 64; |
8e88522cb6da
detect L2 cache line size for Intel Core
Igor Sysoev <igor@sysoev.ru>
parents:
1871
diff
changeset
|
113 } |
8e88522cb6da
detect L2 cache line size for Intel Core
Igor Sysoev <igor@sysoev.ru>
parents:
1871
diff
changeset
|
114 |
611 | 115 break; |
116 | |
117 /* | |
118 * Pentium 4, although its cache line size is 64 bytes, | |
119 * it prefetches up to two cache lines during memory read | |
120 */ | |
121 case 15: | |
122 ngx_cacheline_size = 128; | |
123 break; | |
124 } | |
125 | |
126 } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) { | |
127 ngx_cacheline_size = 64; | |
128 } | |
129 } | |
130 | |
131 #else | |
132 | |
133 | |
134 void | |
135 ngx_cpuinfo(void) | |
136 { | |
137 } | |
138 | |
139 | |
140 #endif |