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 #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, (%1); "
35 " mov %%ebx, 4(%1); "
36 " mov %%edx, 8(%1); "
37 " mov %%ecx, 12(%1); "
38
39 " mov %%esi, %%ebx; "
40
41 : : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" );
42 }
43
44
45 #else /* __amd64__ */
46
47
48 static ngx_inline void
49 ngx_cpuid(uint32_t i, uint32_t *buf)
50 {
51 uint32_t eax, ebx, ecx, edx;
52
53 __asm__ (
54
55 "cpuid"
56
57 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) );
58
59 buf[0] = eax;
60 buf[1] = ebx;
61 buf[2] = edx;
62 buf[3] = ecx;
63 }
64
65
66 #endif
67
68
69 /* auto detect the L2 cache line size of modern and widespread CPUs */
70
71 void
72 ngx_cpuinfo(void)
73 {
74 u_char *vendor;
75 uint32_t vbuf[5], cpu[4], model;
76
77 vbuf[0] = 0;
78 vbuf[1] = 0;
79 vbuf[2] = 0;
80 vbuf[3] = 0;
81 vbuf[4] = 0;
82
83 ngx_cpuid(0, vbuf);
84
85 vendor = (u_char *) &vbuf[1];
86
87 if (vbuf[0] == 0) {
88 return;
89 }
90
91 ngx_cpuid(1, cpu);
92
93 if (ngx_strcmp(vendor, "GenuineIntel") == 0) {
94
95 switch ((cpu[0] & 0xf00) >> 8) {
96
97 /* Pentium */
98 case 5:
99 ngx_cacheline_size = 32;
100 break;
101
102 /* Pentium Pro, II, III */
103 case 6:
104 ngx_cacheline_size = 32;
105
106 model = ((cpu[0] & 0xf0000) >> 8) | (cpu[0] & 0xf0);
107
108 if (model >= 0xd0) {
109 /* Intel Core, Core 2, Atom */
110 ngx_cacheline_size = 64;
111 }
112
113 break;
114
115 /*
116 * Pentium 4, although its cache line size is 64 bytes,
117 * it prefetches up to two cache lines during memory read
118 */
119 case 15:
120 ngx_cacheline_size = 128;
121 break;
122 }
123
124 } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) {
125 ngx_cacheline_size = 64;
126 }
127 }
128
129 #else
130
131
132 void
133 ngx_cpuinfo(void)
134 {
135 }
136
137
138 #endif
139
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.