Rev 2020 | Rev 2029 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2020 | Rev 2027 | ||
---|---|---|---|
Line 25... | Line 25... | ||
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ |
28 | */ |
29 | 29 | ||
- | 30 | #if (defined(ia32) || defined(amd64) || defined(ia64) || defined(ia32xen)) |
|
- | 31 | ||
30 | #include <print.h> |
32 | #include <print.h> |
31 | #include <debug.h> |
33 | #include <debug.h> |
32 | #include <panic.h> |
34 | #include <panic.h> |
33 | 35 | ||
34 | #include <test.h> |
36 | #include <test.h> |
Line 36... | Line 38... | ||
36 | #include <proc/thread.h> |
38 | #include <proc/thread.h> |
37 | 39 | ||
38 | #include <arch.h> |
40 | #include <arch.h> |
39 | #include <arch/arch.h> |
41 | #include <arch/arch.h> |
40 | 42 | ||
41 | #ifdef CONFIG_BENCH |
- | |
42 | #include <arch/cycle.h> |
- | |
43 | #endif |
- | |
44 | 43 | ||
45 | #if (defined(ia32) || defined(amd64) || defined(ia64) || defined(ia32xen)) |
- | |
46 | - | ||
47 | #define THREADS 150*2 |
44 | #define THREADS 150 |
48 | #define ATTEMPTS 100 |
45 | #define ATTEMPTS 100 |
49 | 46 | ||
50 | #define E_10e8 271828182 |
47 | #define E_10e8 271828182 |
51 | #define PI_10e8 314159265 |
48 | #define PI_10e8 314159265 |
52 | 49 | ||
53 | 50 | ||
54 | #ifdef KERN_ia32_ARCH_H_ |
51 | #ifdef KERN_ia32_ARCH_H_ |
55 | static inline double sqrt(double x) { double v; __asm__ ("fsqrt\n" : "=t" (v) : "0" (x)); return v; } |
52 | static inline double sqrt(double x) |
- | 53 | { |
|
- | 54 | double v; |
|
- | 55 | ||
- | 56 | asm ( |
|
- | 57 | "fsqrt\n" |
|
- | 58 | : "=t" (v) |
|
- | 59 | : "0" (x) |
|
- | 60 | ); |
|
- | 61 | ||
- | 62 | return v; |
|
- | 63 | } |
|
56 | #endif |
64 | #endif |
57 | 65 | ||
58 | #ifdef KERN_amd64_ARCH_H_ |
66 | #ifdef KERN_amd64_ARCH_H_ |
59 | static inline double sqrt(double x) { double v; __asm__ ("fsqrt\n" : "=t" (v) : "0" (x)); return v; } |
67 | static inline double sqrt(double x) |
- | 68 | { |
|
- | 69 | double v; |
|
- | 70 | ||
- | 71 | asm ( |
|
- | 72 | "fsqrt\n" |
|
- | 73 | : "=t" (v) |
|
- | 74 | : "0" (x) |
|
- | 75 | ); |
|
- | 76 | ||
- | 77 | return v; |
|
- | 78 | } |
|
60 | #endif |
79 | #endif |
61 | 80 | ||
62 | #ifdef KERN_ia64_ARCH_H_ |
81 | #ifdef KERN_ia64_ARCH_H_ |
- | 82 | ||
- | 83 | #undef PI_10e8 |
|
- | 84 | #define PI_10e8 3141592 |
|
- | 85 | ||
63 | static inline long double sqrt(long double a) |
86 | static inline long double sqrt(long double a) |
64 | { |
87 | { |
65 | long double x = 1; |
88 | long double x = 1; |
66 | long double lx = 0; |
89 | long double lx = 0; |
67 | 90 | ||
68 | if(a<0.00000000000000001) return 0; |
91 | if (a < 0.00000000000000001) |
- | 92 | return 0; |
|
69 | 93 | ||
70 | while(x!=lx) |
94 | while(x != lx) { |
71 | { |
- | |
72 | lx=x; |
95 | lx = x; |
73 | x=(x+(a/x))/2; |
96 | x = (x + (a / x)) / 2; |
74 | } |
97 | } |
- | 98 | ||
75 | return x; |
99 | return x; |
76 | } |
100 | } |
77 | #endif |
101 | #endif |
78 | 102 | ||
79 | 103 | ||
80 | - | ||
81 | static atomic_t threads_ok; |
104 | static atomic_t threads_ok; |
- | 105 | static atomic_t threads_fault; |
|
82 | static waitq_t can_start; |
106 | static waitq_t can_start; |
83 | 107 | ||
84 | static void e(void *data) |
108 | static void e(void *data) |
85 | { |
109 | { |
86 | int i; |
110 | int i; |
Line 89... | Line 113... | ||
89 | thread_detach(THREAD); |
113 | thread_detach(THREAD); |
90 | 114 | ||
91 | waitq_sleep(&can_start); |
115 | waitq_sleep(&can_start); |
92 | 116 | ||
93 | for (i = 0; i<ATTEMPTS; i++) { |
117 | for (i = 0; i<ATTEMPTS; i++) { |
94 | le=-1; |
118 | le = -1; |
95 | e=0; |
119 | e = 0; |
96 | f=1; |
120 | f = 1; |
97 | 121 | ||
98 | for(d=1;e!=le;d*=f,f+=1) { |
122 | for (d = 1; e != le; d *= f, f += 1) { |
99 | le=e; |
123 | le = e; |
100 | e=e+1/d; |
124 | e = e + 1 / d; |
101 | } |
125 | } |
102 | 126 | ||
103 | if((int)(100000000*e)!=E_10e8) |
127 | if ((int) (100000000 * e) != E_10e8) { |
104 | panic("tid%d: e*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000*e),(unative_t) E_10e8); |
128 | printf("tid%d: e*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8); |
- | 129 | atomic_inc(&threads_fault); |
|
- | 130 | break; |
|
- | 131 | } |
|
105 | } |
132 | } |
106 | - | ||
107 | printf("tid%d: e*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000*e),(unative_t) E_10e8); |
- | |
108 | atomic_inc(&threads_ok); |
133 | atomic_inc(&threads_ok); |
109 | } |
134 | } |
110 | 135 | ||
111 | static void pi(void *data) |
136 | static void pi(void *data) |
112 | { |
137 | { |
113 | - | ||
114 | #ifdef KERN_ia64_ARCH_H_ |
- | |
115 | #undef PI_10e8 |
- | |
116 | #define PI_10e8 3141592 |
- | |
117 | #endif |
- | |
118 | - | ||
119 | - | ||
120 | int i; |
138 | int i; |
121 | double lpi, pi; |
139 | double lpi, pi; |
122 | double n, ab, ad; |
140 | double n, ab, ad; |
123 | 141 | ||
124 | thread_detach(THREAD); |
142 | thread_detach(THREAD); |
125 | 143 | ||
126 | waitq_sleep(&can_start); |
144 | waitq_sleep(&can_start); |
127 | 145 | ||
128 | - | ||
129 | for (i = 0; i<ATTEMPTS; i++) { |
146 | for (i = 0; i < ATTEMPTS; i++) { |
130 | lpi = -1; |
147 | lpi = -1; |
131 | pi = 0; |
148 | pi = 0; |
132 | 149 | ||
133 | for (n=2, ab = sqrt(2); lpi != pi; n *= 2, ab = ad) { |
150 | for (n = 2, ab = sqrt(2); lpi != pi; n *= 2, ab = ad) { |
134 | double sc, cd; |
151 | double sc, cd; |
135 | 152 | ||
136 | sc = sqrt(1 - (ab*ab/4)); |
153 | sc = sqrt(1 - (ab * ab / 4)); |
137 | cd = 1 - sc; |
154 | cd = 1 - sc; |
138 | ad = sqrt(ab*ab/4 + cd*cd); |
155 | ad = sqrt(ab * ab / 4 + cd * cd); |
139 | lpi = pi; |
156 | lpi = pi; |
140 | pi = 2 * n * ad; |
157 | pi = 2 * n * ad; |
141 | } |
158 | } |
142 | 159 | ||
143 | #ifdef KERN_ia64_ARCH_H_ |
160 | #ifdef KERN_ia64_ARCH_H_ |
144 | if((int)(1000000*pi)!=PI_10e8) |
161 | if ((int) (1000000 * pi) != PI_10e8) { |
145 | panic("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (1000000*pi),(unative_t) (PI_10e8/100)); |
162 | printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (1000000 * pi), (unative_t) (PI_10e8 / 100)); |
- | 163 | atomic_inc(&threads_fault); |
|
- | 164 | break; |
|
- | 165 | } |
|
146 | #else |
166 | #else |
147 | if((int)(100000000*pi)!=PI_10e8) |
167 | if ((int) (100000000 * pi) != PI_10e8) { |
148 | panic("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000*pi),(unative_t) PI_10e8); |
168 | printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000 * pi), (unative_t) PI_10e8); |
- | 169 | atomic_inc(&threads_fault); |
|
- | 170 | break; |
|
- | 171 | } |
|
149 | #endif |
172 | #endif |
150 | - | ||
151 | } |
173 | } |
152 | - | ||
153 | printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000*pi),(unative_t) PI_10e8); |
- | |
154 | atomic_inc(&threads_ok); |
174 | atomic_inc(&threads_ok); |
155 | } |
175 | } |
156 | 176 | ||
157 | void test_fpu1(void) |
177 | char * test_fpu1(void) |
158 | { |
178 | { |
159 | #ifdef CONFIG_BENCH |
- | |
160 | uint64_t t0 = get_cycle(); |
179 | unsigned int i, total = 0; |
161 | #endif |
- | |
162 | thread_t *t; |
- | |
163 | int i; |
- | |
164 | 180 | ||
165 | waitq_initialize(&can_start); |
181 | waitq_initialize(&can_start); |
- | 182 | atomic_set(&threads_ok, 0); |
|
- | 183 | atomic_set(&threads_fault, 0); |
|
- | 184 | printf("Creating %d threads... ", 2 * THREADS); |
|
166 | 185 | ||
167 | printf("FPU test #1\n"); |
186 | for (i = 0; i < THREADS; i++) { |
168 | printf("Creating %d threads... ", THREADS); |
187 | thread_t *t; |
169 | 188 | ||
170 | for (i=0; i<THREADS/2; i++) { |
- | |
171 | if (!(t = thread_create(e, NULL, TASK, 0, "e"))) |
189 | if (!(t = thread_create(e, NULL, TASK, 0, "e"))) { |
172 | panic("could not create thread\n"); |
190 | printf("could not create thread %d\n", 2 * i); |
- | 191 | break; |
|
- | 192 | } |
|
173 | thread_ready(t); |
193 | thread_ready(t); |
- | 194 | total++; |
|
- | 195 | ||
174 | if (!(t = thread_create(pi, NULL, TASK, 0, "pi"))) |
196 | if (!(t = thread_create(pi, NULL, TASK, 0, "pi"))) { |
175 | panic("could not create thread\n"); |
197 | printf("could not create thread %d\n", 2 * i + 1); |
- | 198 | break; |
|
- | 199 | } |
|
176 | thread_ready(t); |
200 | thread_ready(t); |
- | 201 | total++; |
|
177 | } |
202 | } |
178 | printf("ok\n"); |
203 | printf("ok\n"); |
179 | 204 | ||
180 | thread_sleep(1); |
205 | thread_sleep(1); |
181 | waitq_wakeup(&can_start, WAKEUP_ALL); |
206 | waitq_wakeup(&can_start, WAKEUP_ALL); |
182 | 207 | ||
183 | while (atomic_get(&threads_ok) != THREADS) |
208 | while (atomic_get(&threads_ok) != total) { |
184 | ; |
- | |
185 | - | ||
186 | printf("Test passed.\n"); |
- | |
187 | #ifdef CONFIG_BENCH |
- | |
188 | uint64_t dt = get_cycle() - t0; |
- | |
189 | printf("Time: %.*d cycles\n", sizeof(dt) * 2, dt); |
209 | printf("Threads left: %d\n", total - atomic_get(&threads_ok)); |
190 | #endif |
210 | thread_sleep(1); |
191 | } |
211 | } |
192 | 212 | ||
193 | #else |
213 | if (atomic_get(&threads_fault) == 0) |
194 | - | ||
195 | void test_fpu1(void) |
214 | return NULL; |
196 | { |
215 | |
197 | printf("This test is available only on Intel/AMD platforms."); |
216 | return "Test failed"; |
198 | } |
217 | } |
199 | 218 | ||
200 | #endif |
219 | #endif |