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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [kernel/] [current/] [tests/] [tm_basic.cxx] - Blame information for rev 817

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

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//        tm_basic.cxx
4
//
5
//        Basic timing test / scaffolding
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, 2003 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):     gthomas
43
// Contributors:  gthomas
44
// Date:          1998-10-19
45
// Description:   Very simple kernel timing test
46
//####DESCRIPTIONEND####
47
 
48
#include <pkgconf/kernel.h>
49
#include <pkgconf/hal.h>
50
 
51
#include <cyg/kernel/sched.hxx>
52
#include <cyg/kernel/thread.hxx>
53
#include <cyg/kernel/thread.inl>
54
#include <cyg/kernel/mutex.hxx>
55
#include <cyg/kernel/sema.hxx>
56
#include <cyg/kernel/flag.hxx>
57
#include <cyg/kernel/sched.inl>
58
#include <cyg/kernel/clock.hxx>
59
#include <cyg/kernel/clock.inl>
60
#include <cyg/kernel/kapi.h>
61
 
62
#include <cyg/infra/testcase.h>
63
#include <cyg/infra/diag.h>
64
 
65
#include <cyg/kernel/test/stackmon.h>
66
#include CYGHWR_MEMORY_LAYOUT_H
67
 
68
// Define this to see the statistics with the first sample datum removed.
69
// This can expose the effects of caches on the speed of operations.
70
#undef STATS_WITHOUT_FIRST_SAMPLE
71
 
72
#if defined(CYGFUN_KERNEL_API_C) &&             \
73
    defined(CYGSEM_KERNEL_SCHED_MLQUEUE) &&     \
74
    defined(CYGVAR_KERNEL_COUNTERS_CLOCK) &&    \
75
    !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) &&   \
76
    (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
77
 
78
#define NTHREADS 1
79
#include "testaux.hxx"
80
 
81
// Structure used to keep track of times
82
typedef struct fun_times {
83
    cyg_uint32 start;
84
    cyg_uint32 end;
85
} fun_times;
86
 
87
#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
88
 
89
#ifdef CYGMEM_REGION_ram_SIZE
90
#define CYG_THREAD_OVERHEAD  (STACK_SIZE+sizeof(cyg_thread)+(sizeof(fun_times)*2))
91
#define NTEST_THREADS_AVAIL  ((CYGMEM_REGION_ram_SIZE/16)/CYG_THREAD_OVERHEAD)
92
#define NTEST_THREADS        (2>(NTEST_THREADS_AVAIL)?2:(NTEST_THREADS_AVAIL))
93
#define CYG_MUTEX_OVERHEAD   (sizeof(cyg_mutex_t)+sizeof(fun_times))
94
#define NMUTEXES             ((CYGMEM_REGION_ram_SIZE/16)/CYG_MUTEX_OVERHEAD)
95
#define CYG_MBOX_OVERHEAD    (sizeof(cyg_mbox)+sizeof(fun_times))
96
#define NMBOXES              ((CYGMEM_REGION_ram_SIZE/24)/CYG_MBOX_OVERHEAD)
97
#define CYG_SEMAPHORE_OVERHEAD (sizeof(cyg_sem_t)+sizeof(fun_times))
98
#define NSEMAPHORES          ((CYGMEM_REGION_ram_SIZE/16)/CYG_SEMAPHORE_OVERHEAD)
99
#define CYG_COUNTER_OVERHEAD (sizeof(cyg_counter)+sizeof(fun_times))
100
#define NCOUNTERS            ((CYGMEM_REGION_ram_SIZE/24)/CYG_COUNTER_OVERHEAD)
101
#define CYG_FLAG_OVERHEAD    (sizeof(cyg_flag_t)+sizeof(fun_times))
102
#define NFLAGS               ((CYGMEM_REGION_ram_SIZE/24)/CYG_FLAG_OVERHEAD)
103
#define CYG_ALARM_OVERHEAD   (sizeof(cyg_alarm)+sizeof(fun_times))
104
#define NALARMS              ((CYGMEM_REGION_ram_SIZE/16)/CYG_ALARM_OVERHEAD)
105
#else
106
// Defaults
107
#define NTEST_THREADS    16
108
#define NMUTEXES         32
109
#define NMBOXES          32
110
#define NSEMAPHORES      32
111
#define NFLAGS           32
112
#define NCOUNTERS        32
113
#define NALARMS          32
114
#endif
115
 
116
#define NSAMPLES         32
117
#define NTHREAD_SWITCHES 128
118
#define NSCHEDS          128
119
 
120
#define NSAMPLES_SIM         2
121
#define NTEST_THREADS_SIM    2
122
#define NTHREAD_SWITCHES_SIM 4
123
#define NMUTEXES_SIM         2
124
#define NMBOXES_SIM          2
125
#define NSEMAPHORES_SIM      2
126
#define NSCHEDS_SIM          4
127
#define NFLAGS_SIM           2
128
#define NCOUNTERS_SIM        2
129
#define NALARMS_SIM          2
130
 
131
static int nsamples;
132
static int ntest_threads;
133
static int nthread_switches;
134
static int nmutexes;
135
static int nmboxes;
136
static int nsemaphores;
137
static int nscheds;
138
static int nflags;
139
static int ncounters;
140
static int nalarms;
141
 
142
static char stacks[NTEST_THREADS][STACK_SIZE];
143
static cyg_thread test_threads[NTEST_THREADS];
144
static cyg_handle_t threads[NTEST_THREADS];
145
static int overhead;
146
static cyg_sem_t synchro;
147
static fun_times thread_ft[NTEST_THREADS];
148
 
149
static fun_times test2_ft[NTHREAD_SWITCHES];
150
 
151
static cyg_mutex_t test_mutexes[NMUTEXES];
152
static fun_times mutex_ft[NMUTEXES];
153
static cyg_thread mutex_test_thread;
154
static cyg_handle_t mutex_test_thread_handle;
155
 
156
static cyg_mbox test_mboxes[NMBOXES];
157
static cyg_handle_t test_mbox_handles[NMBOXES];
158
static fun_times mbox_ft[NMBOXES];
159
#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
160
static cyg_thread mbox_test_thread;
161
static cyg_handle_t mbox_test_thread_handle;
162
#endif
163
 
164
static cyg_sem_t test_semaphores[NSEMAPHORES];
165
static fun_times semaphore_ft[NSEMAPHORES];
166
static cyg_thread semaphore_test_thread;
167
static cyg_handle_t semaphore_test_thread_handle;
168
 
169
static fun_times sched_ft[NSCHEDS];
170
 
171
static cyg_counter test_counters[NCOUNTERS];
172
static cyg_handle_t counters[NCOUNTERS];
173
static fun_times counter_ft[NCOUNTERS];
174
 
175
static cyg_flag_t test_flags[NFLAGS];
176
static fun_times flag_ft[NFLAGS];
177
 
178
static cyg_alarm test_alarms[NALARMS];
179
static cyg_handle_t alarms[NALARMS];
180
static fun_times alarm_ft[NALARMS];
181
 
182
static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;
183
static long ns_per_system_clock;
184
 
185
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY)  && defined(HAL_CLOCK_LATENCY)
186
// Data kept by kernel real time clock measuring clock interrupt latency
187
extern cyg_tick_count total_clock_latency, total_clock_interrupts;
188
extern cyg_int32 min_clock_latency, max_clock_latency;
189
extern bool measure_clock_latency;
190
#endif
191
 
192
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) && defined(HAL_CLOCK_LATENCY)
193
extern cyg_tick_count total_clock_dsr_latency, total_clock_dsr_calls;
194
extern cyg_int32 min_clock_dsr_latency, max_clock_dsr_latency;
195
extern bool measure_clock_latency;
196
#endif
197
 
198
void run_sched_tests(void);
199
void run_thread_tests(void);
200
void run_thread_switch_test(void);
201
void run_mutex_tests(void);
202
void run_mutex_circuit_test(void);
203
void run_mbox_tests(void);
204
void run_mbox_circuit_test(void);
205
void run_semaphore_tests(void);
206
void run_semaphore_circuit_test(void);
207
void run_counter_tests(void);
208
void run_flag_tests(void);
209
void run_alarm_tests(void);
210
 
211
#ifndef min
212
#define min(X,Y) ((X) < (Y) ? (X) : (Y))
213
#endif
214
 
215
// Wait until a clock tick [real time clock] has passed.  This should keep it
216
// from happening again during a measurement, thus minimizing any fluctuations
217
void
218
wait_for_tick(void)
219
{
220
    cyg_tick_count_t tv0, tv1;
221
    tv0 = cyg_current_time();
222
    while (true) {
223
        tv1 = cyg_current_time();
224
        if (tv1 != tv0) break;
225
    }
226
}
227
 
228
// Display a number of ticks as microseconds
229
// Note: for improved calculation significance, values are kept in ticks*1000
230
void
231
show_ticks_in_us(cyg_uint32 ticks)
232
{
233
    long long ns;
234
    ns = (ns_per_system_clock * (long long)ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
235
    ns += 5;  // for rounding to .01us
236
    diag_printf("%5d.%02d", (int)(ns/1000), (int)((ns%1000)/10));
237
}
238
 
239
//
240
// If the kernel is instrumented to measure clock interrupt latency, these
241
// measurements can be drastically perturbed by printing via "diag_printf()"
242
// since that code may run with interrupts disabled for long periods.
243
//
244
// In order to get accurate/reasonable latency figures _for the kernel 
245
// primitive functions beint tested_, the kernel's latency measurements
246
// are suspended while the printing actually takes place.
247
//
248
// The measurements are reenabled after the printing, thus allowing for
249
// fair measurements of the kernel primitives, which are not distorted
250
// by the printing mechanisms.
251
 
252
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
253
void
254
disable_clock_latency_measurement(void)
255
{
256
    wait_for_tick();
257
    measure_clock_latency = false;
258
}
259
 
260
void
261
enable_clock_latency_measurement(void)
262
{
263
    wait_for_tick();
264
    measure_clock_latency = true;
265
}
266
 
267
// Ensure that the measurements are reasonable (no startup anomalies)
268
void
269
reset_clock_latency_measurement(void)
270
{
271
  disable_clock_latency_measurement();
272
  total_clock_latency = 0;
273
  total_clock_interrupts = 0;
274
  min_clock_latency = 0x7FFFFFFF;
275
  max_clock_latency = 0;
276
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) && defined(HAL_CLOCK_LATENCY)
277
  total_clock_dsr_latency = 0;
278
  total_clock_dsr_calls = 0;
279
  min_clock_dsr_latency = 0x7FFFFFFF;
280
  max_clock_dsr_latency = 0;
281
#endif  
282
  enable_clock_latency_measurement();
283
 
284
}
285
#else
286
#define disable_clock_latency_measurement()
287
#define enable_clock_latency_measurement()
288
#define reset_clock_latency_measurement()
289
#endif
290
 
