2 * Copyright (c) 2005 Jakub Vana
3 * Copyright (c) 2005 Jakub Jermar
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
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
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #if (defined(ia32) || defined(amd64) || defined(ia64) || defined(ia32xen))
37 #include <proc/thread.h>
40 #include <arch/arch.h>
46 #define E_10e8 271828182
47 #define PI_10e8 314159265
50 #ifdef KERN_ia32_ARCH_H_
51 static inline double sqrt(double x
)
65 #ifdef KERN_amd64_ARCH_H_
66 static inline double sqrt(double x
)
80 #ifdef KERN_ia64_ARCH_H_
83 #define PI_10e8 3141592
85 static inline long double sqrt(long double a
)
90 if (a
< 0.00000000000000001)
95 x
= (x
+ (a
/ x
)) / 2;
103 static atomic_t threads_ok
;
104 static atomic_t threads_fault
;
105 static waitq_t can_start
;
106 static bool sh_quiet
;
108 static void e(void *data
)
113 thread_detach(THREAD
);
115 waitq_sleep(&can_start
);
117 for (i
= 0; i
<ATTEMPTS
; i
++) {
122 for (d
= 1; e
!= le
; d
*= f
, f
+= 1) {
127 if ((int) (100000000 * e
) != E_10e8
) {
129 printf("tid%d: e*10e8=%zd should be %zd\n", THREAD
->tid
, (unative_t
) (100000000 * e
), (unative_t
) E_10e8
);
130 atomic_inc(&threads_fault
);
134 atomic_inc(&threads_ok
);
137 static void pi(void *data
)
143 thread_detach(THREAD
);
145 waitq_sleep(&can_start
);
147 for (i
= 0; i
< ATTEMPTS
; i
++) {
151 for (n
= 2, ab
= sqrt(2); lpi
!= pi
; n
*= 2, ab
= ad
) {
154 sc
= sqrt(1 - (ab
* ab
/ 4));
156 ad
= sqrt(ab
* ab
/ 4 + cd
* cd
);
161 #ifdef KERN_ia64_ARCH_H_
162 if ((int) (1000000 * pi
) != PI_10e8
) {
164 printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD
->tid
, (unative_t
) (1000000 * pi
), (unative_t
) (PI_10e8
/ 100));
165 atomic_inc(&threads_fault
);
169 if ((int) (100000000 * pi
) != PI_10e8
) {
171 printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD
->tid
, (unative_t
) (100000000 * pi
), (unative_t
) PI_10e8
);
172 atomic_inc(&threads_fault
);
177 atomic_inc(&threads_ok
);
180 char * test_fpu1(bool quiet
)
182 unsigned int i
, total
= 0;
185 waitq_initialize(&can_start
);
186 atomic_set(&threads_ok
, 0);
187 atomic_set(&threads_fault
, 0);
190 printf("Creating %d threads... ", 2 * THREADS
);
192 for (i
= 0; i
< THREADS
; i
++) {
195 if (!(t
= thread_create(e
, NULL
, TASK
, 0, "e", false))) {
197 printf("could not create thread %d\n", 2 * i
);
203 if (!(t
= thread_create(pi
, NULL
, TASK
, 0, "pi", false))) {
205 printf("could not create thread %d\n", 2 * i
+ 1);
216 waitq_wakeup(&can_start
, WAKEUP_ALL
);
218 while (atomic_get(&threads_ok
) != total
) {
220 printf("Threads left: %d\n", total
- atomic_get(&threads_ok
));
224 if (atomic_get(&threads_fault
) == 0)
227 return "Test failed";