source: rtems/testsuites/smptests/smplock01/init.c @ 80cf60e

5
Last change on this file since 80cf60e was 80cf60e, checked in by Sebastian Huber <sebastian.huber@…>, on 04/15/20 at 07:48:32

Canonicalize config.h include

Use the following variant which was already used by most source files:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

  • Property mode set to 100644
File size: 15.9 KB
Line 
1/*
2 * Copyright (c) 2013, 2016 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include <rtems/score/smplock.h>
20#include <rtems/score/smplockmcs.h>
21#include <rtems/score/smplockseq.h>
22#include <rtems/test.h>
23#include <rtems.h>
24
25#include "tmacros.h"
26
27const char rtems_test_name[] = "SMPLOCK 1";
28
29#define TASK_PRIORITY 1
30
31#define CPU_COUNT 32
32
33#define TEST_COUNT 13
34
35typedef struct {
36  rtems_test_parallel_context base;
37  unsigned long counter[TEST_COUNT];
38  unsigned long local_counter[CPU_COUNT][TEST_COUNT][CPU_COUNT];
39  SMP_lock_Control lock RTEMS_ALIGNED(CPU_CACHE_LINE_BYTES);
40  Atomic_Uint flag RTEMS_ALIGNED(CPU_CACHE_LINE_BYTES);
41  SMP_MCS_lock_Control mcs_lock RTEMS_ALIGNED(CPU_CACHE_LINE_BYTES);
42#if defined(RTEMS_PROFILING)
43  SMP_lock_Stats mcs_stats;
44#endif
45  SMP_sequence_lock_Control seq_lock RTEMS_ALIGNED(CPU_CACHE_LINE_BYTES);
46  int a RTEMS_ALIGNED(CPU_CACHE_LINE_BYTES);
47  int b RTEMS_ALIGNED(CPU_CACHE_LINE_BYTES);
48} test_context;
49
50static test_context test_instance = {
51  .lock = SMP_LOCK_INITIALIZER("global ticket"),
52#if defined(RTEMS_PROFILING)
53  .mcs_stats = SMP_LOCK_STATS_INITIALIZER("global MCS"),
54#endif
55  .flag = ATOMIC_INITIALIZER_UINT(0),
56  .mcs_lock = SMP_MCS_LOCK_INITIALIZER,
57  .seq_lock = SMP_SEQUENCE_LOCK_INITIALIZER
58};
59
60static rtems_interval test_duration(void)
61{
62  return rtems_clock_get_ticks_per_second();
63}
64
65static rtems_interval test_init(
66  rtems_test_parallel_context *base,
67  void *arg,
68  size_t active_workers
69)
70{
71  return test_duration();
72}
73
74static void test_fini(
75  test_context *ctx,
76  const char *name,
77  size_t test,
78  size_t active_workers
79)
80{
81  unsigned long sum = 0;
82  unsigned long n = active_workers;
83  unsigned long i;
84
85  printf("  <%s activeWorker=\"%lu\">\n", name, n);
86
87  for (i = 0; i < n; ++i) {
88    unsigned long local_counter =
89      ctx->local_counter[active_workers - 1][test][i];
90
91    sum += local_counter;
92
93    printf(
94      "    <LocalCounter worker=\"%lu\">%lu</LocalCounter>\n",
95      i,
96      local_counter
97    );
98  }
99
100  printf(
101    "    <GlobalCounter>%lu</GlobalCounter>\n"
102    "    <SumOfLocalCounter>%lu</SumOfLocalCounter>\n"
103    "  </%s>\n",
104    ctx->counter[test],
105    sum,
106    name
107  );
108}
109
110static void test_0_body(
111  rtems_test_parallel_context *base,
112  void *arg,
113  size_t active_workers,
114  size_t worker_index
115)
116{
117  test_context *ctx = (test_context *) base;
118  size_t test = 0;
119  unsigned long counter = 0;
120  SMP_lock_Context lock_context;
121
122  while (!rtems_test_parallel_stop_job(&ctx->base)) {
123    _SMP_lock_Acquire(&ctx->lock, &lock_context);
124    _SMP_lock_Release(&ctx->lock, &lock_context);
125    ++counter;
126  }
127
128  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
129}
130
131static void test_0_fini(
132  rtems_test_parallel_context *base,
133  void *arg,
134  size_t active_workers
135)
136{
137  test_context *ctx = (test_context *) base;
138
139  test_fini(
140    ctx,
141    "GlobalTicketLockWithLocalCounter",
142    0,
143    active_workers
144  );
145}
146
147static void test_1_body(
148  rtems_test_parallel_context *base,
149  void *arg,
150  size_t active_workers,
151  size_t worker_index
152)
153{
154  test_context *ctx = (test_context *) base;
155  size_t test = 1;
156  unsigned long counter = 0;
157  SMP_MCS_lock_Context lock_context;
158
159  while (!rtems_test_parallel_stop_job(&ctx->base)) {
160    _SMP_MCS_lock_Acquire(&ctx->mcs_lock, &lock_context, &ctx->mcs_stats);
161    _SMP_MCS_lock_Release(&ctx->mcs_lock, &lock_context);
162    ++counter;
163  }
164
165  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
166}
167
168static void test_1_fini(
169  rtems_test_parallel_context *base,
170  void *arg,
171  size_t active_workers
172)
173{
174  test_context *ctx = (test_context *) base;
175
176  test_fini(
177    ctx,
178    "GlobalMCSLockWithLocalCounter",
179    1,
180    active_workers
181  );
182}
183
184static void test_2_body(
185  rtems_test_parallel_context *base,
186  void *arg,
187  size_t active_workers,
188  size_t worker_index
189)
190{
191  test_context *ctx = (test_context *) base;
192  size_t test = 2;
193  unsigned long counter = 0;
194  SMP_lock_Context lock_context;
195
196  while (!rtems_test_parallel_stop_job(&ctx->base)) {
197    _SMP_lock_Acquire(&ctx->lock, &lock_context);
198    ++ctx->counter[test];
199    _SMP_lock_Release(&ctx->lock, &lock_context);
200    ++counter;
201  }
202
203  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
204}
205
206static void test_2_fini(
207  rtems_test_parallel_context *base,
208  void *arg,
209  size_t active_workers
210)
211{
212  test_context *ctx = (test_context *) base;
213
214  test_fini(
215    ctx,
216    "GlobalTicketLockWithGlobalCounter",
217    2,
218    active_workers
219  );
220}
221
222static void test_3_body(
223  rtems_test_parallel_context *base,
224  void *arg,
225  size_t active_workers,
226  size_t worker_index
227)
228{
229  test_context *ctx = (test_context *) base;
230  size_t test = 3;
231  unsigned long counter = 0;
232  SMP_MCS_lock_Context lock_context;
233
234  while (!rtems_test_parallel_stop_job(&ctx->base)) {
235    _SMP_MCS_lock_Acquire(&ctx->mcs_lock, &lock_context, &ctx->mcs_stats);
236    ++ctx->counter[test];
237    _SMP_MCS_lock_Release(&ctx->mcs_lock, &lock_context);
238    ++counter;
239  }
240
241  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
242}
243
244static void test_3_fini(
245  rtems_test_parallel_context *base,
246  void *arg,
247  size_t active_workers
248)
249{
250  test_context *ctx = (test_context *) base;
251
252  test_fini(
253    ctx,
254    "GlobalMCSLockWithGlobalCounter",
255    3,
256    active_workers
257  );
258}
259
260static void test_4_body(
261  rtems_test_parallel_context *base,
262  void *arg,
263  size_t active_workers,
264  size_t worker_index
265)
266{
267  test_context *ctx = (test_context *) base;
268  size_t test = 4;
269  unsigned long counter = 0;
270  SMP_lock_Control lock;
271  SMP_lock_Context lock_context;
272
273  _SMP_lock_Initialize(&lock, "local");
274
275  while (!rtems_test_parallel_stop_job(&ctx->base)) {
276    _SMP_lock_Acquire(&lock, &lock_context);
277    _SMP_lock_Release(&lock, &lock_context);
278    ++counter;
279  }
280
281  _SMP_lock_Destroy(&lock);
282
283  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
284}
285
286static void test_4_fini(
287  rtems_test_parallel_context *base,
288  void *arg,
289  size_t active_workers
290)
291{
292  test_context *ctx = (test_context *) base;
293
294  test_fini(
295    ctx,
296    "LocalTicketLockWithLocalCounter",
297    4,
298    active_workers
299  );
300}
301
302static void test_5_body(
303  rtems_test_parallel_context *base,
304  void *arg,
305  size_t active_workers,
306  size_t worker_index
307)
308{
309  test_context *ctx = (test_context *) base;
310  size_t test = 5;
311  unsigned long counter = 0;
312#if defined(RTEMS_PROFILING)
313  SMP_lock_Stats stats;
314#endif
315  SMP_MCS_lock_Control lock;
316  SMP_MCS_lock_Context lock_context;
317
318  _SMP_lock_Stats_initialize(&stats, "local");
319  _SMP_MCS_lock_Initialize(&lock);
320
321  while (!rtems_test_parallel_stop_job(&ctx->base)) {
322    _SMP_MCS_lock_Acquire(&lock, &lock_context, &stats);
323    _SMP_MCS_lock_Release(&lock, &lock_context);
324    ++counter;
325  }
326
327  _SMP_MCS_lock_Destroy(&lock);
328  _SMP_lock_Stats_destroy(&stats);
329
330  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
331}
332
333static void test_5_fini(
334  rtems_test_parallel_context *base,
335  void *arg,
336  size_t active_workers
337)
338{
339  test_context *ctx = (test_context *) base;
340
341  test_fini(
342    ctx,
343    "LocalMCSLockWithLocalCounter",
344    5,
345    active_workers
346  );
347}
348
349static void test_6_body(
350  rtems_test_parallel_context *base,
351  void *arg,
352  size_t active_workers,
353  size_t worker_index
354)
355{
356  test_context *ctx = (test_context *) base;
357  size_t test = 6;
358  unsigned long counter = 0;
359  SMP_lock_Control lock;
360  SMP_lock_Context lock_context;
361
362  _SMP_lock_Initialize(&lock, "local");
363
364  while (!rtems_test_parallel_stop_job(&ctx->base)) {
365    _SMP_lock_Acquire(&lock, &lock_context);
366
367    /* The counter value is not interesting, only the access to it */
368    ++ctx->counter[test];
369
370    _SMP_lock_Release(&lock, &lock_context);
371    ++counter;
372  }
373
374  _SMP_lock_Destroy(&lock);
375
376  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
377}
378
379static void test_6_fini(
380  rtems_test_parallel_context *base,
381  void *arg,
382  size_t active_workers
383)
384{
385  test_context *ctx = (test_context *) base;
386
387  test_fini(
388    ctx,
389    "LocalTicketLockWithGlobalCounter",
390    6,
391    active_workers
392  );
393}
394
395static void test_7_body(
396  rtems_test_parallel_context *base,
397  void *arg,
398  size_t active_workers,
399  size_t worker_index
400)
401{
402  test_context *ctx = (test_context *) base;
403  size_t test = 7;
404  unsigned long counter = 0;
405#if defined(RTEMS_PROFILING)
406  SMP_lock_Stats stats;
407#endif
408  SMP_MCS_lock_Control lock;
409  SMP_MCS_lock_Context lock_context;
410
411  _SMP_lock_Stats_initialize(&stats, "local");
412  _SMP_MCS_lock_Initialize(&lock);
413
414  while (!rtems_test_parallel_stop_job(&ctx->base)) {
415    _SMP_MCS_lock_Acquire(&lock, &lock_context, &stats);
416
417    /* The counter value is not interesting, only the access to it */
418    ++ctx->counter[test];
419
420    _SMP_MCS_lock_Release(&lock, &lock_context);
421    ++counter;
422  }
423
424  _SMP_MCS_lock_Destroy(&lock);
425  _SMP_lock_Stats_destroy(&stats);
426
427  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
428}
429
430static void test_7_fini(
431  rtems_test_parallel_context *base,
432  void *arg,
433  size_t active_workers
434)
435{
436  test_context *ctx = (test_context *) base;
437
438  test_fini(
439    ctx,
440    "LocalMCSLockWithGlobalCounter",
441    7,
442    active_workers
443  );
444}
445
446static void busy_section(void)
447{
448  int i;
449
450  for (i = 0; i < 101; ++i) {
451    RTEMS_COMPILER_MEMORY_BARRIER();
452  }
453}
454
455static void test_8_body(
456  rtems_test_parallel_context *base,
457  void *arg,
458  size_t active_workers,
459  size_t worker_index
460)
461{
462  test_context *ctx = (test_context *) base;
463  size_t test = 8;
464  unsigned long counter = 0;
465  SMP_lock_Context lock_context;
466
467  while (!rtems_test_parallel_stop_job(&ctx->base)) {
468    _SMP_lock_Acquire(&ctx->lock, &lock_context);
469    busy_section();
470    _SMP_lock_Release(&ctx->lock, &lock_context);
471    ++counter;
472  }
473
474  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
475}
476
477static void test_8_fini(
478  rtems_test_parallel_context *base,
479  void *arg,
480  size_t active_workers
481)
482{
483  test_context *ctx = (test_context *) base;
484
485  test_fini(
486    ctx,
487    "GlobalTicketLockWithBusySection",
488    8,
489    active_workers
490  );
491}
492
493static void test_9_body(
494  rtems_test_parallel_context *base,
495  void *arg,
496  size_t active_workers,
497  size_t worker_index
498)
499{
500  test_context *ctx = (test_context *) base;
501  size_t test = 9;
502  unsigned long counter = 0;
503  SMP_MCS_lock_Context lock_context;
504
505  while (!rtems_test_parallel_stop_job(&ctx->base)) {
506    _SMP_MCS_lock_Acquire(&ctx->mcs_lock, &lock_context, &ctx->mcs_stats);
507    busy_section();
508    _SMP_MCS_lock_Release(&ctx->mcs_lock, &lock_context);
509    ++counter;
510  }
511
512  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
513}
514
515static void test_9_fini(
516  rtems_test_parallel_context *base,
517  void *arg,
518  size_t active_workers
519)
520{
521  test_context *ctx = (test_context *) base;
522
523  test_fini(
524    ctx,
525    "GlobalMCSLockWithBusySection",
526    9,
527    active_workers
528  );
529}
530
531static void test_10_body(
532  rtems_test_parallel_context *base,
533  void *arg,
534  size_t active_workers,
535  size_t worker_index
536)
537{
538  test_context *ctx = (test_context *) base;
539  size_t test = 10;
540  unsigned long counter = 0;
541  unsigned long seq;
542
543  if (rtems_test_parallel_is_master_worker(worker_index)) {
544    while (!rtems_test_parallel_stop_job(&ctx->base)) {
545      seq = _SMP_sequence_lock_Write_begin(&ctx->seq_lock);
546
547      ctx->a = counter;
548      ctx->b = counter;
549
550      _SMP_sequence_lock_Write_end(&ctx->seq_lock, seq);
551
552      ++counter;
553    }
554  } else {
555    while (!rtems_test_parallel_stop_job(&ctx->base)) {
556      unsigned long a;
557      unsigned long b;
558
559      do {
560        seq = _SMP_sequence_lock_Read_begin(&ctx->seq_lock);
561
562        a = ctx->a;
563        b = ctx->b;
564
565      } while (_SMP_sequence_lock_Read_retry(&ctx->seq_lock, seq));
566
567      ++counter;
568      rtems_test_assert(a == b);
569    }
570  }
571
572  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
573}
574
575static void test_10_fini(
576  rtems_test_parallel_context *base,
577  void *arg,
578  size_t active_workers
579)
580{
581  test_context *ctx = (test_context *) base;
582
583  test_fini(
584    ctx,
585    "SequenceLock",
586    10,
587    active_workers
588  );
589}
590
591static void test_11_body(
592  rtems_test_parallel_context *base,
593  void *arg,
594  size_t active_workers,
595  size_t worker_index
596)
597{
598  test_context *ctx = (test_context *) base;
599  size_t test = 11;
600  unsigned long counter = 0;
601
602  while (!rtems_test_parallel_stop_job(&ctx->base)) {
603    while (_Atomic_Exchange_uint(&ctx->flag, 1, ATOMIC_ORDER_ACQUIRE) != 0) {
604      /* Wait */
605    }
606
607    _Atomic_Store_uint(&ctx->flag, 0, ATOMIC_ORDER_RELEASE);
608    ++counter;
609  }
610
611  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
612}
613
614static void test_11_fini(
615  rtems_test_parallel_context *base,
616  void *arg,
617  size_t active_workers
618)
619{
620  test_context *ctx = (test_context *) base;
621
622  test_fini(
623    ctx,
624    "GlobalTASLockWithLocalCounter",
625    11,
626    active_workers
627  );
628}
629
630static void test_12_body(
631  rtems_test_parallel_context *base,
632  void *arg,
633  size_t active_workers,
634  size_t worker_index
635)
636{
637  test_context *ctx = (test_context *) base;
638  size_t test = 12;
639  unsigned long counter = 0;
640
641  while (!rtems_test_parallel_stop_job(&ctx->base)) {
642    while (_Atomic_Exchange_uint(&ctx->flag, 1, ATOMIC_ORDER_ACQUIRE) != 0) {
643      while (_Atomic_Load_uint(&ctx->flag, ATOMIC_ORDER_RELAXED) != 0) {
644        /* Wait */
645      }
646    }
647
648    _Atomic_Store_uint(&ctx->flag, 0, ATOMIC_ORDER_RELEASE);
649    ++counter;
650  }
651
652  ctx->local_counter[active_workers - 1][test][worker_index] = counter;
653}
654
655static void test_12_fini(
656  rtems_test_parallel_context *base,
657  void *arg,
658  size_t active_workers
659)
660{
661  test_context *ctx = (test_context *) base;
662
663  test_fini(
664    ctx,
665    "GlobalTTASLockWithLocalCounter",
666    12,
667    active_workers
668  );
669}
670
671static const rtems_test_parallel_job test_jobs[TEST_COUNT] = {
672  {
673    .init = test_init,
674    .body = test_0_body,
675    .fini = test_0_fini,
676    .cascade = true
677  }, {
678    .init = test_init,
679    .body = test_1_body,
680    .fini = test_1_fini,
681    .cascade = true
682  }, {
683    .init = test_init,
684    .body = test_2_body,
685    .fini = test_2_fini,
686    .cascade = false
687  }, {
688    .init = test_init,
689    .body = test_3_body,
690    .fini = test_3_fini,
691    .cascade = false
692  }, {
693    .init = test_init,
694    .body = test_4_body,
695    .fini = test_4_fini,
696    .cascade = true
697  }, {
698    .init = test_init,
699    .body = test_5_body,
700    .fini = test_5_fini,
701    .cascade = true
702  }, {
703    .init = test_init,
704    .body = test_6_body,
705    .fini = test_6_fini,
706    .cascade = false
707  }, {
708    .init = test_init,
709    .body = test_7_body,
710    .fini = test_7_fini,
711    .cascade = false
712  }, {
713    .init = test_init,
714    .body = test_8_body,
715    .fini = test_8_fini,
716    .cascade = false
717  }, {
718    .init = test_init,
719    .body = test_9_body,
720    .fini = test_9_fini,
721    .cascade = false
722  }, {
723    .init = test_init,
724    .body = test_10_body,
725    .fini = test_10_fini,
726    .cascade = false
727  }, {
728    .init = test_init,
729    .body = test_11_body,
730    .fini = test_11_fini,
731    .cascade = true
732  }, {
733    .init = test_init,
734    .body = test_12_body,
735    .fini = test_12_fini,
736    .cascade = true
737  }
738};
739
740static void test(void)
741{
742  test_context *ctx = &test_instance;
743  const char *test = "SMPLock01";
744
745  printf("<%s>\n", test);
746  rtems_test_parallel(&ctx->base, NULL, &test_jobs[0], TEST_COUNT);
747  printf("</%s>\n", test);
748}
749
750static void Init(rtems_task_argument arg)
751{
752  TEST_BEGIN();
753
754  test();
755
756  TEST_END();
757  rtems_test_exit(0);
758}
759
760#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
761#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
762
763#define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
764
765#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
766
767#define CONFIGURE_MAXIMUM_SEMAPHORES 1
768
769#define CONFIGURE_MAXIMUM_TIMERS 1
770
771#define CONFIGURE_INIT_TASK_PRIORITY TASK_PRIORITY
772#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
773#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
774
775#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
776
777#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
778
779#define CONFIGURE_INIT
780
781#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.