291
void
292
show_times_hdr(void)
293
{
294
    disable_clock_latency_measurement();
295
    diag_printf("\n");
296
    diag_printf("                                 Confidence\n");
297
    diag_printf("     Ave     Min     Max     Var  Ave  Min  Function\n");
298
    diag_printf("  ======  ======  ======  ====== ========== ========\n");
299
    enable_clock_latency_measurement();
300
}
301
 
302
void
303
show_times_detail(fun_times ft[], int nsamples, char *title, bool ignore_first)
304
{
305
    int i, delta, min, max, con_ave, con_min, ave_dev;
306
    int start_sample, total_samples;
307
    cyg_int32 total, ave;
308
 
309
    if (ignore_first) {
310
        start_sample = 1;
311
        total_samples = nsamples-1;
312
    } else {
313
        start_sample = 0;
314
        total_samples = nsamples;
315
    }
316
    total = 0;
317
    min = 0x7FFFFFFF;
318
    max = 0;
319
    for (i = start_sample;  i < nsamples;  i++) {
320
        if (ft[i].end < ft[i].start) {
321
            // Clock wrapped around (timer tick)
322
            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
323
        } else {
324
            delta = ft[i].end - ft[i].start;
325
        }
326
        delta -= overhead;
327
        if (delta < 0) delta = 0;
328
        delta *= 1000;
329
        total += delta;
330
        if (delta < min) min = delta;
331
        if (delta > max) max = delta;
332
    }
333
    ave = total / total_samples;
334
    total = 0;
335
    ave_dev = 0;
336
    for (i = start_sample;  i < nsamples;  i++) {
337
        if (ft[i].end < ft[i].start) {
338
            // Clock wrapped around (timer tick)
339
            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
340
        } else {
341
            delta = ft[i].end - ft[i].start;
342
        }
343
        delta -= overhead;
344
        if (delta < 0) delta = 0;
345
        delta *= 1000;
346
        delta = delta - ave;
347
        if (delta < 0) delta = -delta;
348
        ave_dev += delta;
349
    }
350
    ave_dev /= total_samples;
351
    con_ave = 0;
352
    con_min = 0;
353
    for (i = start_sample;  i < nsamples;  i++) {
354
        if (ft[i].end < ft[i].start) {
355
            // Clock wrapped around (timer tick)
356
            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
357
        } else {
358
            delta = ft[i].end - ft[i].start;
359
        }
360
        delta -= overhead;
361
        if (delta < 0) delta = 0;
362
        delta *= 1000;
363
        if ((delta <= (ave+ave_dev)) && (delta >= (ave-ave_dev))) con_ave++;
364
        if ((delta <= (min+ave_dev)) && (delta >= (min-ave_dev))) con_min++;
365
    }
366
    con_ave = (con_ave * 100) / total_samples;
367
    con_min = (con_min * 100) / total_samples;
368
    show_ticks_in_us(ave);
369
    show_ticks_in_us(min);
370
    show_ticks_in_us(max);
371
    show_ticks_in_us(ave_dev);
372
    disable_clock_latency_measurement();
373
    diag_printf("  %3d%% %3d%%", con_ave, con_min);
374
    diag_printf(" %s\n", title);
375
    enable_clock_latency_measurement();
376
}
377
 
378
void
379
show_times(fun_times ft[], int nsamples, char *title)
380
{
381
    show_times_detail(ft, nsamples, title, false);
382
#ifdef STATS_WITHOUT_FIRST_SAMPLE
383
    show_times_detail(ft, nsamples, "", true);
384
#endif
385
}
386
 
387
void
388
show_test_parameters(void)
389
{
390
    disable_clock_latency_measurement();
391
    diag_printf("\nTesting parameters:\n");
392
    diag_printf("   Clock samples:         %5d\n", nsamples);
393
    diag_printf("   Threads:               %5d\n", ntest_threads);
394
    diag_printf("   Thread switches:       %5d\n", nthread_switches);
395
    diag_printf("   Mutexes:               %5d\n", nmutexes);
396
    diag_printf("   Mailboxes:             %5d\n", nmboxes);
397
    diag_printf("   Semaphores:            %5d\n", nsemaphores);
398
    diag_printf("   Scheduler operations:  %5d\n", nscheds);
399
    diag_printf("   Counters:              %5d\n", ncounters);
400
    diag_printf("   Flags:                 %5d\n", nflags);
401
    diag_printf("   Alarms:                %5d\n", nalarms);
402
    diag_printf("\n");
403
    enable_clock_latency_measurement();
404
}
405
 
406
void
407
end_of_test_group(void)
408
{
409
    disable_clock_latency_measurement();
410
    diag_printf("\n");
411
    enable_clock_latency_measurement();
412
}
413
 
414
// Compute a name for a thread
415
char *
416
thread_name(char *basename, int indx) {
417
    return "<<NULL>>";  // Not currently used
418
}
419
 
420
// test0 - null test, never executed
421
void
422
test0(cyg_uint32 indx)
423
{
424
#ifndef CYGPKG_KERNEL_SMP_SUPPORT
425
    // In SMP, somw of these threads will execute
426
    diag_printf("test0.%d executed?\n", indx);
427
#endif    
428
    cyg_thread_exit();
429
}
430
 
431
// test1 - empty test, simply exit.  Last thread signals parent.
432
void
433
test1(cyg_uint32 indx)
434
{
435
    if (indx == (cyg_uint32)(ntest_threads-1)) {
436
        cyg_semaphore_post(&synchro);  // Signal that last thread is dying
437
    }
438
    cyg_thread_exit();
439
}
440
 
441
// test2 - measure thread switch times
442
void
443
test2(cyg_uint32 indx)
444
{
445
    int i;
446
    for (i = 0;  i < nthread_switches;  i++) {
447
        if (indx == 0) {
448
            HAL_CLOCK_READ(&test2_ft[i].start);
449
        } else {
450
            HAL_CLOCK_READ(&test2_ft[i].end);
451
        }
452
        cyg_thread_yield();
453
    }
454
    if (indx == 1) {
455
        cyg_semaphore_post(&synchro);
456
    }
457
    cyg_thread_exit();
458
}
459
 
460
// Full-circuit mutex unlock/lock test
461
void
462
mutex_test(cyg_uint32 indx)
463
{
464
    int i;
465
    cyg_mutex_lock(&test_mutexes[0]);
466
    for (i = 0;  i < nmutexes;  i++) {
467
        cyg_semaphore_wait(&synchro);
468
        wait_for_tick(); // Wait until the next clock tick to minimize aberations
469
        HAL_CLOCK_READ(&mutex_ft[i].start);
470
        cyg_mutex_unlock(&test_mutexes[0]);
471
        cyg_mutex_lock(&test_mutexes[0]);
472
        cyg_semaphore_post(&synchro);
473
    }
474
    cyg_thread_exit();
475
}
476
 
477
// Full-circuit mbox put/get test
478
void
479
mbox_test(cyg_uint32 indx)
480
{
481
    void *item;
482
    do {
483
        item = cyg_mbox_get(test_mbox_handles[0]);
484
        HAL_CLOCK_READ(&mbox_ft[(int)item].end);
485
        cyg_semaphore_post(&synchro);
486
    } while ((int)item != (nmboxes-1));
487
    cyg_thread_exit();
488
}
489
 
490
// Full-circuit semaphore post/wait test
491
void
492
semaphore_test(cyg_uint32 indx)
493
{
494
    int i;
495
    for (i = 0;  i < nsemaphores;  i++) {
496
        cyg_semaphore_wait(&test_semaphores[0]);
497
        HAL_CLOCK_READ(&semaphore_ft[i].end);
498
        cyg_semaphore_post(&synchro);
499
    }
500
    cyg_thread_exit();
501
}
502
 
