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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [kernel/] [v2_0/] [tests/] [tm_basic.cxx] - Blame information for rev 174

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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