[PATCH 6/7] selftest: sync: stress consumer/producer test
This test is based on the libsync test suite from Android. This commit includes a stress test that replicates a consumer/producer pattern. Signed-off-by: Emilio López--- tools/testing/selftests/sync/Makefile | 1 + .../testing/selftests/sync/sync_stress_consumer.c | 185 + tools/testing/selftests/sync/sync_test.c | 1 + tools/testing/selftests/sync/synctest.h| 3 + 4 files changed, 190 insertions(+) create mode 100644 tools/testing/selftests/sync/sync_stress_consumer.c diff --git a/tools/testing/selftests/sync/Makefile b/tools/testing/selftests/sync/Makefile index 1ed2864..910e3f9 100644 --- a/tools/testing/selftests/sync/Makefile +++ b/tools/testing/selftests/sync/Makefile @@ -19,6 +19,7 @@ TESTS += sync_fence.o TESTS += sync_merge.o TESTS += sync_wait.o TESTS += sync_stress_parallelism.o +TESTS += sync_stress_consumer.o sync_test: $(SRC) $(TESTS) diff --git a/tools/testing/selftests/sync/sync_stress_consumer.c b/tools/testing/selftests/sync/sync_stress_consumer.c new file mode 100644 index 000..d9eff8d --- /dev/null +++ b/tools/testing/selftests/sync/sync_stress_consumer.c @@ -0,0 +1,185 @@ +/* + * sync stress test: producer/consumer + * Copyright 2015-2016 Collabora Ltd. + * + * Based on the implementation from the Android Open Source Project, + * + * Copyright 2012 Google, Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "sync.h" +#include "sw_sync.h" +#include "synctest.h" + +/* IMPORTANT NOTE: if you see this test failing on your system, it may be + * due to a shortage of file descriptors. Please ensure your system has + * a sensible limit for this test to finish correctly. + */ + +/* Returns 1 on error, 0 on success */ +static int busy_wait_on_fence(int fence) +{ + int error, active; + + do { + error = sync_fence_count_with_status(fence, FENCE_STATUS_ERROR); + ASSERT(error == 0, "Error occurred on fence\n"); + active = sync_fence_count_with_status(fence, + FENCE_STATUS_ACTIVE); + } while (active); + + return 0; +} + +static struct { + int iterations; + int threads; + int counter; + int consumer_timeline; + int *producer_timelines; + pthread_mutex_t lock; +} test_data_mpsc; + +static int mpsc_producer_thread(void *d) +{ + int id = (long)d; + int fence, valid, i; + int *producer_timelines = test_data_mpsc.producer_timelines; + int consumer_timeline = test_data_mpsc.consumer_timeline; + int iterations = test_data_mpsc.iterations; + + for (i = 0; i < iterations; i++) { + fence = sw_sync_fence_create(consumer_timeline, "fence", i); + valid = sw_sync_fence_is_valid(fence); + ASSERT(valid, "Failure creating fence\n"); + + /* +* Wait for the consumer to finish. Use alternate +* means of waiting on the fence +*/ + + if ((iterations + id) % 8 != 0) { + ASSERT(sync_wait(fence, -1) > 0, + "Failure waiting on fence\n"); + } else { + ASSERT(busy_wait_on_fence(fence) == 0, + "Failure waiting on fence\n"); + } + + /* +* Every producer increments the counter, the consumer +* checks and erases it +*/ + pthread_mutex_lock(_data_mpsc.lock); + test_data_mpsc.counter++; + pthread_mutex_unlock(_data_mpsc.lock); + + ASSERT(sw_sync_timeline_inc(producer_timelines[id], 1) == 0, + "Error advancing producer timeline\n"); + + sw_sync_fence_destroy(fence); +
[PATCH 6/7] selftest: sync: stress consumer/producer test
This test is based on the libsync test suite from Android. This commit includes a stress test that replicates a consumer/producer pattern. Signed-off-by: Emilio López --- tools/testing/selftests/sync/Makefile | 1 + .../testing/selftests/sync/sync_stress_consumer.c | 185 + tools/testing/selftests/sync/sync_test.c | 1 + tools/testing/selftests/sync/synctest.h| 3 + 4 files changed, 190 insertions(+) create mode 100644 tools/testing/selftests/sync/sync_stress_consumer.c diff --git a/tools/testing/selftests/sync/Makefile b/tools/testing/selftests/sync/Makefile index 1ed2864..910e3f9 100644 --- a/tools/testing/selftests/sync/Makefile +++ b/tools/testing/selftests/sync/Makefile @@ -19,6 +19,7 @@ TESTS += sync_fence.o TESTS += sync_merge.o TESTS += sync_wait.o TESTS += sync_stress_parallelism.o +TESTS += sync_stress_consumer.o sync_test: $(SRC) $(TESTS) diff --git a/tools/testing/selftests/sync/sync_stress_consumer.c b/tools/testing/selftests/sync/sync_stress_consumer.c new file mode 100644 index 000..d9eff8d --- /dev/null +++ b/tools/testing/selftests/sync/sync_stress_consumer.c @@ -0,0 +1,185 @@ +/* + * sync stress test: producer/consumer + * Copyright 2015-2016 Collabora Ltd. + * + * Based on the implementation from the Android Open Source Project, + * + * Copyright 2012 Google, Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "sync.h" +#include "sw_sync.h" +#include "synctest.h" + +/* IMPORTANT NOTE: if you see this test failing on your system, it may be + * due to a shortage of file descriptors. Please ensure your system has + * a sensible limit for this test to finish correctly. + */ + +/* Returns 1 on error, 0 on success */ +static int busy_wait_on_fence(int fence) +{ + int error, active; + + do { + error = sync_fence_count_with_status(fence, FENCE_STATUS_ERROR); + ASSERT(error == 0, "Error occurred on fence\n"); + active = sync_fence_count_with_status(fence, + FENCE_STATUS_ACTIVE); + } while (active); + + return 0; +} + +static struct { + int iterations; + int threads; + int counter; + int consumer_timeline; + int *producer_timelines; + pthread_mutex_t lock; +} test_data_mpsc; + +static int mpsc_producer_thread(void *d) +{ + int id = (long)d; + int fence, valid, i; + int *producer_timelines = test_data_mpsc.producer_timelines; + int consumer_timeline = test_data_mpsc.consumer_timeline; + int iterations = test_data_mpsc.iterations; + + for (i = 0; i < iterations; i++) { + fence = sw_sync_fence_create(consumer_timeline, "fence", i); + valid = sw_sync_fence_is_valid(fence); + ASSERT(valid, "Failure creating fence\n"); + + /* +* Wait for the consumer to finish. Use alternate +* means of waiting on the fence +*/ + + if ((iterations + id) % 8 != 0) { + ASSERT(sync_wait(fence, -1) > 0, + "Failure waiting on fence\n"); + } else { + ASSERT(busy_wait_on_fence(fence) == 0, + "Failure waiting on fence\n"); + } + + /* +* Every producer increments the counter, the consumer +* checks and erases it +*/ + pthread_mutex_lock(_data_mpsc.lock); + test_data_mpsc.counter++; + pthread_mutex_unlock(_data_mpsc.lock); + + ASSERT(sw_sync_timeline_inc(producer_timelines[id], 1) == 0, + "Error advancing producer timeline\n"); + + sw_sync_fence_destroy(fence); + } + + return 0; +} +