503
//
504
// This set of tests is used to measure kernel primitives that deal with threads
505
//
506
void
507
run_thread_tests(void)
508
{
509
    int i;
510
    cyg_priority_t prio;
511
 
512
    // Set my priority higher than any I plan to create
513
    cyg_thread_set_priority(cyg_thread_self(), 2);
514
 
515
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
516
    for (i = 0;  i < ntest_threads;  i++) {
517
        HAL_CLOCK_READ(&thread_ft[i].start);
518
        cyg_thread_create(10,              // Priority - just a number
519
                          test0,           // entry
520
                          i,               // index
521
                          thread_name("thread", i),     // Name
522
                          &stacks[i][0],   // Stack
523
                          STACK_SIZE,      // Size
524
                          &threads[i],     // Handle
525
                          &test_threads[i] // Thread data structure
526
            );
527
        HAL_CLOCK_READ(&thread_ft[i].end);
528
    }
529
    show_times(thread_ft, ntest_threads, "Create thread");
530
 
531
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
532
    for (i = 0;  i < ntest_threads;  i++) {
533
        HAL_CLOCK_READ(&thread_ft[i].start);
534
        cyg_thread_yield();
535
        HAL_CLOCK_READ(&thread_ft[i].end);
536
    }
537
    show_times(thread_ft, ntest_threads, "Yield thread [all suspended]");
538
 
539
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
540
    for (i = 0;  i < ntest_threads;  i++) {
541
        HAL_CLOCK_READ(&thread_ft[i].start);
542
        cyg_thread_suspend(threads[i]);
543
        HAL_CLOCK_READ(&thread_ft[i].end);
544
    }
545
    show_times(thread_ft, ntest_threads, "Suspend [suspended] thread");
546
 
547
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
548
    for (i = 0;  i < ntest_threads;  i++) {
549
        HAL_CLOCK_READ(&thread_ft[i].start);
550
        cyg_thread_resume(threads[i]);
551
        HAL_CLOCK_READ(&thread_ft[i].end);
552
    }
553
    show_times(thread_ft, ntest_threads, "Resume thread");
554
 
555
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
556
    for (i = 0;  i < ntest_threads;  i++) {
557
        HAL_CLOCK_READ(&thread_ft[i].start);
558
        cyg_thread_set_priority(threads[i], 11);
559
        HAL_CLOCK_READ(&thread_ft[i].end);
560
    }
561
    show_times(thread_ft, ntest_threads, "Set priority");
562
 
563
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
564
    for (i = 0;  i < ntest_threads;  i++) {
565
        HAL_CLOCK_READ(&thread_ft[i].start);
566
        prio = cyg_thread_get_priority(threads[i]);
567
        HAL_CLOCK_READ(&thread_ft[i].end);
568
    }
569
    show_times(thread_ft, ntest_threads, "Get priority");
570
 
571
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
572
    for (i = 0;  i < ntest_threads;  i++) {
573
        HAL_CLOCK_READ(&thread_ft[i].start);
574
        cyg_thread_kill(threads[i]);
575
        HAL_CLOCK_READ(&thread_ft[i].end);
576
    }
577
    show_times(thread_ft, ntest_threads, "Kill [suspended] thread");
578
 
579
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
580
    for (i = 0;  i < ntest_threads;  i++) {
581
        HAL_CLOCK_READ(&thread_ft[i].start);
582
        cyg_thread_yield();
583
        HAL_CLOCK_READ(&thread_ft[i].end);
584
    }
585
    show_times(thread_ft, ntest_threads, "Yield [no other] thread");
586
 
587
    // Set my priority higher than any I plan to create
588
    cyg_thread_set_priority(cyg_thread_self(), 2);
589
 
590
    // Recreate the test set
591
    for (i = 0;  i < ntest_threads;  i++) {
592
        cyg_thread_create(10,              // Priority - just a number
593
                          test0,           // entry
594
                          i,               // index
595
                          thread_name("thread", i),     // Name
596
                          &stacks[i][0],   // Stack
597
                          STACK_SIZE,      // Size
598
                          &threads[i],     // Handle
599
                          &test_threads[i] // Thread data structure
600
            );
601
    }
602
 
603
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
604
    for (i = 0;  i < ntest_threads;  i++) {
605
        HAL_CLOCK_READ(&thread_ft[i].start);
606
        cyg_thread_resume(threads[i]);
607
        HAL_CLOCK_READ(&thread_ft[i].end);
608
    }
609
    show_times(thread_ft, ntest_threads, "Resume [suspended low prio] thread");
610
 
611
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
612
    for (i = 0;  i < ntest_threads;  i++) {
613
        HAL_CLOCK_READ(&thread_ft[i].start);
614
        cyg_thread_resume(threads[i]);
615
        HAL_CLOCK_READ(&thread_ft[i].end);
616
    }
617
    show_times(thread_ft, ntest_threads, "Resume [runnable low prio] thread");
618
 
619
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
620
    for (i = 0;  i < ntest_threads;  i++) {
621
        HAL_CLOCK_READ(&thread_ft[i].start);
622
        cyg_thread_suspend(threads[i]);
623
        HAL_CLOCK_READ(&thread_ft[i].end);
624
    }
625
    show_times(thread_ft, ntest_threads, "Suspend [runnable] thread");
626
 
627
 
628
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
629
    for (i = 0;  i < ntest_threads;  i++) {
630
        HAL_CLOCK_READ(&thread_ft[i].start);
631
        cyg_thread_yield();
632
        HAL_CLOCK_READ(&thread_ft[i].end);
633
    }
634
    show_times(thread_ft, ntest_threads, "Yield [only low prio] thread");
635
 
636
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
637
    for (i = 0;  i < ntest_threads;  i++) {
638
        HAL_CLOCK_READ(&thread_ft[i].start);
639
        cyg_thread_suspend(threads[i]);
640
        HAL_CLOCK_READ(&thread_ft[i].end);
641
    }
642
    show_times(thread_ft, ntest_threads, "Suspend [runnable->not runnable]");
643
    for (i = 0;  i < ntest_threads;  i++) {
644
        cyg_thread_resume(threads[i]);
645
    }
646
 
647
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
648
    for (i = 0;  i < ntest_threads;  i++) {
649
        HAL_CLOCK_READ(&thread_ft[i].start);
650
        cyg_thread_kill(threads[i]);
651
        HAL_CLOCK_READ(&thread_ft[i].end);
652
    }
653
    show_times(thread_ft, ntest_threads, "Kill [runnable] thread");
654
 
655
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
656
    for (i = 0;  i < ntest_threads;  i++) {
657
        HAL_CLOCK_READ(&thread_ft[i].start);
658
        cyg_thread_delete(threads[i]);
659
        HAL_CLOCK_READ(&thread_ft[i].end);
660
    }
661
    show_times(thread_ft, ntest_threads, "Destroy [dead] thread");
662
 
663
    // Recreate the test set
664
    for (i = 0;  i < ntest_threads;  i++) {
665
        cyg_thread_create(10,              // Priority - just a number
666
                          test0,           // entry
667
                          i,               // index
668
                          thread_name("thread", i),     // Name
669
                          &stacks[i][0],   // Stack
670
                          STACK_SIZE,      // Size
671
                          &threads[i],     // Handle
672
                          &test_threads[i] // Thread data structure
673
            );
674
        cyg_thread_resume(threads[i]);
675
    }
676
 
677
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
678
    for (i = 0;  i < ntest_threads;  i++) {
679
        HAL_CLOCK_READ(&thread_ft[i].start);
680
        cyg_thread_delete(threads[i]);
681
        HAL_CLOCK_READ(&thread_ft[i].end);
682
    }
683
    show_times(thread_ft, ntest_threads, "Destroy [runnable] thread");
684
 
685
    // Set my priority lower than any I plan to create
686
    cyg_thread_set_priority(cyg_thread_self(), 3);
687
 
688
    // Set up the end-of-threads synchronizer
689
    cyg_semaphore_init(&synchro, 0);
690
 
691
    // Recreate the test set
692
    for (i = 0;  i < ntest_threads;  i++) {
693
        cyg_thread_create(2,               // Priority - just a number
694
                          test1,           // entry
695
                          i,               // index
696
                          thread_name("thread", i),     // Name
697
                          &stacks[i][0],   // Stack
698
                          STACK_SIZE,      // Size
699
                          &threads[i],     // Handle
700
                          &test_threads[i] // Thread data structure
701
            );
702
    }
703
 
704
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
705
    for (i = 0;  i < ntest_threads;  i++) {
706
        HAL_CLOCK_READ(&thread_ft[i].start);
707
        cyg_thread_resume(threads[i]);
708
        HAL_CLOCK_READ(&thread_ft[i].end);
709
    }
710
    show_times(thread_ft, ntest_threads, "Resume [high priority] thread");
711
    cyg_semaphore_wait(&synchro);  // Wait for all threads to finish
712
    // Make sure they are all dead
713
    for (i = 0;  i < ntest_threads;  i++) {
714
        cyg_thread_delete(threads[i]);
715
    }
716
 
717
    run_thread_switch_test();
718
    end_of_test_group();
719
}
720
 
721
void
722
run_thread_switch_test(void)
723
{
724
    int i;
725
 
726
    // Set up for thread context switch 
727
    for (i = 0;  i < 2;  i++) {
728
        cyg_thread_create(10,              // Priority - just a number
729
                          test2,           // entry
730
                          i,               // index
731
                          thread_name("thread", i),     // Name
732
                          &stacks[i][0],   // Stack
733
                          STACK_SIZE,      // Size
734
                          &threads[i],     // Handle
735
                          &test_threads[i] // Thread data structure
736
            );
737
        cyg_thread_resume(threads[i]);
738
    }
739
    // Set up the end-of-threads synchronizer
740
    cyg_semaphore_init(&synchro, 0);
741
    cyg_semaphore_wait(&synchro);
742
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
743
    show_times(test2_ft, nthread_switches, "Thread switch");
744
    // Clean up
745
    for (i = 0;  i < 2;  i++) {
746
        cyg_thread_delete(threads[i]);
747
    }
748
}
749
 
