OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [language/] [c/] [libc/] [time/] [current/] [tests/] [clock.c] - Blame information for rev 810

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//=================================================================
2
//
3
//        clock.c
4
//
5
//        Testcase for C library clock()
6
//
7
//=================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//=================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     ctarpy, jlarmour
43
// Contributors:  
44
// Date:          1999-03-05
45
// Description:   Contains testcode for C library clock() function
46
//
47
//
48
//####DESCRIPTIONEND####
49
 
50
// CONFIGURATION
51
 
52
#include <pkgconf/libc_time.h>   // Configuration header
53
#include <pkgconf/system.h>
54
#include <pkgconf/isoinfra.h>
55
#include <pkgconf/infra.h>
56
 
57
#include <cyg/infra/testcase.h>
58
 
59
// This test is bound to fail often on the synthetic target -- we
60
// don't have exclusive access to the CPU.
61
 
62
#if defined(CYGPKG_HAL_SYNTH)
63
# define NA_MSG "Timing accuracy not guaranteed on synthetic target"
64
#elif !defined(CYGINT_ISO_MAIN_STARTUP)
65
# define NA_MSG "Requires main() startup"
66
#elif defined(CYGDBG_USE_TRACING)
67
# define NA_MSG "Cannot give an accurate test when tracing is enabled"
68
#endif
69
 
70
#ifdef NA_MSG
71
void
72
cyg_start(void)
73
{
74
    CYG_TEST_INIT();
75
    CYG_TEST_NA( NA_MSG );
76
}
77
 
78
#else
79
 
80
 
81
// INCLUDES
82
 
83
#include <time.h>
84
#include <cyg/infra/diag.h>
85
#include <cyg/hal/hal_cache.h>
86
#include <cyg/hal/hal_intr.h>
87
 
88
 
89
// CONSTANTS
90
 
91
// This defines how many loops before we decide that
92
// the clock doesnt work
93
#define MAX_TIMEOUT 100000
94
 
95
// Percentage error before we declare fail: range 0 - 100
96
#define TOLERANCE 40
97
 
98
// Permissible absolute deviation from mean value to take care of incorrect
99
// failure conclusions in case of small mean values (if absolute values of
100
// clock() are small, percentage variation can be large)
101
#define FUDGE_FACTOR 6
102
 
103
// Number of samples to take
104
#define SAMPLES 30
105
 
106
// We ignore ctrs[0] because it's always 0
107
// We ignore ctrs[1] because it will always be odd since it was
108
// the first measurement taken at the start of the looping, and
109
// the initial clock measurement (in clocks[0]) was not treated as
110
// part of the loop and therefore can't be considered to take the same
111
// time.
112
// We ignore ctrs[2] because it always seems to be substantially faster
113
// that the other samples. Probably due to cache/timing effect after the
114
// previous loop.
115
// Finally, ctrs[3] is skipped because it's also very fast on ARM targets.
116
 
117
#define SKIPPED_SAMPLES 6
118
 
119
 
120
// FUNCTIONS
121
 
122
static int
123
my_abs(int i)
124
{
125
    return (i < 0) ? -i : i;
126
} // my_abs()
127
 
128
 
129
// Clock measurement is done in a separate function so that alignment
130
// constraints are deterministic - some processors may perform better
131
// in loops that are better aligned, so by making it always the same
132
// function, this is prevented.
133
// FIXME: how do we guarantee the compiler won't inline this on -O3?
134
static unsigned long
135
clock_loop( const int timeout, clock_t prevclock, clock_t *newclock )
136
{
137
    clock_t c=0;
138
    long i;
139
 
140
    for (i=0; i<timeout; i++) {
141
        c = clock();
142
        if ( c != prevclock )
143
            break; // Hit the next clock pulse
144
    }
145
 
146
    if (i==timeout)
147
        CYG_TEST_FAIL_FINISH("No change in clock state!");
148
 
149
    // it should not overflow in the lifetime of this test
150
    if (c < prevclock)
151
        CYG_TEST_FAIL_FINISH("Clock decremented!");
152
 
153
    *newclock = c;
154
 
155
    return i;
156
} // clock_loop()
157
 
