~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to kernel/test/fpu/sse1.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005 Ondrej Palkovsky
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * - Redistributions of source code must retain the above copyright
 
10
 *   notice, this list of conditions and the following disclaimer.
 
11
 * - Redistributions in binary form must reproduce the above copyright
 
12
 *   notice, this list of conditions and the following disclaimer in the
 
13
 *   documentation and/or other materials provided with the distribution.
 
14
 * - The name of the author may not be used to endorse or promote products
 
15
 *   derived from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
#include <print.h>
 
30
#include <debug.h>
 
31
 
 
32
#include <test.h>
 
33
#include <atomic.h>
 
34
#include <proc/thread.h>
 
35
#include <time/delay.h>
 
36
 
 
37
#include <arch.h>
 
38
 
 
39
#define THREADS   25
 
40
#define DELAY     10000L
 
41
#define ATTEMPTS  5
 
42
 
 
43
static atomic_t threads_ok;
 
44
static atomic_t threads_fault;
 
45
static waitq_t can_start;
 
46
 
 
47
static void testit1(void *data)
 
48
{
 
49
        int i;
 
50
        int arg __attribute__((aligned(16))) = (int) ((unative_t) data);
 
51
        int after_arg __attribute__((aligned(16)));
 
52
        
 
53
        thread_detach(THREAD);
 
54
        
 
55
        waitq_sleep(&can_start);
 
56
        
 
57
        for (i = 0; i < ATTEMPTS; i++) {
 
58
                asm volatile (
 
59
                        "movlpd %[arg], %%xmm2\n"
 
60
                        : [arg] "=m" (arg)
 
61
                );
 
62
                
 
63
                delay(DELAY);
 
64
                asm volatile (
 
65
                        "movlpd %%xmm2, %[after_arg]\n"
 
66
                        : [after_arg] "=m" (after_arg)
 
67
                );
 
68
                
 
69
                if (arg != after_arg) {
 
70
                        TPRINTF("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
 
71
                        atomic_inc(&threads_fault);
 
72
                        break;
 
73
                }
 
74
        }
 
75
        atomic_inc(&threads_ok);
 
76
}
 
77
 
 
78
static void testit2(void *data)
 
79
{
 
80
        int i;
 
81
        int arg __attribute__((aligned(16))) = (int) ((unative_t) data);
 
82
        int after_arg __attribute__((aligned(16)));
 
83
        
 
84
        thread_detach(THREAD);
 
85
        
 
86
        waitq_sleep(&can_start);
 
87
        
 
88
        for (i = 0; i < ATTEMPTS; i++) {
 
89
                asm volatile (
 
90
                        "movlpd %[arg], %%xmm2\n"
 
91
                        : [arg] "=m" (arg)
 
92
                );
 
93
                
 
94
                scheduler();
 
95
                asm volatile (
 
96
                        "movlpd %%xmm2, %[after_arg]\n"
 
97
                        : [after_arg] "=m" (after_arg)
 
98
                );
 
99
                
 
100
                if (arg != after_arg) {
 
101
                        TPRINTF("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
 
102
                        atomic_inc(&threads_fault);
 
103
                        break;
 
104
                }
 
105
        }
 
106
        atomic_inc(&threads_ok);
 
107
}
 
108
 
 
109
char *test_sse1(void)
 
110
{
 
111
        unsigned int i, total = 0;
 
112
        
 
113
        waitq_initialize(&can_start);
 
114
        atomic_set(&threads_ok, 0);
 
115
        atomic_set(&threads_fault, 0);
 
116
        
 
117
        TPRINTF("Creating %u threads... ", 2 * THREADS);
 
118
        
 
119
        for (i = 0; i < THREADS; i++) {
 
120
                thread_t *t;
 
121
                
 
122
                if (!(t = thread_create(testit1, (void *) ((unative_t) 2 * i), TASK, 0, "testit1", false))) {
 
123
                        TPRINTF("could not create thread %u\n", 2 * i);
 
124
                        break;
 
125
                }
 
126
                thread_ready(t);
 
127
                total++;
 
128
                
 
129
                if (!(t = thread_create(testit2, (void *) ((unative_t) 2 * i + 1), TASK, 0, "testit2", false))) {
 
130
                        TPRINTF("could not create thread %u\n", 2 * i + 1);
 
131
                        break;
 
132
                }
 
133
                thread_ready(t);
 
134
                total++;
 
135
        }
 
136
        
 
137
        TPRINTF("ok\n");
 
138
        
 
139
        thread_sleep(1);
 
140
        waitq_wakeup(&can_start, WAKEUP_ALL);
 
141
        
 
142
        while (atomic_get(&threads_ok) != (long) total) {
 
143
                TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
 
144
                thread_sleep(1);
 
145
        }
 
146
        
 
147
        if (atomic_get(&threads_fault) == 0)
 
148
                return NULL;
 
149
        
 
150
        return "Test failed";
 
151
}