750
void
751
run_mutex_tests(void)
752
{
753
    int i;
754
 
755
    // Mutex primitives
756
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
757
    for (i = 0;  i < nmutexes;  i++) {
758
        HAL_CLOCK_READ(&mutex_ft[i].start);
759
        cyg_mutex_init(&test_mutexes[i]);
760
        HAL_CLOCK_READ(&mutex_ft[i].end);
761
    }
762
    show_times(mutex_ft, nmutexes, "Init mutex");
763
 
764
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
765
    for (i = 0;  i < nmutexes;  i++) {
766
        HAL_CLOCK_READ(&mutex_ft[i].start);
767
        cyg_mutex_lock(&test_mutexes[i]);
768
        HAL_CLOCK_READ(&mutex_ft[i].end);
769
    }
770
    show_times(mutex_ft, nmutexes, "Lock [unlocked] mutex");
771
 
772
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
773
    for (i = 0;  i < nmutexes;  i++) {
774
        HAL_CLOCK_READ(&mutex_ft[i].start);
775
        cyg_mutex_unlock(&test_mutexes[i]);
776
        HAL_CLOCK_READ(&mutex_ft[i].end);
777
    }
778
    show_times(mutex_ft, nmutexes, "Unlock [locked] mutex");
779
 
780
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
781
    for (i = 0;  i < nmutexes;  i++) {
782
        HAL_CLOCK_READ(&mutex_ft[i].start);
783
        cyg_mutex_trylock(&test_mutexes[i]);
784
        HAL_CLOCK_READ(&mutex_ft[i].end);
785
    }
786
    show_times(mutex_ft, nmutexes, "Trylock [unlocked] mutex");
787
 
788
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
789
    for (i = 0;  i < nmutexes;  i++) {
790
        HAL_CLOCK_READ(&mutex_ft[i].start);
791
        cyg_mutex_trylock(&test_mutexes[i]);
792
        HAL_CLOCK_READ(&mutex_ft[i].end);
793
    }
794
    show_times(mutex_ft, nmutexes, "Trylock [locked] mutex");
795
 
796
    // Must unlock mutices before destroying them.
797
    for (i = 0;  i < nmutexes;  i++) {
798
        cyg_mutex_unlock(&test_mutexes[i]);
799
    }
800
 
801
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
802
    for (i = 0;  i < nmutexes;  i++) {
803
        HAL_CLOCK_READ(&mutex_ft[i].start);
804
        cyg_mutex_destroy(&test_mutexes[i]);
805
        HAL_CLOCK_READ(&mutex_ft[i].end);
806
    }
807
    show_times(mutex_ft, nmutexes, "Destroy mutex");
808
    run_mutex_circuit_test();
809
    end_of_test_group();
810
}
811
 
812
void
813
run_mutex_circuit_test(void)
814
{
815
    int i;
816
    // Set my priority lower than any I plan to create
817
    cyg_thread_set_priority(cyg_thread_self(), 4);
818
    // Set up for full mutex unlock/lock test
819
    cyg_mutex_init(&test_mutexes[0]);
820
    cyg_semaphore_init(&synchro, 0);
821
    cyg_thread_create(3,              // Priority - just a number
822
                      mutex_test,           // entry
823
                      0,               // index
824
                      thread_name("thread", 0),     // Name
825
                      &stacks[0][0],   // Stack
826
                      STACK_SIZE,      // Size
827
                      &mutex_test_thread_handle,   // Handle
828
                      &mutex_test_thread    // Thread data structure
829
        );
830
    cyg_thread_resume(mutex_test_thread_handle);
831
    // Need to raise priority so that this thread will block on the "lock"
832
    cyg_thread_set_priority(cyg_thread_self(), 2);
833
    for (i = 0;  i < nmutexes;  i++) {
834
        cyg_semaphore_post(&synchro);
835
        cyg_mutex_lock(&test_mutexes[0]);
836
        HAL_CLOCK_READ(&mutex_ft[i].end);
837
        cyg_mutex_unlock(&test_mutexes[0]);
838
        cyg_semaphore_wait(&synchro);
839
    }
840
    cyg_thread_delete(mutex_test_thread_handle);
841
    show_times(mutex_ft, nmutexes, "Unlock/Lock mutex");
842
}
843
 
844
void
845
run_mbox_tests(void)
846
{
847
    int i, cnt;
848
    void *item;
849
    // Mailbox primitives
850
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
851
    for (i = 0;  i < nmboxes;  i++) {
852
        HAL_CLOCK_READ(&mbox_ft[i].start);
853
        cyg_mbox_create(&test_mbox_handles[i], &test_mboxes[i]);
854
        HAL_CLOCK_READ(&mbox_ft[i].end);
855
    }
856
    show_times(mbox_ft, nmboxes, "Create mbox");
857
 
858
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
859
    for (i = 0;  i < nmboxes;  i++) {
860
        HAL_CLOCK_READ(&mbox_ft[i].start);
861
        cnt = cyg_mbox_peek(test_mbox_handles[i]);
862
        HAL_CLOCK_READ(&mbox_ft[i].end);
863
    }
864
    show_times(mbox_ft, nmboxes, "Peek [empty] mbox");
865
 
866
#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
867
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
868
    for (i = 0;  i < nmboxes;  i++) {
869
        HAL_CLOCK_READ(&mbox_ft[i].start);
870
        cyg_mbox_put(test_mbox_handles[i], (void *)i);
871
        HAL_CLOCK_READ(&mbox_ft[i].end);
872
    }
873
    show_times(mbox_ft, nmboxes, "Put [first] mbox");
874
 
875
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
876
    for (i = 0;  i < nmboxes;  i++) {
877
        HAL_CLOCK_READ(&mbox_ft[i].start);
878
        cnt = cyg_mbox_peek(test_mbox_handles[i]);
879
        HAL_CLOCK_READ(&mbox_ft[i].end);
880
    }
881
    show_times(mbox_ft, nmboxes, "Peek [1 msg] mbox");
882
 
883
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
884
    for (i = 0;  i < nmboxes;  i++) {
885
        HAL_CLOCK_READ(&mbox_ft[i].start);
886
        cyg_mbox_put(test_mbox_handles[i], (void *)i);
887
        HAL_CLOCK_READ(&mbox_ft[i].end);
888
    }
889
    show_times(mbox_ft, nmboxes, "Put [second] mbox");
890
 
891
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
892
    for (i = 0;  i < nmboxes;  i++) {
893
        HAL_CLOCK_READ(&mbox_ft[i].start);
894
        cnt = cyg_mbox_peek(test_mbox_handles[i]);
895
        HAL_CLOCK_READ(&mbox_ft[i].end);
896
    }
897
    show_times(mbox_ft, nmboxes, "Peek [2 msgs] mbox");
898
 
899
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
900
    for (i = 0;  i < nmboxes;  i++) {
901
        HAL_CLOCK_READ(&mbox_ft[i].start);
902
        item = cyg_mbox_get(test_mbox_handles[i]);
903
        HAL_CLOCK_READ(&mbox_ft[i].end);
904
    }
905
    show_times(mbox_ft, nmboxes, "Get [first] mbox");
906
 
907
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
908
    for (i = 0;  i < nmboxes;  i++) {
909
        HAL_CLOCK_READ(&mbox_ft[i].start);
910
        item = cyg_mbox_get(test_mbox_handles[i]);
911
        HAL_CLOCK_READ(&mbox_ft[i].end);
912
    }
913
    show_times(mbox_ft, nmboxes, "Get [second] mbox");
914
#endif // ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
915
 
916
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
917
    for (i = 0;  i < nmboxes;  i++) {
918
        HAL_CLOCK_READ(&mbox_ft[i].start);
919
        cyg_mbox_tryput(test_mbox_handles[i], (void *)i);
920
        HAL_CLOCK_READ(&mbox_ft[i].end);
921
    }
922
    show_times(mbox_ft, nmboxes, "Tryput [first] mbox");
923
 
924
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
925
    for (i = 0;  i < nmboxes;  i++) {
926
        HAL_CLOCK_READ(&mbox_ft[i].start);
927
        item = cyg_mbox_peek_item(test_mbox_handles[i]);
928
        HAL_CLOCK_READ(&mbox_ft[i].end);
929
    }
930
    show_times(mbox_ft, nmboxes, "Peek item [non-empty] mbox");
931
 
932
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
933
    for (i = 0;  i < nmboxes;  i++) {
934
        HAL_CLOCK_READ(&mbox_ft[i].start);
935
        item = cyg_mbox_tryget(test_mbox_handles[i]);
936
        HAL_CLOCK_READ(&mbox_ft[i].end);
937
    }
938
    show_times(mbox_ft, nmboxes, "Tryget [non-empty] mbox");
939
 
940
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
941
    for (i = 0;  i < nmboxes;  i++) {
942
        HAL_CLOCK_READ(&mbox_ft[i].start);
943
        item = cyg_mbox_peek_item(test_mbox_handles[i]);
944
        HAL_CLOCK_READ(&mbox_ft[i].end);
945
    }
946
    show_times(mbox_ft, nmboxes, "Peek item [empty] mbox");
947
 
948
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
949
    for (i = 0;  i < nmboxes;  i++) {
950
        HAL_CLOCK_READ(&mbox_ft[i].start);
951
        item = cyg_mbox_tryget(test_mbox_handles[i]);
952
        HAL_CLOCK_READ(&mbox_ft[i].end);
953
    }
954
    show_times(mbox_ft, nmboxes, "Tryget [empty] mbox");
955
 
956
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
957
    for (i = 0;  i < nmboxes;  i++) {
958
        HAL_CLOCK_READ(&mbox_ft[i].start);
959
        cyg_mbox_waiting_to_get(test_mbox_handles[i]);
960
        HAL_CLOCK_READ(&mbox_ft[i].end);
961
    }
962
    show_times(mbox_ft, nmboxes, "Waiting to get mbox");
963
 
964
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
965
    for (i = 0;  i < nmboxes;  i++) {
966
        HAL_CLOCK_READ(&mbox_ft[i].start);
967
        cyg_mbox_waiting_to_put(test_mbox_handles[i]);
968
        HAL_CLOCK_READ(&mbox_ft[i].end);
969
    }
970
    show_times(mbox_ft, nmboxes, "Waiting to put mbox");
971
 
972
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
973
    for (i = 0;  i < nmboxes;  i++) {
974
        HAL_CLOCK_READ(&mbox_ft[i].start);
975
        cyg_mbox_delete(test_mbox_handles[i]);
976
        HAL_CLOCK_READ(&mbox_ft[i].end);
977
    }
978
    show_times(mbox_ft, nmboxes, "Delete mbox");
979
 
980
    run_mbox_circuit_test();
981
    end_of_test_group();
982
}
983
 
