aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-15 17:17:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-15 17:17:32 -0500
commit09dee2a608a4a7d42f021f83084ade7de2415d7e (patch)
tree5e5cce54d2f20763e03eaeb07aaac1bffd968f9d /tools
parentd25b6af91ec600faaff3a7e863f19d3e16593e52 (diff)
parent22f6592b23ef8a0c09283bcb13087340721e1154 (diff)
Merge tag 'linux-kselftest-4.10-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kselftest updates from Shuah Khan: "This update consists of: - new tests to exercise the Sync Kernel Infrastructure. These tests are part of a battery of Android libsync tests and are re-written to test the new sync user-space interfaces from Emilio López, and Gustavo Padovan. - test to run hw-independent mock tests for i915.ko from Chris Wilson - a new gpio test case from Bamvor Jian Zhang - missing gitignore additions" * tag 'linux-kselftest-4.10-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: selftest/gpio: add gpio test case selftest: sync: improve assert() failure message kselftests: Exercise hw-independent mock tests for i915.ko selftests: add missing gitignore files/dirs selftests: add missing set-tz to timers .gitignore selftest: sync: stress test for merges selftest: sync: stress consumer/producer test selftest: sync: stress test for parallelism selftest: sync: wait tests for sw_sync framework selftest: sync: merge tests for sw_sync framework selftest: sync: fence tests for sw_sync framework selftest: sync: basic tests for sw_sync framework
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/.gitignore1
-rw-r--r--tools/testing/selftests/Makefile2
-rwxr-xr-xtools/testing/selftests/drivers/gpu/i915.sh14
-rw-r--r--tools/testing/selftests/gpio/Makefile23
-rw-r--r--tools/testing/selftests/gpio/gpio-mockup-chardev.c324
-rwxr-xr-xtools/testing/selftests/gpio/gpio-mockup-sysfs.sh134
-rwxr-xr-xtools/testing/selftests/gpio/gpio-mockup.sh201
-rw-r--r--tools/testing/selftests/nsfs/.gitignore2
-rw-r--r--tools/testing/selftests/sigaltstack/.gitignore1
-rw-r--r--tools/testing/selftests/sync/.gitignore1
-rw-r--r--tools/testing/selftests/sync/Makefile24
-rw-r--r--tools/testing/selftests/sync/sw_sync.h46
-rw-r--r--tools/testing/selftests/sync/sync.c221
-rw-r--r--tools/testing/selftests/sync/sync.h40
-rw-r--r--tools/testing/selftests/sync/sync_alloc.c74
-rw-r--r--tools/testing/selftests/sync/sync_fence.c132
-rw-r--r--tools/testing/selftests/sync/sync_merge.c60
-rw-r--r--tools/testing/selftests/sync/sync_stress_consumer.c185
-rw-r--r--tools/testing/selftests/sync/sync_stress_merge.c115
-rw-r--r--tools/testing/selftests/sync/sync_stress_parallelism.c111
-rw-r--r--tools/testing/selftests/sync/sync_test.c79
-rw-r--r--tools/testing/selftests/sync/sync_wait.c91
-rw-r--r--tools/testing/selftests/sync/synctest.h66
-rw-r--r--tools/testing/selftests/timers/.gitignore1
24 files changed, 1948 insertions, 0 deletions
diff --git a/tools/testing/selftests/.gitignore b/tools/testing/selftests/.gitignore
new file mode 100644
index 000000000000..f0600d20ce7d
--- /dev/null
+++ b/tools/testing/selftests/.gitignore
@@ -0,0 +1 @@
kselftest
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index a3144a3de3a8..71b05891a6a1 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += exec
7TARGETS += firmware 7TARGETS += firmware
8TARGETS += ftrace 8TARGETS += ftrace
9TARGETS += futex 9TARGETS += futex
10TARGETS += gpio
10TARGETS += ipc 11TARGETS += ipc
11TARGETS += kcmp 12TARGETS += kcmp
12TARGETS += lib 13TARGETS += lib
@@ -24,6 +25,7 @@ TARGETS += seccomp
24TARGETS += sigaltstack 25TARGETS += sigaltstack
25TARGETS += size 26TARGETS += size
26TARGETS += static_keys 27TARGETS += static_keys
28TARGETS += sync
27TARGETS += sysctl 29TARGETS += sysctl
28ifneq (1, $(quicktest)) 30ifneq (1, $(quicktest))
29TARGETS += timers 31TARGETS += timers
diff --git a/tools/testing/selftests/drivers/gpu/i915.sh b/tools/testing/selftests/drivers/gpu/i915.sh
new file mode 100755
index 000000000000..d407f0fa1e3a
--- /dev/null
+++ b/tools/testing/selftests/drivers/gpu/i915.sh
@@ -0,0 +1,14 @@
1#!/bin/sh
2# Runs hardware independent tests for i915 (drivers/gpu/drm/i915)
3
4if ! /sbin/modprobe -q -r i915; then
5 echo "drivers/gpu/i915: [SKIP]"
6 exit 77
7fi
8
9if /sbin/modprobe -q i915 mock_selftests=-1; then
10 echo "drivers/gpu/i915: ok"
11else
12 echo "drivers/gpu/i915: [FAIL]"
13 exit 1
14fi
diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftests/gpio/Makefile
new file mode 100644
index 000000000000..205e4d10e085
--- /dev/null
+++ b/tools/testing/selftests/gpio/Makefile
@@ -0,0 +1,23 @@
1
2TEST_PROGS := gpio-mockup.sh
3TEST_FILES := gpio-mockup-sysfs.sh $(BINARIES)
4BINARIES := gpio-mockup-chardev
5
6include ../lib.mk
7
8all: $(BINARIES)
9
10clean:
11 $(RM) $(BINARIES)
12
13CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/
14LDLIBS += -lmount -I/usr/include/libmount
15
16$(BINARIES): ../../../gpio/gpio-utils.o ../../../../usr/include/linux/gpio.h
17
18../../../gpio/gpio-utils.o:
19 make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C ../../../gpio
20
21../../../../usr/include/linux/gpio.h:
22 make -C ../../../.. headers_install INSTALL_HDR_PATH=$(shell pwd)/../../../../usr/
23
diff --git a/tools/testing/selftests/gpio/gpio-mockup-chardev.c b/tools/testing/selftests/gpio/gpio-mockup-chardev.c
new file mode 100644
index 000000000000..667e916fa7cc
--- /dev/null
+++ b/tools/testing/selftests/gpio/gpio-mockup-chardev.c
@@ -0,0 +1,324 @@
1/*
2 * GPIO chardev test helper
3 *
4 * Copyright (C) 2016 Bamvor Jian Zhang
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 */
10
11#define _GNU_SOURCE
12#include <unistd.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <stdio.h>
16#include <errno.h>
17#include <string.h>
18#include <fcntl.h>
19#include <getopt.h>
20#include <sys/ioctl.h>
21#include <libmount.h>
22#include <err.h>
23#include <dirent.h>
24#include <linux/gpio.h>
25#include "../../../gpio/gpio-utils.h"
26
27#define CONSUMER "gpio-selftest"
28#define GC_NUM 10
29enum direction {
30 OUT,
31 IN
32};
33
34static int get_debugfs(char **path)
35{
36 struct libmnt_context *cxt;
37 struct libmnt_table *tb;
38 struct libmnt_iter *itr = NULL;
39 struct libmnt_fs *fs;
40 int found = 0;
41
42 cxt = mnt_new_context();
43 if (!cxt)
44 err(EXIT_FAILURE, "libmount context allocation failed");
45
46 itr = mnt_new_iter(MNT_ITER_FORWARD);
47 if (!itr)
48 err(EXIT_FAILURE, "failed to initialize libmount iterator");
49
50 if (mnt_context_get_mtab(cxt, &tb))
51 err(EXIT_FAILURE, "failed to read mtab");
52
53 while (mnt_table_next_fs(tb, itr, &fs) == 0) {
54 const char *type = mnt_fs_get_fstype(fs);
55
56 if (!strcmp(type, "debugfs")) {
57 found = 1;
58 break;
59 }
60 }
61 if (found)
62 asprintf(path, "%s/gpio", mnt_fs_get_target(fs));
63
64 mnt_free_iter(itr);
65 mnt_free_context(cxt);
66
67 if (!found)
68 return -1;
69
70 return 0;
71}
72
73static int gpio_debugfs_get(const char *consumer, int *dir, int *value)
74{
75 char *debugfs;
76 FILE *f;
77 char *line = NULL;
78 size_t len = 0;
79 char *cur;
80 int found = 0;
81
82 if (get_debugfs(&debugfs) != 0)
83 err(EXIT_FAILURE, "debugfs is not mounted");
84
85 f = fopen(debugfs, "r");
86 if (!f)
87 err(EXIT_FAILURE, "read from gpio debugfs failed");
88
89 /*
90 * gpio-2 ( |gpio-selftest ) in lo
91 */
92 while (getline(&line, &len, f) != -1) {
93 cur = strstr(line, consumer);
94 if (cur == NULL)
95 continue;
96
97 cur = strchr(line, ')');
98 if (!cur)
99 continue;
100
101 cur += 2;
102 if (!strncmp(cur, "out", 3)) {
103 *dir = OUT;
104 cur += 4;
105 } else if (!strncmp(cur, "in", 2)) {
106 *dir = IN;
107 cur += 4;
108 }
109
110 if (!strncmp(cur, "hi", 2))
111 *value = 1;
112 else if (!strncmp(cur, "lo", 2))
113 *value = 0;
114
115 found = 1;
116 break;
117 }
118 free(debugfs);
119 fclose(f);
120 free(line);
121
122 if (!found)
123 return -1;
124
125 return 0;
126}
127
128static struct gpiochip_info *list_gpiochip(const char *gpiochip_name, int *ret)
129{
130 struct gpiochip_info *cinfo;
131 struct gpiochip_info *current;
132 const struct dirent *ent;
133 DIR *dp;
134 char *chrdev_name;
135 int fd;
136 int i = 0;
137
138 cinfo = calloc(sizeof(struct gpiochip_info) * 4, GC_NUM + 1);
139 if (!cinfo)
140 err(EXIT_FAILURE, "gpiochip_info allocation failed");
141
142 current = cinfo;
143 dp = opendir("/dev");
144 if (!dp) {
145 *ret = -errno;
146 goto error_out;
147 } else {
148 *ret = 0;
149 }
150
151 while (ent = readdir(dp), ent) {
152 if (check_prefix(ent->d_name, "gpiochip")) {
153 *ret = asprintf(&chrdev_name, "/dev/%s", ent->d_name);
154 if (*ret < 0)
155 goto error_out;
156
157 fd = open(chrdev_name, 0);
158 if (fd == -1) {
159 *ret = -errno;
160 fprintf(stderr, "Failed to open %s\n",
161 chrdev_name);
162 goto error_close_dir;
163 }
164 *ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, current);
165 if (*ret == -1) {
166 perror("Failed to issue CHIPINFO IOCTL\n");
167 goto error_close_dir;
168 }
169 close(fd);
170 if (strcmp(current->label, gpiochip_name) == 0
171 || check_prefix(current->label, gpiochip_name)) {
172 *ret = 0;
173 current++;
174 i++;
175 }
176 }
177 }
178
179 if ((!*ret && i == 0) || *ret < 0) {
180 free(cinfo);
181 cinfo = NULL;
182 }
183 if (!*ret && i > 0) {
184 cinfo = realloc(cinfo, sizeof(struct gpiochip_info) * 4 * i);
185 *ret = i;
186 }
187
188error_close_dir:
189 closedir(dp);
190error_out:
191 if (*ret < 0)
192 err(EXIT_FAILURE, "list gpiochip failed: %s", strerror(*ret));
193
194 return cinfo;
195}
196
197int gpio_pin_test(struct gpiochip_info *cinfo, int line, int flag, int value)
198{
199 struct gpiohandle_data data;
200 unsigned int lines[] = {line};
201 int fd;
202 int debugfs_dir = IN;
203 int debugfs_value = 0;
204 int ret;
205
206 data.values[0] = value;
207 ret = gpiotools_request_linehandle(cinfo->name, lines, 1, flag, &data,
208 CONSUMER);
209 if (ret < 0)
210 goto fail_out;
211 else
212 fd = ret;
213
214 ret = gpio_debugfs_get(CONSUMER, &debugfs_dir, &debugfs_value);
215 if (ret) {
216 ret = -EINVAL;
217 goto fail_out;
218 }
219 if (flag & GPIOHANDLE_REQUEST_INPUT) {
220 if (debugfs_dir != IN) {
221 errno = -EINVAL;
222 ret = -errno;
223 }
224 } else if (flag & GPIOHANDLE_REQUEST_OUTPUT) {
225 if (flag & GPIOHANDLE_REQUEST_ACTIVE_LOW)
226 debugfs_value = !debugfs_value;
227
228 if (!(debugfs_dir == OUT && value == debugfs_value))
229 errno = -EINVAL;
230 ret = -errno;
231
232 }
233 gpiotools_release_linehandle(fd);
234
235fail_out:
236 if (ret)
237 err(EXIT_FAILURE, "gpio<%s> line<%d> test flag<0x%x> value<%d>",
238 cinfo->name, line, flag, value);
239
240 return ret;
241}
242
243void gpio_pin_tests(struct gpiochip_info *cinfo, unsigned int line)
244{
245 printf("line<%d>", line);
246 gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_OUTPUT, 0);
247 printf(".");
248 gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_OUTPUT, 1);
249 printf(".");
250 gpio_pin_test(cinfo, line,
251 GPIOHANDLE_REQUEST_OUTPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW,
252 0);
253 printf(".");
254 gpio_pin_test(cinfo, line,
255 GPIOHANDLE_REQUEST_OUTPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW,
256 1);
257 printf(".");
258 gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_INPUT, 0);
259 printf(".");
260}
261
262/*
263 * ./gpio-mockup-chardev gpio_chip_name_prefix is_valid_gpio_chip
264 * Return 0 if successful or exit with EXIT_FAILURE if test failed.
265 * gpio_chip_name_prefix: The prefix of gpiochip you want to test. E.g.
266 * gpio-mockup
267 * is_valid_gpio_chip: Whether the gpio_chip is valid. 1 means valid,
268 * 0 means invalid which could not be found by
269 * list_gpiochip.
270 */
271int main(int argc, char *argv[])
272{
273 char *prefix;
274 int valid;
275 struct gpiochip_info *cinfo;
276 struct gpiochip_info *current;
277 int i;
278 int ret;
279
280 if (argc < 3) {
281 printf("Usage: %s prefix is_valid", argv[0]);
282 exit(EXIT_FAILURE);
283 }
284
285 prefix = argv[1];
286 valid = strcmp(argv[2], "true") == 0 ? 1 : 0;
287
288 printf("Test gpiochip %s: ", prefix);
289 cinfo = list_gpiochip(prefix, &ret);
290 if (!cinfo) {
291 if (!valid && ret == 0) {
292 printf("Invalid test successful\n");
293 ret = 0;
294 goto out;
295 } else {
296 ret = -EINVAL;
297 goto out;
298 }
299 } else if (cinfo && !valid) {
300 ret = -EINVAL;
301 goto out;
302 }
303 current = cinfo;
304 for (i = 0; i < ret; i++) {
305 gpio_pin_tests(current, 0);
306 gpio_pin_tests(current, current->lines - 1);
307 gpio_pin_tests(current, random() % current->lines);
308 current++;
309 }
310 ret = 0;
311 printf("successful\n");
312
313out:
314 if (ret)
315 fprintf(stderr, "gpio<%s> test failed\n", prefix);
316
317 if (cinfo)
318 free(cinfo);
319
320 if (ret)
321 exit(EXIT_FAILURE);
322
323 return ret;
324}
diff --git a/tools/testing/selftests/gpio/gpio-mockup-sysfs.sh b/tools/testing/selftests/gpio/gpio-mockup-sysfs.sh
new file mode 100755
index 000000000000..085d7a39899c
--- /dev/null
+++ b/tools/testing/selftests/gpio/gpio-mockup-sysfs.sh
@@ -0,0 +1,134 @@
1
2is_consistent()
3{
4 val=
5
6 active_low_sysfs=`cat $GPIO_SYSFS/gpio$nr/active_low`
7 val_sysfs=`cat $GPIO_SYSFS/gpio$nr/value`
8 dir_sysfs=`cat $GPIO_SYSFS/gpio$nr/direction`
9
10 gpio_this_debugfs=`cat $GPIO_DEBUGFS |grep "gpio-$nr" | sed "s/(.*)//g"`
11 dir_debugfs=`echo $gpio_this_debugfs | awk '{print $2}'`
12 val_debugfs=`echo $gpio_this_debugfs | awk '{print $3}'`
13 if [ $val_debugfs = "lo" ]; then
14 val=0
15 elif [ $val_debugfs = "hi" ]; then
16 val=1
17 fi
18
19 if [ $active_low_sysfs = "1" ]; then
20 if [ $val = "0" ]; then
21 val="1"
22 else
23 val="0"
24 fi
25 fi
26
27 if [ $val_sysfs = $val ] && [ $dir_sysfs = $dir_debugfs ]; then
28 echo -n "."
29 else
30 echo "test fail, exit"
31 die
32 fi
33}
34
35test_pin_logic()
36{
37 nr=$1
38 direction=$2
39 active_low=$3
40 value=$4
41
42 echo $direction > $GPIO_SYSFS/gpio$nr/direction
43 echo $active_low > $GPIO_SYSFS/gpio$nr/active_low
44 if [ $direction = "out" ]; then
45 echo $value > $GPIO_SYSFS/gpio$nr/value
46 fi
47 is_consistent $nr
48}
49
50test_one_pin()
51{
52 nr=$1
53
54 echo -n "test pin<$nr>"
55
56 echo $nr > $GPIO_SYSFS/export 2>/dev/null
57
58 if [ X$? != X0 ]; then
59 echo "test GPIO pin $nr failed"
60 die
61 fi
62
63 #"Checking if the sysfs is consistent with debugfs: "
64 is_consistent $nr
65
66 #"Checking the logic of active_low: "
67 test_pin_logic $nr out 1 1
68 test_pin_logic $nr out 1 0
69 test_pin_logic $nr out 0 1
70 test_pin_logic $nr out 0 0
71
72 #"Checking the logic of direction: "
73 test_pin_logic $nr in 1 1
74 test_pin_logic $nr out 1 0
75 test_pin_logic $nr low 0 1
76 test_pin_logic $nr high 0 0
77
78 echo $nr > $GPIO_SYSFS/unexport
79
80 echo "successful"
81}
82
83test_one_pin_fail()
84{
85 nr=$1
86
87 echo $nr > $GPIO_SYSFS/export 2>/dev/null
88
89 if [ X$? != X0 ]; then
90 echo "test invalid pin $nr successful"
91 else
92 echo "test invalid pin $nr failed"
93 echo $nr > $GPIO_SYSFS/unexport 2>/dev/null
94 die
95 fi
96}
97
98list_chip()
99{
100 echo `ls -d $GPIO_DRV_SYSFS/gpiochip* 2>/dev/null`
101}
102
103test_chip()
104{
105 chip=$1
106 name=`basename $chip`
107 base=`cat $chip/base`
108 ngpio=`cat $chip/ngpio`
109 printf "%-10s %-5s %-5s\n" $name $base $ngpio
110 if [ $ngpio = "0" ]; then
111 echo "number of gpio is zero is not allowed".
112 fi
113 test_one_pin $base
114 test_one_pin $(($base + $ngpio - 1))
115 test_one_pin $((( RANDOM % $ngpio ) + $base ))
116}
117
118test_chips_sysfs()
119{
120 gpiochip=`list_chip $module`
121 if [ X"$gpiochip" = X ]; then
122 if [ X"$valid" = Xfalse ]; then
123 echo "successful"
124 else
125 echo "fail"
126 die
127 fi
128 else
129 for chip in $gpiochip; do
130 test_chip $chip
131 done
132 fi
133}
134
diff --git a/tools/testing/selftests/gpio/gpio-mockup.sh b/tools/testing/selftests/gpio/gpio-mockup.sh
new file mode 100755
index 000000000000..b183439e058e
--- /dev/null
+++ b/tools/testing/selftests/gpio/gpio-mockup.sh
@@ -0,0 +1,201 @@
1#!/bin/bash
2
3#exit status
4#1: run as non-root user
5#2: sysfs/debugfs not mount
6#3: insert module fail when gpio-mockup is a module.
7#4: other reason.
8
9SYSFS=
10GPIO_SYSFS=
11GPIO_DRV_SYSFS=
12DEBUGFS=
13GPIO_DEBUGFS=
14dev_type=
15module=
16
17usage()
18{
19 echo "Usage:"
20 echo "$0 [-f] [-m name] [-t type]"
21 echo "-f: full test. It maybe conflict with existence gpio device."
22 echo "-m: module name, default name is gpio-mockup. It could also test"
23 echo " other gpio device."
24 echo "-t: interface type: chardev(char device) and sysfs(being"
25 echo " deprecated). The first one is default"
26 echo ""
27 echo "$0 -h"
28 echo "This usage"
29}
30
31prerequisite()
32{
33 msg="skip all tests:"
34 if [ $UID != 0 ]; then
35 echo $msg must be run as root >&2
36 exit 1
37 fi
38 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
39 if [ ! -d "$SYSFS" ]; then
40 echo $msg sysfs is not mounted >&2
41 exit 2
42 fi
43 GPIO_SYSFS=`echo $SYSFS/class/gpio`
44 GPIO_DRV_SYSFS=`echo $SYSFS/devices/platform/$module/gpio`
45 DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
46 if [ ! -d "$DEBUGFS" ]; then
47 echo $msg debugfs is not mounted >&2
48 exit 2
49 fi
50 GPIO_DEBUGFS=`echo $DEBUGFS/gpio`
51 source gpio-mockup-sysfs.sh
52}
53
54try_insert_module()
55{
56 if [ -d "$GPIO_DRV_SYSFS" ]; then
57 echo "$GPIO_DRV_SYSFS exist. Skip insert module"
58 else
59 modprobe -q $module $1
60 if [ X$? != X0 ]; then
61 echo $msg insmod $module failed >&2
62 exit 3
63 fi
64 fi
65}
66
67remove_module()
68{
69 modprobe -r -q $module
70}
71
72die()
73{
74 remove_module
75 exit 4
76}
77
78test_chips()
79{
80 if [ X$dev_type = Xsysfs ]; then
81 echo "WARNING: sysfs ABI of gpio is going to deprecated."
82 test_chips_sysfs $*
83 else
84 $BASE/gpio-mockup-chardev $*
85 fi
86}
87
88gpio_test()
89{
90 param=$1
91 valid=$2
92
93 if [ X"$param" = X ]; then
94 die
95 fi
96 try_insert_module "gpio_mockup_ranges=$param"
97 echo -n "GPIO $module test with ranges: <"
98 echo "$param>: "
99 printf "%-10s %s\n" $param
100 test_chips $module $valid
101 remove_module
102}
103
104BASE=`dirname $0`
105
106dev_type=
107TEMP=`getopt -o fhm:t: -n '$0' -- "$@"`
108
109if [ "$?" != "0" ]; then
110 echo "Parameter process failed, Terminating..." >&2
111 exit 1
112fi
113
114# Note the quotes around `$TEMP': they are essential!
115eval set -- "$TEMP"
116
117while true; do
118 case $1 in
119 -f)
120 full_test=true
121 shift
122 ;;
123 -h)
124 usage
125 exit
126 ;;
127 -m)
128 module=$2
129 shift 2
130 ;;
131 -t)
132 dev_type=$2
133 shift 2
134 ;;
135 --)
136 shift
137 break
138 ;;
139 *)
140 echo "Internal error!"
141 exit 1
142 ;;
143 esac
144done
145
146if [ X"$module" = X ]; then
147 module="gpio-mockup"
148fi
149
150if [ X$dev_type != Xsysfs ]; then
151 dev_type="chardev"
152fi
153
154prerequisite
155
156echo "1. Test dynamic allocation of gpio successful means insert gpiochip and"
157echo " manipulate gpio pin successful"
158gpio_test "-1,32" true
159gpio_test "-1,32,-1,32" true
160gpio_test "-1,32,-1,32,-1,32" true
161if [ X$full_test = Xtrue ]; then
162 gpio_test "-1,32,32,64" true
163 gpio_test "-1,32,40,64,-1,5" true
164 gpio_test "-1,32,32,64,-1,32" true
165 gpio_test "0,32,32,64,-1,32,-1,32" true
166 gpio_test "-1,32,-1,32,0,32,32,64" true
167 echo "2. Do basic test: successful means insert gpiochip and"
168 echo " manipulate gpio pin successful"
169 gpio_test "0,32" true
170 gpio_test "0,32,32,64" true
171 gpio_test "0,32,40,64,64,96" true
172fi
173echo "3. Error test: successful means insert gpiochip failed"
174echo "3.1 Test number of gpio overflow"
175#Currently: The max number of gpio(1024) is defined in arm architecture.
176gpio_test "-1,32,-1,1024" false
177if [ X$full_test = Xtrue ]; then
178 echo "3.2 Test zero line of gpio"
179 gpio_test "0,0" false
180 echo "3.3 Test range overlap"
181 echo "3.3.1 Test corner case"
182 gpio_test "0,32,0,1" false
183 gpio_test "0,32,32,64,32,40" false
184 gpio_test "0,32,35,64,35,45" false
185 gpio_test "0,32,31,32" false
186 gpio_test "0,32,32,64,36,37" false
187 gpio_test "0,32,35,64,34,36" false
188 echo "3.3.2 Test inserting invalid second gpiochip"
189 gpio_test "0,32,30,35" false
190 gpio_test "0,32,1,5" false
191 gpio_test "10,32,9,14" false
192 gpio_test "10,32,30,35" false
193 echo "3.3.3 Test others"
194 gpio_test "0,32,40,56,39,45" false
195 gpio_test "0,32,40,56,30,33" false
196 gpio_test "0,32,40,56,30,41" false
197 gpio_test "0,32,40,56,20,21" false
198fi
199
200echo GPIO test PASS
201
diff --git a/tools/testing/selftests/nsfs/.gitignore b/tools/testing/selftests/nsfs/.gitignore
new file mode 100644
index 000000000000..2ab2c824ce86
--- /dev/null
+++ b/tools/testing/selftests/nsfs/.gitignore
@@ -0,0 +1,2 @@
1owner
2pidns
diff --git a/tools/testing/selftests/sigaltstack/.gitignore b/tools/testing/selftests/sigaltstack/.gitignore
new file mode 100644
index 000000000000..35897b0a3f44
--- /dev/null
+++ b/tools/testing/selftests/sigaltstack/.gitignore
@@ -0,0 +1 @@
sas
diff --git a/tools/testing/selftests/sync/.gitignore b/tools/testing/selftests/sync/.gitignore
new file mode 100644
index 000000000000..f5091e7792f2
--- /dev/null
+++ b/tools/testing/selftests/sync/.gitignore
@@ -0,0 +1 @@
sync_test
diff --git a/tools/testing/selftests/sync/Makefile b/tools/testing/selftests/sync/Makefile
new file mode 100644
index 000000000000..87ac400507c0
--- /dev/null
+++ b/tools/testing/selftests/sync/Makefile
@@ -0,0 +1,24 @@
1CFLAGS += -O2 -g -std=gnu89 -pthread -Wall -Wextra
2CFLAGS += -I../../../../usr/include/
3LDFLAGS += -pthread
4
5TEST_PROGS = sync_test
6
7all: $(TEST_PROGS)
8
9include ../lib.mk
10
11OBJS = sync_test.o sync.o
12
13TESTS += sync_alloc.o
14TESTS += sync_fence.o
15TESTS += sync_merge.o
16TESTS += sync_wait.o
17TESTS += sync_stress_parallelism.o
18TESTS += sync_stress_consumer.o
19TESTS += sync_stress_merge.o
20
21sync_test: $(OBJS) $(TESTS)
22
23clean:
24 $(RM) sync_test $(OBJS) $(TESTS)
diff --git a/tools/testing/selftests/sync/sw_sync.h b/tools/testing/selftests/sync/sw_sync.h
new file mode 100644
index 000000000000..e2cfc6bad83e
--- /dev/null
+++ b/tools/testing/selftests/sync/sw_sync.h
@@ -0,0 +1,46 @@
1/*
2 * sw_sync abstraction
3 *
4 * Copyright 2015-2016 Collabora Ltd.
5 *
6 * Based on the implementation from the Android Open Source Project,
7 *
8 * Copyright 2013 Google, Inc
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29#ifndef SELFTESTS_SW_SYNC_H
30#define SELFTESTS_SW_SYNC_H
31
32/*
33 * sw_sync is mainly intended for testing and should not be compiled into
34 * production kernels
35 */
36
37int sw_sync_timeline_create(void);
38int sw_sync_timeline_is_valid(int fd);
39int sw_sync_timeline_inc(int fd, unsigned int count);
40void sw_sync_timeline_destroy(int fd);
41
42int sw_sync_fence_create(int fd, const char *name, unsigned int value);
43int sw_sync_fence_is_valid(int fd);
44void sw_sync_fence_destroy(int fd);
45
46#endif
diff --git a/tools/testing/selftests/sync/sync.c b/tools/testing/selftests/sync/sync.c
new file mode 100644
index 000000000000..f3d599f249b9
--- /dev/null
+++ b/tools/testing/selftests/sync/sync.c
@@ -0,0 +1,221 @@
1/*
2 * sync / sw_sync abstraction
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 <fcntl.h>
29#include <malloc.h>
30#include <poll.h>
31#include <stdint.h>
32#include <string.h>
33#include <unistd.h>
34
35#include <sys/ioctl.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include "sync.h"
40#include "sw_sync.h"
41
42#include <linux/sync_file.h>
43
44
45/* SW_SYNC ioctls */
46struct sw_sync_create_fence_data {
47 __u32 value;
48 char name[32];
49 __s32 fence;
50};
51
52#define SW_SYNC_IOC_MAGIC 'W'
53#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\
54 struct sw_sync_create_fence_data)
55#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
56
57
58int sync_wait(int fd, int timeout)
59{
60 struct pollfd fds;
61
62 fds.fd = fd;
63 fds.events = POLLIN | POLLERR;
64
65 return poll(&fds, 1, timeout);
66}
67
68int sync_merge(const char *name, int fd1, int fd2)
69{
70 struct sync_merge_data data = {};
71 int err;
72
73 data.fd2 = fd2;
74 strncpy(data.name, name, sizeof(data.name) - 1);
75 data.name[sizeof(data.name) - 1] = '\0';
76
77 err = ioctl(fd1, SYNC_IOC_MERGE, &data);
78 if (err < 0)
79 return err;
80
81 return data.fence;
82}
83
84static struct sync_file_info *sync_file_info(int fd)
85{
86 struct sync_file_info *info;
87 struct sync_fence_info *fence_info;
88 int err, num_fences;
89
90 info = calloc(1, sizeof(*info));
91 if (info == NULL)
92 return NULL;
93
94 err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
95 if (err < 0) {
96 free(info);
97 return NULL;
98 }
99
100 num_fences = info->num_fences;
101
102 if (num_fences) {
103 info->flags = 0;
104 info->num_fences = num_fences;
105
106 fence_info = calloc(num_fences, sizeof(*fence_info));
107 if (!fence_info) {
108 free(info);
109 return NULL;
110 }
111
112 info->sync_fence_info = (uint64_t)fence_info;
113
114 err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
115 if (err < 0) {
116 free(fence_info);
117 free(info);
118 return NULL;
119 }
120 }
121
122 return info;
123}
124
125static void sync_file_info_free(struct sync_file_info *info)
126{
127 free((void *)info->sync_fence_info);
128 free(info);
129}
130
131int sync_fence_size(int fd)
132{
133 int count;
134 struct sync_file_info *info = sync_file_info(fd);
135
136 if (!info)
137 return 0;
138
139 count = info->num_fences;
140
141 sync_file_info_free(info);
142
143 return count;
144}
145
146int sync_fence_count_with_status(int fd, int status)
147{
148 unsigned int i, count = 0;
149 struct sync_fence_info *fence_info = NULL;
150 struct sync_file_info *info = sync_file_info(fd);
151
152 if (!info)
153 return -1;
154
155 fence_info = (struct sync_fence_info *)info->sync_fence_info;
156 for (i = 0 ; i < info->num_fences ; i++) {
157 if (fence_info[i].status == status)
158 count++;
159 }
160
161 sync_file_info_free(info);
162
163 return count;
164}
165
166int sw_sync_timeline_create(void)
167{
168 return open("/sys/kernel/debug/sync/sw_sync", O_RDWR);
169}
170
171int sw_sync_timeline_inc(int fd, unsigned int count)
172{
173 __u32 arg = count;
174
175 return ioctl(fd, SW_SYNC_IOC_INC, &arg);
176}
177
178int sw_sync_timeline_is_valid(int fd)
179{
180 int status;
181
182 if (fd == -1)
183 return 0;
184
185 status = fcntl(fd, F_GETFD, 0);
186 return (status >= 0);
187}
188
189void sw_sync_timeline_destroy(int fd)
190{
191 if (sw_sync_timeline_is_valid(fd))
192 close(fd);
193}
194
195int sw_sync_fence_create(int fd, const char *name, unsigned int value)
196{
197 struct sw_sync_create_fence_data data = {};
198 int err;
199
200 data.value = value;
201 strncpy(data.name, name, sizeof(data.name) - 1);
202 data.name[sizeof(data.name) - 1] = '\0';
203
204 err = ioctl(fd, SW_SYNC_IOC_CREATE_FENCE, &data);
205 if (err < 0)
206 return err;
207
208 return data.fence;
209}
210
211int sw_sync_fence_is_valid(int fd)
212{
213 /* Same code! */
214 return sw_sync_timeline_is_valid(fd);
215}
216
217void sw_sync_fence_destroy(int fd)
218{
219 if (sw_sync_fence_is_valid(fd))
220 close(fd);
221}
diff --git a/tools/testing/selftests/sync/sync.h b/tools/testing/selftests/sync/sync.h
new file mode 100644
index 000000000000..fb7156148350
--- /dev/null
+++ b/tools/testing/selftests/sync/sync.h
@@ -0,0 +1,40 @@
1/*
2 * sync abstraction
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#ifndef SELFTESTS_SYNC_H
29#define SELFTESTS_SYNC_H
30
31#define FENCE_STATUS_ERROR (-1)
32#define FENCE_STATUS_ACTIVE (0)
33#define FENCE_STATUS_SIGNALED (1)
34
35int sync_wait(int fd, int timeout);
36int sync_merge(const char *name, int fd1, int fd2);
37int sync_fence_size(int fd);
38int sync_fence_count_with_status(int fd, int status);
39
40#endif
diff --git a/tools/testing/selftests/sync/sync_alloc.c b/tools/testing/selftests/sync/sync_alloc.c
new file mode 100644
index 000000000000..66a28afc05dc
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_alloc.c
@@ -0,0 +1,74 @@
1/*
2 * sync allocation tests
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 "sync.h"
29#include "sw_sync.h"
30#include "synctest.h"
31
32int test_alloc_timeline(void)
33{
34 int timeline, valid;
35
36 timeline = sw_sync_timeline_create();
37 valid = sw_sync_timeline_is_valid(timeline);
38 ASSERT(valid, "Failure allocating timeline\n");
39
40 sw_sync_timeline_destroy(timeline);
41 return 0;
42}
43
44int test_alloc_fence(void)
45{
46 int timeline, fence, valid;
47
48 timeline = sw_sync_timeline_create();
49 valid = sw_sync_timeline_is_valid(timeline);
50 ASSERT(valid, "Failure allocating timeline\n");
51
52 fence = sw_sync_fence_create(timeline, "allocFence", 1);
53 valid = sw_sync_fence_is_valid(fence);
54 ASSERT(valid, "Failure allocating fence\n");
55
56 sw_sync_fence_destroy(fence);
57 sw_sync_timeline_destroy(timeline);
58 return 0;
59}
60
61int test_alloc_fence_negative(void)
62{
63 int fence, timeline;
64
65 timeline = sw_sync_timeline_create();
66 ASSERT(timeline > 0, "Failure allocating timeline\n");
67
68 fence = sw_sync_fence_create(-1, "fence", 1);
69 ASSERT(fence < 0, "Success allocating negative fence\n");
70
71 sw_sync_fence_destroy(fence);
72 sw_sync_timeline_destroy(timeline);
73 return 0;
74}
diff --git a/tools/testing/selftests/sync/sync_fence.c b/tools/testing/selftests/sync/sync_fence.c
new file mode 100644
index 000000000000..13f175287da3
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_fence.c
@@ -0,0 +1,132 @@
1/*
2 * sync fence tests with one timeline
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 "sync.h"
29#include "sw_sync.h"
30#include "synctest.h"
31
32int test_fence_one_timeline_wait(void)
33{
34 int fence, valid, ret;
35 int timeline = sw_sync_timeline_create();
36
37 valid = sw_sync_timeline_is_valid(timeline);
38 ASSERT(valid, "Failure allocating timeline\n");
39
40 fence = sw_sync_fence_create(timeline, "allocFence", 5);
41 valid = sw_sync_fence_is_valid(fence);
42 ASSERT(valid, "Failure allocating fence\n");
43
44 /* Wait on fence until timeout */
45 ret = sync_wait(fence, 0);
46 ASSERT(ret == 0, "Failure waiting on fence until timeout\n");
47
48 /* Advance timeline from 0 -> 1 */
49 ret = sw_sync_timeline_inc(timeline, 1);
50 ASSERT(ret == 0, "Failure advancing timeline\n");
51
52 /* Wait on fence until timeout */
53 ret = sync_wait(fence, 0);
54 ASSERT(ret == 0, "Failure waiting on fence until timeout\n");
55
56 /* Signal the fence */
57 ret = sw_sync_timeline_inc(timeline, 4);
58 ASSERT(ret == 0, "Failure signaling the fence\n");
59
60 /* Wait successfully */
61 ret = sync_wait(fence, 0);
62 ASSERT(ret > 0, "Failure waiting on fence\n");
63
64 /* Go even further, and confirm wait still succeeds */
65 ret = sw_sync_timeline_inc(timeline, 10);
66 ASSERT(ret == 0, "Failure going further\n");
67 ret = sync_wait(fence, 0);
68 ASSERT(ret > 0, "Failure waiting ahead\n");
69
70 sw_sync_fence_destroy(fence);
71 sw_sync_timeline_destroy(timeline);
72
73 return 0;
74}
75
76int test_fence_one_timeline_merge(void)
77{
78 int a, b, c, d, valid;
79 int timeline = sw_sync_timeline_create();
80
81 /* create fence a,b,c and then merge them all into fence d */
82 a = sw_sync_fence_create(timeline, "allocFence", 1);
83 b = sw_sync_fence_create(timeline, "allocFence", 2);
84 c = sw_sync_fence_create(timeline, "allocFence", 3);
85
86 valid = sw_sync_fence_is_valid(a) &&
87 sw_sync_fence_is_valid(b) &&
88 sw_sync_fence_is_valid(c);
89 ASSERT(valid, "Failure allocating fences\n");
90
91 d = sync_merge("mergeFence", b, a);
92 d = sync_merge("mergeFence", c, d);
93 valid = sw_sync_fence_is_valid(d);
94 ASSERT(valid, "Failure merging fences\n");
95
96 /* confirm all fences have one active point (even d) */
97 ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_ACTIVE) == 1,
98 "a has too many active fences!\n");
99 ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_ACTIVE) == 1,
100 "b has too many active fences!\n");
101 ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_ACTIVE) == 1,
102 "c has too many active fences!\n");
103 ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_ACTIVE) == 1,
104 "d has too many active fences!\n");
105
106 /* confirm that d is not signaled until the max of a,b,c */
107 sw_sync_timeline_inc(timeline, 1);
108 ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_SIGNALED) == 1,
109 "a did not signal!\n");
110 ASSERT(sync_fence_count_with_status(d, FENCE_STATUS_ACTIVE) == 1,
111 "d signaled too early!\n");
112
113 sw_sync_timeline_inc(timeline, 1);
114 ASSERT(sync_fence_count_with_status(b, FENCE_STATUS_SIGNALED) == 1,
115 "b did not signal!\n");
116 ASSERT(sync_fence_count_with_status(d, FENCE_STATUS_ACTIVE) == 1,
117 "d signaled too early!\n");
118
119 sw_sync_timeline_inc(timeline, 1);
120 ASSERT(sync_fence_count_with_status(c, FENCE_STATUS_SIGNALED) == 1,
121 "c did not signal!\n");
122 ASSERT(sync_fence_count_with_status(d, FENCE_STATUS_ACTIVE) == 0 &&
123 sync_fence_count_with_status(d, FENCE_STATUS_SIGNALED) == 1,
124 "d did not signal!\n");
125
126 sw_sync_fence_destroy(d);
127 sw_sync_fence_destroy(c);
128 sw_sync_fence_destroy(b);
129 sw_sync_fence_destroy(a);
130 sw_sync_timeline_destroy(timeline);
131 return 0;
132}
diff --git a/tools/testing/selftests/sync/sync_merge.c b/tools/testing/selftests/sync/sync_merge.c
new file mode 100644
index 000000000000..8914d43395c7
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_merge.c
@@ -0,0 +1,60 @@
1/*
2 * sync fence merge tests
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 "sync.h"
29#include "sw_sync.h"
30#include "synctest.h"
31
32int test_fence_merge_same_fence(void)
33{
34 int fence, valid, merged;
35 int timeline = sw_sync_timeline_create();
36
37 valid = sw_sync_timeline_is_valid(timeline);
38 ASSERT(valid, "Failure allocating timeline\n");
39
40 fence = sw_sync_fence_create(timeline, "allocFence", 5);
41 valid = sw_sync_fence_is_valid(fence);
42 ASSERT(valid, "Failure allocating fence\n");
43
44 merged = sync_merge("mergeFence", fence, fence);
45 valid = sw_sync_fence_is_valid(fence);
46 ASSERT(valid, "Failure merging fence\n");
47
48 ASSERT(sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED) == 0,
49 "fence signaled too early!\n");
50
51 sw_sync_timeline_inc(timeline, 5);
52 ASSERT(sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED) == 1,
53 "fence did not signal!\n");
54
55 sw_sync_fence_destroy(merged);
56 sw_sync_fence_destroy(fence);
57 sw_sync_timeline_destroy(timeline);
58
59 return 0;
60}
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 000000000000..d9eff8d524f7
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_stress_consumer.c
@@ -0,0 +1,185 @@
1/*
2 * sync stress test: producer/consumer
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
34/* IMPORTANT NOTE: if you see this test failing on your system, it may be
35 * due to a shortage of file descriptors. Please ensure your system has
36 * a sensible limit for this test to finish correctly.
37 */
38
39/* Returns 1 on error, 0 on success */
40static int busy_wait_on_fence(int fence)
41{
42 int error, active;
43
44 do {
45 error = sync_fence_count_with_status(fence, FENCE_STATUS_ERROR);
46 ASSERT(error == 0, "Error occurred on fence\n");
47 active = sync_fence_count_with_status(fence,
48 FENCE_STATUS_ACTIVE);
49 } while (active);
50
51 return 0;
52}
53
54static struct {
55 int iterations;
56 int threads;
57 int counter;
58 int consumer_timeline;
59 int *producer_timelines;
60 pthread_mutex_t lock;
61} test_data_mpsc;
62
63static int mpsc_producer_thread(void *d)
64{
65 int id = (long)d;
66 int fence, valid, i;
67 int *producer_timelines = test_data_mpsc.producer_timelines;
68 int consumer_timeline = test_data_mpsc.consumer_timeline;
69 int iterations = test_data_mpsc.iterations;
70
71 for (i = 0; i < iterations; i++) {
72 fence = sw_sync_fence_create(consumer_timeline, "fence", i);
73 valid = sw_sync_fence_is_valid(fence);
74 ASSERT(valid, "Failure creating fence\n");
75
76 /*
77 * Wait for the consumer to finish. Use alternate
78 * means of waiting on the fence
79 */
80
81 if ((iterations + id) % 8 != 0) {
82 ASSERT(sync_wait(fence, -1) > 0,
83 "Failure waiting on fence\n");
84 } else {
85 ASSERT(busy_wait_on_fence(fence) == 0,
86 "Failure waiting on fence\n");
87 }
88
89 /*
90 * Every producer increments the counter, the consumer
91 * checks and erases it
92 */
93 pthread_mutex_lock(&test_data_mpsc.lock);
94 test_data_mpsc.counter++;
95 pthread_mutex_unlock(&test_data_mpsc.lock);
96
97 ASSERT(sw_sync_timeline_inc(producer_timelines[id], 1) == 0,
98 "Error advancing producer timeline\n");
99
100 sw_sync_fence_destroy(fence);
101 }
102
103 return 0;
104}
105
106static int mpcs_consumer_thread(void)
107{
108 int fence, merged, tmp, valid, it, i;
109 int *producer_timelines = test_data_mpsc.producer_timelines;
110 int consumer_timeline = test_data_mpsc.consumer_timeline;
111 int iterations = test_data_mpsc.iterations;
112 int n = test_data_mpsc.threads;
113
114 for (it = 1; it <= iterations; it++) {
115 fence = sw_sync_fence_create(producer_timelines[0], "name", it);
116 for (i = 1; i < n; i++) {
117 tmp = sw_sync_fence_create(producer_timelines[i],
118 "name", it);
119 merged = sync_merge("name", tmp, fence);
120 sw_sync_fence_destroy(tmp);
121 sw_sync_fence_destroy(fence);
122 fence = merged;
123 }
124
125 valid = sw_sync_fence_is_valid(fence);
126 ASSERT(valid, "Failure merging fences\n");
127
128 /*
129 * Make sure we see an increment from every producer thread.
130 * Vary the means by which we wait.
131 */
132 if (iterations % 8 != 0) {
133 ASSERT(sync_wait(fence, -1) > 0,
134 "Producers did not increment as expected\n");
135 } else {
136 ASSERT(busy_wait_on_fence(fence) == 0,
137 "Producers did not increment as expected\n");
138 }
139
140 ASSERT(test_data_mpsc.counter == n * it,
141 "Counter value mismatch!\n");
142
143 /* Release the producer threads */
144 ASSERT(sw_sync_timeline_inc(consumer_timeline, 1) == 0,
145 "Failure releasing producer threads\n");
146
147 sw_sync_fence_destroy(fence);
148 }
149
150 return 0;
151}
152
153int test_consumer_stress_multi_producer_single_consumer(void)
154{
155 int iterations = 1 << 12;
156 int n = 5;
157 long i, ret;
158 int producer_timelines[n];
159 int consumer_timeline;
160 pthread_t threads[n];
161
162 consumer_timeline = sw_sync_timeline_create();
163 for (i = 0; i < n; i++)
164 producer_timelines[i] = sw_sync_timeline_create();
165
166 test_data_mpsc.producer_timelines = producer_timelines;
167 test_data_mpsc.consumer_timeline = consumer_timeline;
168 test_data_mpsc.iterations = iterations;
169 test_data_mpsc.threads = n;
170 test_data_mpsc.counter = 0;
171 pthread_mutex_init(&test_data_mpsc.lock, NULL);
172
173 for (i = 0; i < n; i++) {
174 pthread_create(&threads[i], NULL, (void * (*)(void *))
175 mpsc_producer_thread, (void *)i);
176 }
177
178 /* Consumer thread runs here */
179 ret = mpcs_consumer_thread();
180
181 for (i = 0; i < n; i++)
182 pthread_join(threads[i], NULL);
183
184 return ret;
185}
diff --git a/tools/testing/selftests/sync/sync_stress_merge.c b/tools/testing/selftests/sync/sync_stress_merge.c
new file mode 100644
index 000000000000..99e83ef45fbf
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_stress_merge.c
@@ -0,0 +1,115 @@
1/*
2 * sync stress test: merging
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 <stdlib.h>
29#include <string.h>
30#include <time.h>
31
32#include "sync.h"
33#include "sw_sync.h"
34#include "synctest.h"
35
36int test_merge_stress_random_merge(void)
37{
38 int i, size, ret;
39 int timeline_count = 32;
40 int merge_count = 1024 * 32;
41 int timelines[timeline_count];
42 int fence_map[timeline_count];
43 int fence, tmpfence, merged, valid;
44 int timeline, timeline_offset, sync_point;
45
46 srand(time(NULL));
47
48 for (i = 0; i < timeline_count; i++)
49 timelines[i] = sw_sync_timeline_create();
50
51 fence = sw_sync_fence_create(timelines[0], "fence", 0);
52 valid = sw_sync_fence_is_valid(fence);
53 ASSERT(valid, "Failure creating fence\n");
54
55 memset(fence_map, -1, sizeof(fence_map));
56 fence_map[0] = 0;
57
58 /*
59 * Randomly create sync_points out of a fixed set of timelines,
60 * and merge them together
61 */
62 for (i = 0; i < merge_count; i++) {
63 /* Generate sync_point. */
64 timeline_offset = rand() % timeline_count;
65 timeline = timelines[timeline_offset];
66 sync_point = rand();
67
68 /* Keep track of the latest sync_point in each timeline. */
69 if (fence_map[timeline_offset] == -1)
70 fence_map[timeline_offset] = sync_point;
71 else if (fence_map[timeline_offset] < sync_point)
72 fence_map[timeline_offset] = sync_point;
73
74 /* Merge */
75 tmpfence = sw_sync_fence_create(timeline, "fence", sync_point);
76 merged = sync_merge("merge", tmpfence, fence);
77 sw_sync_fence_destroy(tmpfence);
78 sw_sync_fence_destroy(fence);
79 fence = merged;
80
81 valid = sw_sync_fence_is_valid(merged);
82 ASSERT(valid, "Failure creating fence i\n");
83 }
84
85 size = 0;
86 for (i = 0; i < timeline_count; i++)
87 if (fence_map[i] != -1)
88 size++;
89
90 /* Confirm our map matches the fence. */
91 ASSERT(sync_fence_size(fence) == size,
92 "Quantity of elements not matching\n");
93
94 /* Trigger the merged fence */
95 for (i = 0; i < timeline_count; i++) {
96 if (fence_map[i] != -1) {
97 ret = sync_wait(fence, 0);
98 ASSERT(ret == 0,
99 "Failure waiting on fence until timeout\n");
100 /* Increment the timeline to the last sync_point */
101 sw_sync_timeline_inc(timelines[i], fence_map[i]);
102 }
103 }
104
105 /* Check that the fence is triggered. */
106 ret = sync_wait(fence, 0);
107 ASSERT(ret > 0, "Failure triggering fence\n");
108
109 sw_sync_fence_destroy(fence);
110
111 for (i = 0; i < timeline_count; i++)
112 sw_sync_timeline_destroy(timelines[i]);
113
114 return 0;
115}
diff --git a/tools/testing/selftests/sync/sync_stress_parallelism.c b/tools/testing/selftests/sync/sync_stress_parallelism.c
new file mode 100644
index 000000000000..e6c9be671dfc
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_stress_parallelism.c
@@ -0,0 +1,111 @@
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}
diff --git a/tools/testing/selftests/sync/sync_test.c b/tools/testing/selftests/sync/sync_test.c
new file mode 100644
index 000000000000..9ea08d9f0b13
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_test.c
@@ -0,0 +1,79 @@
1/*
2 * sync test runner
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 <stdio.h>
29#include <unistd.h>
30#include <stdlib.h>
31#include <sys/types.h>
32#include <sys/wait.h>
33
34#include "synctest.h"
35
36static int run_test(int (*test)(void), char *name)
37{
38 int result;
39 pid_t childpid;
40
41 fflush(stdout);
42 childpid = fork();
43
44 if (childpid) {
45 waitpid(childpid, &result, 0);
46 if (WIFEXITED(result))
47 return WEXITSTATUS(result);
48 return 1;
49 }
50
51 printf("[RUN]\tExecuting %s\n", name);
52 exit(test());
53}
54
55int main(void)
56{
57 int err = 0;
58
59 printf("[RUN]\tTesting sync framework\n");
60
61 err += RUN_TEST(test_alloc_timeline);
62 err += RUN_TEST(test_alloc_fence);
63 err += RUN_TEST(test_alloc_fence_negative);
64
65 err += RUN_TEST(test_fence_one_timeline_wait);
66 err += RUN_TEST(test_fence_one_timeline_merge);
67 err += RUN_TEST(test_fence_merge_same_fence);
68 err += RUN_TEST(test_fence_multi_timeline_wait);
69 err += RUN_TEST(test_stress_two_threads_shared_timeline);
70 err += RUN_TEST(test_consumer_stress_multi_producer_single_consumer);
71 err += RUN_TEST(test_merge_stress_random_merge);
72
73 if (err)
74 printf("[FAIL]\tsync errors: %d\n", err);
75 else
76 printf("[OK]\tsync\n");
77
78 return !!err;
79}
diff --git a/tools/testing/selftests/sync/sync_wait.c b/tools/testing/selftests/sync/sync_wait.c
new file mode 100644
index 000000000000..d69b752f6550
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_wait.c
@@ -0,0 +1,91 @@
1/*
2 * sync fence wait tests
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 "sync.h"
29#include "sw_sync.h"
30#include "synctest.h"
31
32int test_fence_multi_timeline_wait(void)
33{
34 int timelineA, timelineB, timelineC;
35 int fenceA, fenceB, fenceC, merged;
36 int valid, active, signaled, ret;
37
38 timelineA = sw_sync_timeline_create();
39 timelineB = sw_sync_timeline_create();
40 timelineC = sw_sync_timeline_create();
41
42 fenceA = sw_sync_fence_create(timelineA, "fenceA", 5);
43 fenceB = sw_sync_fence_create(timelineB, "fenceB", 5);
44 fenceC = sw_sync_fence_create(timelineC, "fenceC", 5);
45
46 merged = sync_merge("mergeFence", fenceB, fenceA);
47 merged = sync_merge("mergeFence", fenceC, merged);
48
49 valid = sw_sync_fence_is_valid(merged);
50 ASSERT(valid, "Failure merging fence from various timelines\n");
51
52 /* Confirm fence isn't signaled */
53 active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
54 ASSERT(active == 3, "Fence signaled too early!\n");
55
56 ret = sync_wait(merged, 0);
57 ASSERT(ret == 0,
58 "Failure waiting on fence until timeout\n");
59
60 ret = sw_sync_timeline_inc(timelineA, 5);
61 active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
62 signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
63 ASSERT(active == 2 && signaled == 1,
64 "Fence did not signal properly!\n");
65
66 ret = sw_sync_timeline_inc(timelineB, 5);
67 active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
68 signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
69 ASSERT(active == 1 && signaled == 2,
70 "Fence did not signal properly!\n");
71
72 ret = sw_sync_timeline_inc(timelineC, 5);
73 active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
74 signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
75 ASSERT(active == 0 && signaled == 3,
76 "Fence did not signal properly!\n");
77
78 /* confirm you can successfully wait */
79 ret = sync_wait(merged, 100);
80 ASSERT(ret > 0, "Failure waiting on signaled fence\n");
81
82 sw_sync_fence_destroy(merged);
83 sw_sync_fence_destroy(fenceC);
84 sw_sync_fence_destroy(fenceB);
85 sw_sync_fence_destroy(fenceA);
86 sw_sync_timeline_destroy(timelineC);
87 sw_sync_timeline_destroy(timelineB);
88 sw_sync_timeline_destroy(timelineA);
89
90 return 0;
91}
diff --git a/tools/testing/selftests/sync/synctest.h b/tools/testing/selftests/sync/synctest.h
new file mode 100644
index 000000000000..e7d1d57dba7a
--- /dev/null
+++ b/tools/testing/selftests/sync/synctest.h
@@ -0,0 +1,66 @@
1/*
2 * sync tests
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#ifndef SELFTESTS_SYNCTEST_H
29#define SELFTESTS_SYNCTEST_H
30
31#include <stdio.h>
32
33#define ASSERT(cond, msg) do { \
34 if (!(cond)) { \
35 printf("[ERROR]\t%s", (msg)); \
36 return 1; \
37 } \
38} while (0)
39
40#define RUN_TEST(x) run_test((x), #x)
41
42/* Allocation tests */
43int test_alloc_timeline(void);
44int test_alloc_fence(void);
45int test_alloc_fence_negative(void);
46
47/* Fence tests with one timeline */
48int test_fence_one_timeline_wait(void);
49int test_fence_one_timeline_merge(void);
50
51/* Fence merge tests */
52int test_fence_merge_same_fence(void);
53
54/* Fence wait tests */
55int test_fence_multi_timeline_wait(void);
56
57/* Stress test - parallelism */
58int test_stress_two_threads_shared_timeline(void);
59
60/* Stress test - consumer */
61int test_consumer_stress_multi_producer_single_consumer(void);
62
63/* Stress test - merging */
64int test_merge_stress_random_merge(void);
65
66#endif
diff --git a/tools/testing/selftests/timers/.gitignore b/tools/testing/selftests/timers/.gitignore
index 68f3fc71ac44..cc986621f512 100644
--- a/tools/testing/selftests/timers/.gitignore
+++ b/tools/testing/selftests/timers/.gitignore
@@ -17,3 +17,4 @@ skew_consistency
17threadtest 17threadtest
18valid-adjtimex 18valid-adjtimex
19adjtick 19adjtick
20set-tz