cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sync_stress_parallelism.c (3398B)


      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}