984
void
985
run_mbox_circuit_test(void)
986
{
987
#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
988
    int i;
989
    // Set my priority lower than any I plan to create
990
    cyg_thread_set_priority(cyg_thread_self(), 3);
991
    // Set up for full mbox put/get test
992
    cyg_mbox_create(&test_mbox_handles[0], &test_mboxes[0]);
993
    cyg_semaphore_init(&synchro, 0);
994
    cyg_thread_create(2,              // Priority - just a number
995
                      mbox_test,           // entry
996
                      0,               // index
997
                      thread_name("thread", 0),     // Name
998
                      &stacks[0][0],   // Stack
999
                      STACK_SIZE,      // Size
1000
                      &mbox_test_thread_handle,   // Handle
1001
                      &mbox_test_thread    // Thread data structure
1002
        );
1003
    cyg_thread_resume(mbox_test_thread_handle);
1004
    for (i = 0;  i < nmboxes;  i++) {
1005
        wait_for_tick(); // Wait until the next clock tick to minimize aberations
1006
        HAL_CLOCK_READ(&mbox_ft[i].start);
1007
        cyg_mbox_put(test_mbox_handles[0], (void *)i);
1008
        cyg_semaphore_wait(&synchro);
1009
    }
1010
    cyg_thread_delete(mbox_test_thread_handle);
1011
    show_times(mbox_ft, nmboxes, "Put/Get mbox");
1012
#endif
1013
}
1014
 
1015
void
1016
run_semaphore_tests(void)
1017
{
1018
    int i;
1019
    cyg_count32 sem_val;
1020
    // Semaphore primitives
1021
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1022
    for (i = 0;  i < nsemaphores;  i++) {
1023
        HAL_CLOCK_READ(&semaphore_ft[i].start);
1024
        cyg_semaphore_init(&test_semaphores[i], 0);
1025
        HAL_CLOCK_READ(&semaphore_ft[i].end);
1026
    }
1027
    show_times(semaphore_ft, nsemaphores, "Init semaphore");
1028
 
1029
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1030
    for (i = 0;  i < nsemaphores;  i++) {
1031
        HAL_CLOCK_READ(&semaphore_ft[i].start);
1032
        cyg_semaphore_post(&test_semaphores[i]);
1033
        HAL_CLOCK_READ(&semaphore_ft[i].end);
1034
    }
1035
    show_times(semaphore_ft, nsemaphores, "Post [0] semaphore");
1036
 
1037
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1038
    for (i = 0;  i < nsemaphores;  i++) {
1039
        HAL_CLOCK_READ(&semaphore_ft[i].start);
1040
        cyg_semaphore_wait(&test_semaphores[i]);
1041
        HAL_CLOCK_READ(&semaphore_ft[i].end);
1042
    }
1043
    show_times(semaphore_ft, nsemaphores, "Wait [1] semaphore");
1044
 
1045
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1046
    for (i = 0;  i < nsemaphores;  i++) {
1047
        HAL_CLOCK_READ(&semaphore_ft[i].start);
1048
        cyg_semaphore_trywait(&test_semaphores[i]);
1049
        HAL_CLOCK_READ(&semaphore_ft[i].end);
1050
    }
1051
    show_times(semaphore_ft, nsemaphores, "Trywait [0] semaphore");
1052
 
1053
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1054
    for (i = 0;  i < nsemaphores;  i++) {
1055
        cyg_semaphore_post(&test_semaphores[i]);
1056
        HAL_CLOCK_READ(&semaphore_ft[i].start);
1057
        cyg_semaphore_trywait(&test_semaphores[i]);
1058
        HAL_CLOCK_READ(&semaphore_ft[i].end);
1059
    }
1060
    show_times(semaphore_ft, nsemaphores, "Trywait [1] semaphore");
1061
 
1062
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1063
    for (i = 0;  i < nsemaphores;  i++) {
1064
        HAL_CLOCK_READ(&semaphore_ft[i].start);
1065
        cyg_semaphore_peek(&test_semaphores[i], &sem_val);
1066
        HAL_CLOCK_READ(&semaphore_ft[i].end);
1067
    }
1068
    show_times(semaphore_ft, nsemaphores, "Peek semaphore");
1069
 
1070
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1071
    for (i = 0;  i < nsemaphores;  i++) {
1072
        HAL_CLOCK_READ(&semaphore_ft[i].start);
1073
        cyg_semaphore_destroy(&test_semaphores[i]);
1074
        HAL_CLOCK_READ(&semaphore_ft[i].end);
1075
    }
1076
    show_times(semaphore_ft, nsemaphores, "Destroy semaphore");
1077
 
1078
    run_semaphore_circuit_test();
1079
    end_of_test_group();
1080
}
1081
 
1082
void
1083
run_semaphore_circuit_test(void)
1084
{
1085
    int i;
1086
    // Set my priority lower than any I plan to create
1087
    cyg_thread_set_priority(cyg_thread_self(), 3);
1088
    // Set up for full semaphore post/wait test
1089
    cyg_semaphore_init(&test_semaphores[0], 0);
1090
    cyg_semaphore_init(&synchro, 0);
1091
    cyg_thread_create(2,              // Priority - just a number
1092
                      semaphore_test,           // entry
1093
                      0,               // index
1094
                      thread_name("thread", 0),     // Name
1095
                      &stacks[0][0],   // Stack
1096
                      STACK_SIZE,      // Size
1097
                      &semaphore_test_thread_handle,   // Handle
1098
                      &semaphore_test_thread    // Thread data structure
1099
        );
1100
    cyg_thread_resume(semaphore_test_thread_handle);
1101
    for (i = 0;  i < nsemaphores;  i++) {
1102
        wait_for_tick(); // Wait until the next clock tick to minimize aberations
1103
        HAL_CLOCK_READ(&semaphore_ft[i].start);
1104
        cyg_semaphore_post(&test_semaphores[0]);
1105
        cyg_semaphore_wait(&synchro);
1106
    }
1107
    cyg_thread_delete(semaphore_test_thread_handle);
1108
    show_times(semaphore_ft, nsemaphores, "Post/Wait semaphore");
1109
}
1110
 
1111
void
1112
run_counter_tests(void)
1113
{
1114
    int i;
1115
    cyg_tick_count_t val=0;
1116
 
1117
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1118
    for (i = 0;  i < ncounters;  i++) {
1119
        HAL_CLOCK_READ(&counter_ft[i].start);
1120
        cyg_counter_create(&counters[i], &test_counters[i]);
1121
        HAL_CLOCK_READ(&counter_ft[i].end);
1122
    }
1123
    show_times(counter_ft, ncounters, "Create counter");
1124
 
1125
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1126
    for (i = 0;  i < ncounters;  i++) {
1127
        HAL_CLOCK_READ(&counter_ft[i].start);
1128
        val = cyg_counter_current_value(counters[i]);
1129
        HAL_CLOCK_READ(&counter_ft[i].end);
1130
    }
1131
    show_times(counter_ft, ncounters, "Get counter value");
1132
 
1133
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1134
    for (i = 0;  i < ncounters;  i++) {
1135
        HAL_CLOCK_READ(&counter_ft[i].start);
1136
        cyg_counter_set_value(counters[i], val);
1137
        HAL_CLOCK_READ(&counter_ft[i].end);
1138
    }
1139
    show_times(counter_ft, ncounters, "Set counter value");
1140
 
1141
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1142
    for (i = 0;  i < ncounters;  i++) {
1143
        HAL_CLOCK_READ(&counter_ft[i].start);
1144
        cyg_counter_tick(counters[i]);
1145
        HAL_CLOCK_READ(&counter_ft[i].end);
1146
    }
1147
    show_times(counter_ft, ncounters, "Tick counter");
1148
 
1149
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1150
    for (i = 0;  i < ncounters;  i++) {
1151
        HAL_CLOCK_READ(&counter_ft[i].start);
1152
        cyg_counter_delete(counters[i]);
1153
        HAL_CLOCK_READ(&counter_ft[i].end);
1154
    }
1155
    show_times(counter_ft, ncounters, "Delete counter");
1156
    end_of_test_group();
1157
}
1158
 