158
// both of these get zeroed out
159
static unsigned long ctrs[SAMPLES];
160
static clock_t clocks[SAMPLES];
161
 
162
int
163
main(int argc, char *argv[])
164
{
165
    unsigned long mean=0, sum=0, maxerr=0;
166
    int i;
167
    unsigned int absdev;
168
 
169
    CYG_TEST_INIT();
170
 
171
    CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C library "
172
                  "clock() function");
173
 
174
    // First disable the caches - they may affect the timing loops
175
    // below - causing the elapsed time during the clock() call to vary.
176
    {
177
        register CYG_INTERRUPT_STATE oldints;
178
 
179
        HAL_DISABLE_INTERRUPTS(oldints);
180
        HAL_DCACHE_SYNC();
181
        HAL_ICACHE_DISABLE();
182
        HAL_DCACHE_DISABLE();
183
        HAL_DCACHE_SYNC();
184
        HAL_ICACHE_INVALIDATE_ALL();
185
        HAL_DCACHE_INVALIDATE_ALL();
186
        HAL_RESTORE_INTERRUPTS(oldints);
187
    }
188
 
189
    // This waits for a clock tick, to ensure that we are at the
190
    // start of a clock period. Then sit in a tight loop to get
191
    // the clock period. Repeat this, and make sure that it the
192
    // two timed periods are acceptably close.
193
 
194
    clocks[0] = clock();
195
 
196
    if (clocks[0] == (clock_t)-1)  // unimplemented is potentially valid.
197
    {
198
#ifdef CYGSEM_LIBC_TIME_CLOCK_WORKING
199
        CYG_TEST_FAIL_FINISH( "clock() returns -1, meaning unimplemented");
200
#else
201
        CYG_TEST_PASS_FINISH( "clock() returns -1, meaning unimplemented");
202
#endif
203
    } // if
204
 
205
    // record clocks in a tight consistent loop to avoid random variations
206
    for (i=1; i<SAMPLES; i++) {
207
        ctrs[i] = clock_loop( MAX_TIMEOUT, clocks[i-1], &clocks[i] );
208
    }
209
 
210
    for (i=0;i<SAMPLES;i++) {
211
        // output what we got - useful for diagnostics of occasional
212
        // test failures
213
        diag_printf("clocks[%d] = %d, ctrs[%d] = %d\n", i, clocks[i],
214
                    i, ctrs[i]);
215
 
216
        // Now we work out the error etc.
217
        if (i>=SKIPPED_SAMPLES) {
218
            sum += ctrs[i];
219
        }
220
    }
221
 
222
    // deduce out the average
223
    mean = sum / (SAMPLES-SKIPPED_SAMPLES);
224
 
225
    // now go through valid results and compare against average
226
    for (i=SKIPPED_SAMPLES;i<SAMPLES;i++) {
227
        unsigned long err;
228
 
229
        absdev = my_abs(ctrs[i]-mean);
230
        // use mean+1 as divisor to avoid div-by-zero
231
        err = (100 * absdev) / (mean+1);
232
        if (err > TOLERANCE && absdev > FUDGE_FACTOR) {
233
            diag_printf("mean=%d, ctrs[%d]=%d, err=%d\n", mean, i, ctrs[i],
234
                        err);
235
            CYG_TEST_FAIL_FINISH("clock() within tolerance");
236
        }
237
        if (err > maxerr)
238
            maxerr=err;
239
    }
240
 
241
    diag_printf("mean=%d, maxerr=%d\n", mean, maxerr);
242
    CYG_TEST_PASS_FINISH("clock() stable");
243
 
244
} // main()
245
 
246
#endif // ifndef NA_MSG
247
 
248
// EOF clock.c

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.