linux/tools/testing/selftests/sync/sync_stress_parallelism.c
<<
>>
Prefs
   1/*
   2 *  sync stress test: parallelism
   3 *  Copyright 2015-2016 Collabora Ltd.
   4 *
   5 *  Based on the implementation from the Android Open Source Project,
   6 *
   7 *  Copyright 2012 Google, Inc
   8 *
   9 *  Permission is hereby granted, free of charge, to any person obtaining a
  10 *  copy of this software and associated documentation files (the "Software"),
  11 *  to deal in the Software without restriction, including without limitation
  12 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13 *  and/or sell copies of the Software, and to permit persons to whom the
  14 *  Software is furnished to do so, subject to the following conditions:
  15 *
  16 *  The above copyright notice and this permission notice shall be included in
  17 *  all copies or substantial portions of the Software.
  18 *
  19 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23 *  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24 *  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25 *  OTHER DEALINGS IN THE SOFTWARE.
  26 */
  27
  28#include <pthread.h>
  29
  30#include "sync.h"
  31#include "sw_sync.h"
  32#include "synctest.h"
  33
  34static struct {
  35        int iterations;
  36        int timeline;
  37        int counter;
  38} test_data_two_threads;
  39
  40static int test_stress_two_threads_shared_timeline_thread(void *d)
  41{
  42        int thread_id = (long)d;
  43        int timeline = test_data_two_threads.timeline;
  44        int iterations = test_data_two_threads.iterations;
  45        int fence, valid, ret, i;
  46
  47        for (i = 0; i < iterations; i++) {
  48                fence = sw_sync_fence_create(timeline, "fence",
  49                                             i * 2 + thread_id);
  50                valid = sw_sync_fence_is_valid(fence);
  51                ASSERT(valid, "Failure allocating fence\n");
  52
  53                /* Wait on the prior thread to complete */
  54                ret = sync_wait(fence, -1);
  55                ASSERT(ret > 0, "Problem occurred on prior thread\n");
  56
  57                /*
  58                 * Confirm the previous thread's writes are visible
  59                 * and then increment
  60                 */
  61                ASSERT(test_data_two_threads.counter == i * 2 + thread_id,
  62                       "Counter got damaged!\n");
  63                test_data_two_threads.counter++;
  64
  65                /* Kick off the other thread */
  66                ret = sw_sync_timeline_inc(timeline, 1);
  67                ASSERT(ret == 0, "Advancing timeline failed\n");
  68
  69                sw_sync_fence_destroy(fence);
  70        }
  71
  72        return 0;
  73}
  74
  75int test_stress_two_threads_shared_timeline(void)
  76{
  77        pthread_t a, b;
  78        int valid;
  79        int timeline = sw_sync_timeline_create();
  80
  81        valid = sw_sync_timeline_is_valid(timeline);
  82        ASSERT(valid, "Failure allocating timeline\n");
  83
  84        test_data_two_threads.iterations = 1 << 16;
  85        test_data_two_threads.counter = 0;
  86        test_data_two_threads.timeline = timeline;
  87
  88        /*
  89         * Use a single timeline to synchronize two threads
  90         * hammmering on the same counter.
  91         */
  92
  93        pthread_create(&a, NULL, (void *(*)(void *))
  94                       test_stress_two_threads_shared_timeline_thread,
  95                       (void *)0);
  96        pthread_create(&b, NULL, (void *(*)(void *))
  97                       test_stress_two_threads_shared_timeline_thread,
  98                       (void *)1);
  99
 100        pthread_join(a, NULL);
 101        pthread_join(b, NULL);
 102
 103        /* make sure the threads did not trample on one another */
 104        ASSERT(test_data_two_threads.counter ==
 105               test_data_two_threads.iterations * 2,
 106               "Counter has unexpected value\n");
 107
 108        sw_sync_timeline_destroy(timeline);
 109
 110        return 0;
 111}
 112