1159
void
1160
run_flag_tests(void)
1161
{
1162
    int i;
1163
    cyg_flag_value_t val;
1164
 
1165
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1166
    for (i = 0;  i < nflags;  i++) {
1167
        HAL_CLOCK_READ(&flag_ft[i].start);
1168
        cyg_flag_init(&test_flags[i]);
1169
        HAL_CLOCK_READ(&flag_ft[i].end);
1170
    }
1171
    show_times(flag_ft, nflags, "Init flag");
1172
 
1173
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1174
    for (i = 0;  i < nflags;  i++) {
1175
        HAL_CLOCK_READ(&flag_ft[i].start);
1176
        cyg_flag_destroy(&test_flags[i]);
1177
        HAL_CLOCK_READ(&flag_ft[i].end);
1178
    }
1179
    show_times(flag_ft, nflags, "Destroy flag");
1180
 
1181
    // Recreate the flags - reused in the remaining tests
1182
    for (i = 0;  i < nflags;  i++) {
1183
        cyg_flag_init(&test_flags[i]);
1184
    }
1185
 
1186
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1187
    for (i = 0;  i < nflags;  i++) {
1188
        HAL_CLOCK_READ(&flag_ft[i].start);
1189
        cyg_flag_maskbits(&test_flags[i], 0);
1190
        HAL_CLOCK_READ(&flag_ft[i].end);
1191
    }
1192
    show_times(flag_ft, nflags, "Mask bits in flag");
1193
 
1194
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1195
    for (i = 0;  i < nflags;  i++) {
1196
        HAL_CLOCK_READ(&flag_ft[i].start);
1197
        cyg_flag_setbits(&test_flags[i], 0x11);
1198
        HAL_CLOCK_READ(&flag_ft[i].end);
1199
    }
1200
    show_times(flag_ft, nflags, "Set bits in flag [no waiters]");
1201
 
1202
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1203
    for (i = 0;  i < nflags;  i++) {
1204
        cyg_flag_setbits(&test_flags[i], 0x11);
1205
        HAL_CLOCK_READ(&flag_ft[i].start);
1206
        cyg_flag_wait(&test_flags[i], 0x11, CYG_FLAG_WAITMODE_AND);
1207
        HAL_CLOCK_READ(&flag_ft[i].end);
1208
    }
1209
    show_times(flag_ft, nflags, "Wait for flag [AND]");
1210
 
1211
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1212
    for (i = 0;  i < nflags;  i++) {
1213
        cyg_flag_setbits(&test_flags[i], 0x11);
1214
        HAL_CLOCK_READ(&flag_ft[i].start);
1215
        cyg_flag_wait(&test_flags[i], 0x11, CYG_FLAG_WAITMODE_OR);
1216
        HAL_CLOCK_READ(&flag_ft[i].end);
1217
    }
1218
    show_times(flag_ft, nflags, "Wait for flag [OR]");
1219
 
1220
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1221
    for (i = 0;  i < nflags;  i++) {
1222
        cyg_flag_setbits(&test_flags[i], 0x11);
1223
        HAL_CLOCK_READ(&flag_ft[i].start);
1224
        cyg_flag_wait(&test_flags[i], 0x11, CYG_FLAG_WAITMODE_AND|CYG_FLAG_WAITMODE_CLR);
1225
        HAL_CLOCK_READ(&flag_ft[i].end);
1226
    }
1227
    show_times(flag_ft, nflags, "Wait for flag [AND/CLR]");
1228
 
1229
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1230
    for (i = 0;  i < nflags;  i++) {
1231
        cyg_flag_setbits(&test_flags[i], 0x11);
1232
        HAL_CLOCK_READ(&flag_ft[i].start);
1233
        cyg_flag_wait(&test_flags[i], 0x11, CYG_FLAG_WAITMODE_OR|CYG_FLAG_WAITMODE_CLR);
1234
        HAL_CLOCK_READ(&flag_ft[i].end);
1235
    }
1236
    show_times(flag_ft, nflags, "Wait for flag [OR/CLR]");
1237
 
1238
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1239
    for (i = 0;  i < nflags;  i++) {
1240
        cyg_flag_setbits(&test_flags[i], 0x11);
1241
        HAL_CLOCK_READ(&flag_ft[i].start);
1242
        val = cyg_flag_peek(&test_flags[i]);
1243
        HAL_CLOCK_READ(&flag_ft[i].end);
1244
    }
1245
    show_times(flag_ft, nflags, "Peek on flag");
1246
 
1247
    // Destroy flags - no longer needed
1248
    for (i = 0;  i < nflags;  i++) {
1249
        cyg_flag_destroy(&test_flags[i]);
1250
    }
1251
    end_of_test_group();
1252
}
1253
 
1254
// Alarm callback function
1255
void
1256
alarm_cb(cyg_handle_t alarm, cyg_addrword_t val)
1257
{
1258
    // empty call back
1259
}
1260
 
1261
// Callback used to test determinancy
1262
static volatile int alarm_cnt;
1263
void
1264
alarm_cb2(cyg_handle_t alarm, cyg_addrword_t indx)
1265
{
1266
    if (alarm_cnt == nscheds) return;
1267
    sched_ft[alarm_cnt].start = 0;
1268
    HAL_CLOCK_READ(&sched_ft[alarm_cnt++].end);
1269
    if (alarm_cnt == nscheds) {
1270
        cyg_semaphore_post(&synchro);
1271
    }
1272
}
1273
 
1274
static void
1275
alarm_cb3(cyg_handle_t alarm, cyg_addrword_t indx)
1276
{
1277
    if (alarm_cnt == nscheds) {
1278
        cyg_semaphore_post(&synchro);
1279
    } else {
1280
        sched_ft[alarm_cnt].start = 0;
1281
        cyg_thread_resume((cyg_handle_t)indx);
1282
    }
1283
}
1284
 
1285
// Null thread, used to keep scheduler busy
1286
void
1287
alarm_test(cyg_uint32 id)
1288
{
1289
    while (true) {
1290
        cyg_thread_yield();
1291
    }
1292
}
1293
 
1294
// Thread that suspends itself at the first opportunity
1295
void
1296
alarm_test2(cyg_uint32 id)
1297
{
1298
    cyg_handle_t me = cyg_thread_self();
1299
    while (true) {
1300
        HAL_CLOCK_READ(&sched_ft[alarm_cnt++].end);
1301
        cyg_thread_suspend(me);
1302
    }
1303
}
1304
 
1305
void
1306
run_alarm_tests(void)
1307
{
1308
    int i;
1309
    cyg_tick_count_t init_val, step_val;
1310
    cyg_handle_t rtc_handle;
1311
 
1312
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1313
    for (i = 0;  i < ncounters;  i++) {
1314
        cyg_counter_create(&counters[i], &test_counters[i]);
1315
    }
1316
    for (i = 0;  i < nalarms;  i++) {
1317
        HAL_CLOCK_READ(&alarm_ft[i].start);
1318
        cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]);
1319
        HAL_CLOCK_READ(&alarm_ft[i].end);
1320
    }
1321
    show_times(alarm_ft, nalarms, "Create alarm");
1322
 
1323
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1324
    init_val = 0;  step_val = 0;
1325
    for (i = 0;  i < nalarms;  i++) {
1326
        HAL_CLOCK_READ(&alarm_ft[i].start);
1327
        cyg_alarm_initialize(alarms[i], init_val, step_val);
1328
        HAL_CLOCK_READ(&alarm_ft[i].end);
1329
    }
1330
    show_times(alarm_ft, nalarms, "Initialize alarm");
1331
 
1332
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1333
    init_val = 0;  step_val = 0;
1334
    for (i = 0;  i < nalarms;  i++) {
1335
        HAL_CLOCK_READ(&alarm_ft[i].start);
1336
        cyg_alarm_disable(alarms[i]);
1337
        HAL_CLOCK_READ(&alarm_ft[i].end);
1338
    }
1339
    show_times(alarm_ft, nalarms, "Disable alarm");
1340
 
1341
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1342
    init_val = 0;  step_val = 0;
1343
    for (i = 0;  i < nalarms;  i++) {
1344
        HAL_CLOCK_READ(&alarm_ft[i].start);
1345
        cyg_alarm_enable(alarms[i]);
1346
        HAL_CLOCK_READ(&alarm_ft[i].end);
1347
    }
1348
    show_times(alarm_ft, nalarms, "Enable alarm");
1349
 
1350
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1351
    for (i = 0;  i < nalarms;  i++) {
1352
        HAL_CLOCK_READ(&alarm_ft[i].start);
1353
        cyg_alarm_delete(alarms[i]);
1354
        HAL_CLOCK_READ(&alarm_ft[i].end);
1355
    }
1356
    show_times(alarm_ft, nalarms, "Delete alarm");
1357
 
1358
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1359
    cyg_counter_create(&counters[0], &test_counters[0]);
1360
    cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]);
1361
    init_val = 9999;  step_val = 9999;
1362
    cyg_alarm_initialize(alarms[0], init_val, step_val);
1363
    cyg_alarm_enable(alarms[0]);
1364
    for (i = 0;  i < ncounters;  i++) {
1365
        HAL_CLOCK_READ(&counter_ft[i].start);
1366
        cyg_counter_tick(counters[0]);
1367
        HAL_CLOCK_READ(&counter_ft[i].end);
1368
    }
1369
    show_times(counter_ft, ncounters, "Tick counter [1 alarm]");
1370
 
1371
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1372
    cyg_counter_create(&counters[0], &test_counters[0]);
1373
    for (i = 0;  i < nalarms;  i++) {
1374
        cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]);
1375
        init_val = 9999;  step_val = 9999;
1376
        cyg_alarm_initialize(alarms[i], init_val, step_val);
1377
        cyg_alarm_enable(alarms[i]);
1378
    }
1379
    for (i = 0;  i < ncounters;  i++) {
1380
        HAL_CLOCK_READ(&counter_ft[i].start);
1381
        cyg_counter_tick(counters[0]);
1382
        HAL_CLOCK_READ(&counter_ft[i].end);
1383
    }
1384
    show_times(counter_ft, ncounters, "Tick counter [many alarms]");
1385
 
1386
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1387
    cyg_counter_create(&counters[0], &test_counters[0]);
1388
    cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]);
1389
    init_val = 1;  step_val = 1;
1390
    cyg_alarm_initialize(alarms[0], init_val, step_val);
1391
    cyg_alarm_enable(alarms[0]);
1392
    for (i = 0;  i < ncounters;  i++) {
1393
        HAL_CLOCK_READ(&counter_ft[i].start);
1394
        cyg_counter_tick(counters[0]);
1395
        HAL_CLOCK_READ(&counter_ft[i].end);
1396
    }
1397
    show_times(counter_ft, ncounters, "Tick & fire counter [1 alarm]");
1398
 
1399
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1400
    cyg_counter_create(&counters[0], &test_counters[0]);
1401
    for (i = 0;  i < nalarms;  i++) {
1402
        cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]);
1403
        init_val = 1;  step_val = 1;
1404
        cyg_alarm_initialize(alarms[i], init_val, step_val);
1405
        cyg_alarm_enable(alarms[i]);
1406
    }
1407
    for (i = 0;  i < nalarms;  i++) {
1408
        HAL_CLOCK_READ(&alarm_ft[i].start);
1409
        cyg_counter_tick(counters[0]);
1410
        HAL_CLOCK_READ(&alarm_ft[i].end);
1411
    }
1412
    for (i = 0;  i < nalarms;  i++) {
1413
        cyg_alarm_delete(alarms[i]);
1414
    }
1415
    show_times(alarm_ft, nalarms, "Tick & fire counters [>1 together]");
1416
 
1417
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1418
    cyg_counter_create(&counters[0], &test_counters[0]);
1419
    for (i = 0;  i < nalarms;  i++) {
1420
        cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]);
1421
        init_val = i+1;  step_val = nalarms+1;
1422
        cyg_alarm_initialize(alarms[i], init_val, step_val);
1423
        cyg_alarm_enable(alarms[i]);
1424
    }
1425
    for (i = 0;  i < nalarms;  i++) {
1426
        HAL_CLOCK_READ(&alarm_ft[i].start);
1427
        cyg_counter_tick(counters[0]);
1428
        HAL_CLOCK_READ(&alarm_ft[i].end);
1429
    }
