112 lines · c
1/*2 * sync stress test: parallelism3 * Copyright 2015-2016 Collabora Ltd.4 *5 * Based on the implementation from the Android Open Source Project,6 *7 * Copyright 2012 Google, Inc8 *9 * Permission is hereby granted, free of charge, to any person obtaining a10 * copy of this software and associated documentation files (the "Software"),11 * to deal in the Software without restriction, including without limitation12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,13 * and/or sell copies of the Software, and to permit persons to whom the14 * Software is furnished to do so, subject to the following conditions:15 *16 * The above copyright notice and this permission notice shall be included in17 * all copies or substantial portions of the Software.18 *19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR23 * 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 OR25 * 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 visible59 * and then increment60 */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 threads90 * 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