1430
    for (i = 0;  i < nalarms;  i++) {
1431
        cyg_alarm_delete(alarms[i]);
1432
    }
1433
    show_times(alarm_ft, nalarms, "Tick & fire counters [>1 separately]");
1434
 
1435
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1436
    cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle);
1437
    cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]);
1438
    init_val = 5;  step_val = 5;  alarm_cnt = 0;
1439
    cyg_alarm_initialize(alarms[0], init_val, step_val);
1440
    cyg_semaphore_init(&synchro, 0);
1441
    cyg_alarm_enable(alarms[0]);
1442
    cyg_semaphore_wait(&synchro);
1443
    cyg_alarm_disable(alarms[0]);
1444
    cyg_alarm_delete(alarms[0]);
1445
    show_times(sched_ft, nscheds, "Alarm latency [0 threads]");
1446
 
1447
    // Set my priority higher than any I plan to create
1448
    cyg_thread_set_priority(cyg_thread_self(), 2);
1449
    for (i = 0;  i < 2;  i++) {
1450
        cyg_thread_create(10,              // Priority - just a number
1451
                          alarm_test,      // entry
1452
                          i,               // index
1453
                          thread_name("thread", i),     // Name
1454
                          &stacks[i][0],   // Stack
1455
                          STACK_SIZE,      // Size
1456
                          &threads[i],     // Handle
1457
                          &test_threads[i] // Thread data structure
1458
            );
1459
        cyg_thread_resume(threads[i]);
1460
    }
1461
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1462
    cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle);
1463
    cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]);
1464
    init_val = 5;  step_val = 5;  alarm_cnt = 0;
1465
    cyg_alarm_initialize(alarms[0], init_val, step_val);
1466
    cyg_semaphore_init(&synchro, 0);
1467
    cyg_alarm_enable(alarms[0]);
1468
    cyg_semaphore_wait(&synchro);
1469
    cyg_alarm_disable(alarms[0]);
1470
    cyg_alarm_delete(alarms[0]);
1471
    show_times(sched_ft, nscheds, "Alarm latency [2 threads]");
1472
    for (i = 0;  i < 2;  i++) {
1473
        cyg_thread_suspend(threads[i]);
1474
        cyg_thread_delete(threads[i]);
1475
    }
1476
 
1477
    // Set my priority higher than any I plan to create
1478
    cyg_thread_set_priority(cyg_thread_self(), 2);
1479
    for (i = 0;  i < ntest_threads;  i++) {
1480
        cyg_thread_create(10,              // Priority - just a number
1481
                          alarm_test,      // entry
1482
                          i,               // index
1483
                          thread_name("thread", i),     // Name
1484
                          &stacks[i][0],   // Stack
1485
                          STACK_SIZE,      // Size
1486
                          &threads[i],     // Handle
1487
                          &test_threads[i] // Thread data structure
1488
            );
1489
        cyg_thread_resume(threads[i]);
1490
    }
1491
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1492
    cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle);
1493
    cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]);
1494
    init_val = 5;  step_val = 5;  alarm_cnt = 0;
1495
    cyg_alarm_initialize(alarms[0], init_val, step_val);
1496
    cyg_semaphore_init(&synchro, 0);
1497
    cyg_alarm_enable(alarms[0]);
1498
    cyg_semaphore_wait(&synchro);
1499
    cyg_alarm_disable(alarms[0]);
1500
    cyg_alarm_delete(alarms[0]);
1501
    show_times(sched_ft, nscheds, "Alarm latency [many threads]");
1502
    for (i = 0;  i < ntest_threads;  i++) {
1503
        cyg_thread_suspend(threads[i]);
1504
        cyg_thread_delete(threads[i]);
1505
    }
1506
 
1507
    // Set my priority higher than any I plan to create
1508
    cyg_thread_set_priority(cyg_thread_self(), 2);
1509
    cyg_thread_create(10,              // Priority - just a number
1510
                      alarm_test2,     // entry
1511
                      i,               // index
1512
                      thread_name("thread", 0),     // Name
1513
                      &stacks[0][0],   // Stack
1514
                      STACK_SIZE,      // Size
1515
                      &threads[0],     // Handle
1516
                      &test_threads[0] // Thread data structure
1517
        );
1518
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1519
    cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle);
1520
    cyg_alarm_create(rtc_handle, alarm_cb3, threads[0], &alarms[0],
1521
                     &test_alarms[0]);
1522
    init_val = 5;  step_val = 5;  alarm_cnt = 0;
1523
    cyg_alarm_initialize(alarms[0], init_val, step_val);
1524
    cyg_semaphore_init(&synchro, 0);
1525
    cyg_alarm_enable(alarms[0]);
1526
    cyg_semaphore_wait(&synchro);
1527
    cyg_alarm_disable(alarms[0]);
1528
    cyg_alarm_delete(alarms[0]);
1529
    show_times(sched_ft, nscheds, "Alarm -> thread resume latency");
1530
    cyg_thread_suspend(threads[0]);
1531
    cyg_thread_delete(threads[0]);
1532
 
1533
    end_of_test_group();
1534
}
1535
 
1536
void
1537
run_sched_tests(void)
1538
{
1539
    int i;
1540
 
1541
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1542
    for (i = 0;  i < nscheds;  i++) {
1543
        HAL_CLOCK_READ(&sched_ft[i].start);
1544
        cyg_scheduler_lock();
1545
        HAL_CLOCK_READ(&sched_ft[i].end);
1546
        cyg_scheduler_unlock();
1547
    }
1548
    show_times(sched_ft, nscheds, "Scheduler lock");
1549
 
1550
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1551
    for (i = 0;  i < nscheds;  i++) {
1552
        cyg_scheduler_lock();
1553
        HAL_CLOCK_READ(&sched_ft[i].start);
1554
        cyg_scheduler_unlock();
1555
        HAL_CLOCK_READ(&sched_ft[i].end);
1556
    }
1557
    show_times(sched_ft, nscheds, "Scheduler unlock [0 threads]");
1558
 
1559
    // Set my priority higher than any I plan to create
1560
    cyg_thread_set_priority(cyg_thread_self(), 2);
1561
    for (i = 0;  i < 1;  i++) {
1562
        cyg_thread_create(10,              // Priority - just a number
1563
                          test0,           // entry
1564
                          i,               // index
1565
                          thread_name("thread", i),     // Name
1566
                          &stacks[i][0],   // Stack
1567
                          STACK_SIZE,      // Size
1568
                          &threads[i],     // Handle
1569
                          &test_threads[i] // Thread data structure
1570
            );
1571
    }
1572
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1573
    for (i = 0;  i < nscheds;  i++) {
1574
        cyg_scheduler_lock();
1575
        HAL_CLOCK_READ(&sched_ft[i].start);
1576
        cyg_scheduler_unlock();
1577
        HAL_CLOCK_READ(&sched_ft[i].end);
1578
    }
1579
    show_times(sched_ft, nscheds, "Scheduler unlock [1 suspended]");
1580
    for (i = 0;  i < 1;  i++) {
1581
        cyg_thread_delete(threads[i]);
1582
    }
1583
 
1584
    // Set my priority higher than any I plan to create
1585
    cyg_thread_set_priority(cyg_thread_self(), 2);
1586
    for (i = 0;  i < ntest_threads;  i++) {
1587
        cyg_thread_create(10,              // Priority - just a number
1588
                          test0,           // entry
1589
                          i,               // index
1590
                          thread_name("thread", i),     // Name
1591
                          &stacks[i][0],   // Stack
1592
                          STACK_SIZE,      // Size
1593
                          &threads[i],     // Handle
1594
                          &test_threads[i] // Thread data structure
1595
            );
1596
    }
1597
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1598
    for (i = 0;  i < nscheds;  i++) {
1599
        cyg_scheduler_lock();
1600
        HAL_CLOCK_READ(&sched_ft[i].start);
1601
        cyg_scheduler_unlock();
1602
        HAL_CLOCK_READ(&sched_ft[i].end);
1603
    }
1604
    show_times(sched_ft, nscheds, "Scheduler unlock [many suspended]");
1605
    for (i = 0;  i < ntest_threads;  i++) {
1606
        cyg_thread_delete(threads[i]);
1607
    }
1608
 
1609
    // Set my priority higher than any I plan to create
1610
    cyg_thread_set_priority(cyg_thread_self(), 2);
1611
    for (i = 0;  i < ntest_threads;  i++) {
1612
        cyg_thread_create(10,              // Priority - just a number
1613
                          test0,           // entry
1614
                          i,               // index
1615
                          thread_name("thread", i),     // Name
1616
                          &stacks[i][0],   // Stack
1617
                          STACK_SIZE,      // Size
1618
                          &threads[i],     // Handle
1619
                          &test_threads[i] // Thread data structure
1620
            );
1621
        cyg_thread_resume(threads[i]);
1622
    }
1623
    wait_for_tick(); // Wait until the next clock tick to minimize aberations
1624
    for (i = 0;  i < nscheds;  i++) {
1625
        cyg_scheduler_lock();
1626
        HAL_CLOCK_READ(&sched_ft[i].start);
1627
        cyg_scheduler_unlock();
1628
        HAL_CLOCK_READ(&sched_ft[i].end);
1629
    }
1630
    show_times(sched_ft, nscheds, "Scheduler unlock [many low prio]");
1631
    for (i = 0;  i < ntest_threads;  i++) {
1632
        cyg_thread_delete(threads[i]);
1633
    }
1634
    end_of_test_group();
1635
}
1636
 
1637
static void
1638
_run_all_tests(CYG_ADDRESS id)
1639
{
1640
    int i, j;
1641
    cyg_uint32 tv[nsamples], tv0, tv1;
1642
    cyg_uint32 min_stack, max_stack, total_stack, actual_stack;
1643
    cyg_tick_count_t ticks, tick0, tick1;
1644
#ifdef CYG_SCHEDULER_LOCK_TIMINGS
1645
    cyg_uint32 lock_ave, lock_max;
1646
#endif
1647
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
1648
    cyg_int32 clock_ave;
1649
#endif
1650
 
1651
    disable_clock_latency_measurement();
1652
 
1653
#ifndef CYGPKG_KERNEL_SMP_SUPPORT
1654
    cyg_test_dump_thread_stack_stats( "Startup, main stack", thread[0] );
1655
    cyg_test_dump_interrupt_stack_stats( "Startup" );
1656
    cyg_test_dump_idlethread_stack_stats( "Startup" );
1657
    cyg_test_clear_interrupt_stack();
1658
#endif
1659
 
1660
    diag_printf("\neCos Kernel Timings\n");
1661
    diag_printf("Notes: all times are in microseconds (.000001) unless otherwise stated\n");
1662
#ifdef STATS_WITHOUT_FIRST_SAMPLE
1663
    diag_printf("       second line of results have first sample removed\n");
1664
#endif
1665
 
1666
    cyg_thread_delay(2);  // Make sure the clock is actually running
1667
 
1668
    ns_per_system_clock = 1000000/rtc_resolution[1];
1669
 
1670
    wait_for_tick();
1671
    for (i = 0;  i < nsamples;  i++) {
1672
        HAL_CLOCK_READ(&tv[i]);
1673
    }
1674
    tv0 = 0;
1675
    for (i = 1;  i < nsamples;  i++) {
1676
        tv0 += tv[i] - tv[i-1];
1677
    }
1678
    end_of_test_group();
1679
 
1680
    overhead = tv0 / (nsamples-1);
1681
    diag_printf("Reading the hardware clock takes %d 'ticks' overhead\n", overhead);
1682
    diag_printf("... this value will be factored out of all other measurements\n");
1683
 
1684
    // Try and measure how long the clock interrupt handling takes
1685
    for (i = 0;  i < nsamples;  i++) {
1686
        tick0 = cyg_current_time();
1687
        while (true) {
1688
            tick1 = cyg_current_time();
1689
            if (tick0 != tick1) break;
1690
        }
1691
        HAL_CLOCK_READ(&tv[i]);
1692
    }
1693
    tv1 = 0;
1694
    for (i = 0;  i < nsamples;  i++) {
1695
        tv1 += tv[i] * 1000;
1696
    }
1697
    tv1 = tv1 / nsamples;
1698
    tv1 -= overhead;  // Adjust out the cost of getting the timer value
1699
    diag_printf("Clock interrupt took");
1700
    show_ticks_in_us(tv1);
1701
    diag_printf(" microseconds (%d raw clock ticks)\n", tv1/1000);
1702
    enable_clock_latency_measurement();
1703
 
1704
    ticks = cyg_current_time();
1705
 
1706
    show_test_parameters();
1707
    show_times_hdr();
1708
 
1709
    reset_clock_latency_measurement();
1710
 
1711
    run_thread_tests();
1712
    run_sched_tests();
1713
    run_mutex_tests();
1714
    run_mbox_tests();
1715
    run_semaphore_tests();
1716
    run_counter_tests();
1717
    run_flag_tests();
1718
    run_alarm_tests();
1719
 
1720
#ifdef CYG_SCHEDULER_LOCK_TIMINGS
1721
    Cyg_Scheduler::get_lock_times(&lock_ave, &lock_max);
1722
    diag_printf("\nMax lock:");
1723
    show_ticks_in_us(lock_max);
1724
    diag_printf(", Ave lock:");
1725
    show_ticks_in_us(lock_ave);
1726
    diag_printf("\n");
1727
#endif
1728
 
1729
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
1730
    // Display latency figures in same format as all other numbers
1731
    disable_clock_latency_measurement();
1732
    clock_ave = (total_clock_latency*1000) / total_clock_interrupts;
1733
    show_ticks_in_us(clock_ave);
1734
    show_ticks_in_us(min_clock_latency*1000);
1735
    show_ticks_in_us(max_clock_latency*1000);
1736
    show_ticks_in_us(0);
1737
    diag_printf("            Clock/interrupt latency\n\n");
1738
    enable_clock_latency_measurement();
1739
#endif
1740
 
1741
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) && defined(HAL_CLOCK_LATENCY)
1742
    disable_clock_latency_measurement();
1743
    clock_ave = (total_clock_dsr_latency*1000) / total_clock_dsr_calls;
1744
    show_ticks_in_us(clock_ave);
1745
    show_ticks_in_us(min_clock_dsr_latency*1000);
1746
    show_ticks_in_us(max_clock_dsr_latency*1000);
1747
    show_ticks_in_us(0);
1748
    diag_printf("            Clock DSR latency\n\n");
1749
    enable_clock_latency_measurement();
1750
#endif
1751
 
1752
#ifndef CYGPKG_KERNEL_SMP_SUPPORT    
1753
    disable_clock_latency_measurement();
1754
    min_stack = STACK_SIZE;
1755
    max_stack = 0;
1756
    total_stack = 0;
1757
    for (i = 0;  i < (int)NTEST_THREADS;  i++) {
1758
        for (j = 0;  j < STACK_SIZE;  j++) {
1759
            if (stacks[i][j]) break;
1760
        }
1761
        actual_stack = STACK_SIZE-j;
1762
        if (actual_stack < min_stack) min_stack = actual_stack;
1763
        if (actual_stack > max_stack) max_stack = actual_stack;
1764
        total_stack += actual_stack;
1765
    }
1766
    for (j = 0;  j < STACKSIZE;  j++) {
1767
        if (((char *)stack[0])[j]) break;
1768
    }
1769
    diag_printf("%5ld  %5d   %5d  (main stack: %5d)  Thread stack used (%d total)\n",
1770
                (unsigned long) total_stack/NTEST_THREADS, min_stack, max_stack,
1771
                STACKSIZE - j, STACK_SIZE);
1772
 
1773
    cyg_test_dump_thread_stack_stats( "All done, main stack", thread[0] );
1774
    cyg_test_dump_interrupt_stack_stats( "All done" );
1775
    cyg_test_dump_idlethread_stack_stats( "All done" );
1776
#endif
1777
 
1778
    enable_clock_latency_measurement();
1779
 
1780
    ticks = cyg_current_time();
1781
    diag_printf("\nTiming complete - %d ms total\n\n", (int)((ticks*ns_per_system_clock)/1000));
1782
}
1783
 
1784
void
1785
run_all_tests(CYG_ADDRESS id)
1786
{
1787
#if CYGNUM_TESTS_RUN_COUNT < 0
1788
    while (1)
1789
#else       
1790
    int i;
1791
    for (i = 0;  i < CYGNUM_TESTS_RUN_COUNT;  i++)
1792
#endif
1793
        _run_all_tests(id);
1794
    CYG_TEST_PASS_FINISH("Basic timing OK");
1795
}
1796
 
1797
void tm_basic_main( void )
1798
{
1799
    CYG_TEST_INIT();
1800
 
1801
    if (cyg_test_is_simulator) {
1802
        nsamples = NSAMPLES_SIM;
1803
        ntest_threads = NTEST_THREADS_SIM;
1804
        nthread_switches = NTHREAD_SWITCHES_SIM;
1805
        nmutexes = NMUTEXES_SIM;
1806
        nmboxes = NMBOXES_SIM;
1807
        nsemaphores = NSEMAPHORES_SIM;
1808
        nscheds = NSCHEDS_SIM;
1809
        nflags = NFLAGS_SIM;
1810
        ncounters = NCOUNTERS_SIM;
1811
        nalarms = NALARMS_SIM;
1812
    } else {
1813
        nsamples = NSAMPLES;
1814
        ntest_threads = NTEST_THREADS;
1815
        nthread_switches = NTHREAD_SWITCHES;
1816
        nmutexes = NMUTEXES;
1817
        nmboxes = NMBOXES;
1818
        nsemaphores = NSEMAPHORES;
1819
        nscheds = NSCHEDS;
1820
        nflags = NFLAGS;
1821
        ncounters = NCOUNTERS;
1822
        nalarms = NALARMS;
1823
    }
1824
 
1825
    // Sanity
1826
#ifdef WORKHORSE_TEST
1827
    ntest_threads = min(512, ntest_threads);
1828
    nmutexes = min(1024, nmutexes);
1829
    nsemaphores = min(1024, nsemaphores);
1830
    nmboxes = min(1024, nmboxes);
1831
    ncounters = min(1024, ncounters);
1832
    nalarms = min(1024, nalarms);
1833
#else
1834
    ntest_threads = min(64, ntest_threads);
1835
    nmutexes = min(32, nmutexes);
1836
    nsemaphores = min(32, nsemaphores);
1837
    nmboxes = min(32, nmboxes);
1838
    ncounters = min(32, ncounters);
1839
    nflags = min(32, nflags);
1840
    nalarms = min(32, nalarms);
1841
#endif
1842
 
1843
    new_thread(run_all_tests, 0);
1844
 
1845
    Cyg_Scheduler::scheduler.start();
1846
 
1847
}
1848
 
1849
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
1850
externC void
1851
cyg_hal_invoke_constructors();
1852
#endif
1853
 
1854
externC void
1855
cyg_start( void )
1856
{
1857
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
1858
    cyg_hal_invoke_constructors();
1859
#endif
1860
    tm_basic_main();
1861
}
1862
 
1863
#else // CYGFUN_KERNEL_API_C
1864
 
1865
externC void
1866
cyg_start( void )
1867
{
1868
    CYG_TEST_INIT();
1869
    CYG_TEST_INFO("Timing tests require:\n"
1870
                "CYGFUN_KERNEL_API_C && \n"
1871
                "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n"
1872
                "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
1873
                "!CYGDBG_INFRA_DIAG_USE_DEVICE &&\n"
1874
                "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
1875
    CYG_TEST_NA("Timing tests requirements");
1876
}
1877
#endif // CYGFUN_KERNEL_API_C, etc.
1878
 
1879
// EOF tm_basic.cxx

powered by: WebSVN 2.1.0

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