diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-15 17:17:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-15 17:17:32 -0500 |
commit | 09dee2a608a4a7d42f021f83084ade7de2415d7e (patch) | |
tree | 5e5cce54d2f20763e03eaeb07aaac1bffd968f9d /tools | |
parent | d25b6af91ec600faaff3a7e863f19d3e16593e52 (diff) | |
parent | 22f6592b23ef8a0c09283bcb13087340721e1154 (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')
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 | |||
7 | TARGETS += firmware | 7 | TARGETS += firmware |
8 | TARGETS += ftrace | 8 | TARGETS += ftrace |
9 | TARGETS += futex | 9 | TARGETS += futex |
10 | TARGETS += gpio | ||
10 | TARGETS += ipc | 11 | TARGETS += ipc |
11 | TARGETS += kcmp | 12 | TARGETS += kcmp |
12 | TARGETS += lib | 13 | TARGETS += lib |
@@ -24,6 +25,7 @@ TARGETS += seccomp | |||
24 | TARGETS += sigaltstack | 25 | TARGETS += sigaltstack |
25 | TARGETS += size | 26 | TARGETS += size |
26 | TARGETS += static_keys | 27 | TARGETS += static_keys |
28 | TARGETS += sync | ||
27 | TARGETS += sysctl | 29 | TARGETS += sysctl |
28 | ifneq (1, $(quicktest)) | 30 | ifneq (1, $(quicktest)) |
29 | TARGETS += timers | 31 | TARGETS += 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 | |||
4 | if ! /sbin/modprobe -q -r i915; then | ||
5 | echo "drivers/gpu/i915: [SKIP]" | ||
6 | exit 77 | ||
7 | fi | ||
8 | |||
9 | if /sbin/modprobe -q i915 mock_selftests=-1; then | ||
10 | echo "drivers/gpu/i915: ok" | ||
11 | else | ||
12 | echo "drivers/gpu/i915: [FAIL]" | ||
13 | exit 1 | ||
14 | fi | ||
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 | |||
2 | TEST_PROGS := gpio-mockup.sh | ||
3 | TEST_FILES := gpio-mockup-sysfs.sh $(BINARIES) | ||
4 | BINARIES := gpio-mockup-chardev | ||
5 | |||
6 | include ../lib.mk | ||
7 | |||
8 | all: $(BINARIES) | ||
9 | |||
10 | clean: | ||
11 | $(RM) $(BINARIES) | ||
12 | |||
13 | CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ | ||
14 | LDLIBS += -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 | ||
29 | enum direction { | ||
30 | OUT, | ||
31 | IN | ||
32 | }; | ||
33 | |||
34 | static 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 | |||
73 | static 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 | |||
128 | static 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 | |||
188 | error_close_dir: | ||
189 | closedir(dp); | ||
190 | error_out: | ||
191 | if (*ret < 0) | ||
192 | err(EXIT_FAILURE, "list gpiochip failed: %s", strerror(*ret)); | ||
193 | |||
194 | return cinfo; | ||
195 | } | ||
196 | |||
197 | int 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 | |||
235 | fail_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 | |||
243 | void 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 | */ | ||
271 | int 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 | |||
313 | out: | ||
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 | |||
2 | is_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 | |||
35 | test_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 | |||
50 | test_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 | |||
83 | test_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 | |||
98 | list_chip() | ||
99 | { | ||
100 | echo `ls -d $GPIO_DRV_SYSFS/gpiochip* 2>/dev/null` | ||
101 | } | ||
102 | |||
103 | test_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 | |||
118 | test_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 | |||
9 | SYSFS= | ||
10 | GPIO_SYSFS= | ||
11 | GPIO_DRV_SYSFS= | ||
12 | DEBUGFS= | ||
13 | GPIO_DEBUGFS= | ||
14 | dev_type= | ||
15 | module= | ||
16 | |||
17 | usage() | ||
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 | |||
31 | prerequisite() | ||
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 | |||
54 | try_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 | |||
67 | remove_module() | ||
68 | { | ||
69 | modprobe -r -q $module | ||
70 | } | ||
71 | |||
72 | die() | ||
73 | { | ||
74 | remove_module | ||
75 | exit 4 | ||
76 | } | ||
77 | |||
78 | test_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 | |||
88 | gpio_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 | |||
104 | BASE=`dirname $0` | ||
105 | |||
106 | dev_type= | ||
107 | TEMP=`getopt -o fhm:t: -n '$0' -- "$@"` | ||
108 | |||
109 | if [ "$?" != "0" ]; then | ||
110 | echo "Parameter process failed, Terminating..." >&2 | ||
111 | exit 1 | ||
112 | fi | ||
113 | |||
114 | # Note the quotes around `$TEMP': they are essential! | ||
115 | eval set -- "$TEMP" | ||
116 | |||
117 | while 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 | ||
144 | done | ||
145 | |||
146 | if [ X"$module" = X ]; then | ||
147 | module="gpio-mockup" | ||
148 | fi | ||
149 | |||
150 | if [ X$dev_type != Xsysfs ]; then | ||
151 | dev_type="chardev" | ||
152 | fi | ||
153 | |||
154 | prerequisite | ||
155 | |||
156 | echo "1. Test dynamic allocation of gpio successful means insert gpiochip and" | ||
157 | echo " manipulate gpio pin successful" | ||
158 | gpio_test "-1,32" true | ||
159 | gpio_test "-1,32,-1,32" true | ||
160 | gpio_test "-1,32,-1,32,-1,32" true | ||
161 | if [ 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 | ||
172 | fi | ||
173 | echo "3. Error test: successful means insert gpiochip failed" | ||
174 | echo "3.1 Test number of gpio overflow" | ||
175 | #Currently: The max number of gpio(1024) is defined in arm architecture. | ||
176 | gpio_test "-1,32,-1,1024" false | ||
177 | if [ 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 | ||
198 | fi | ||
199 | |||
200 | echo 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 @@ | |||
1 | owner | ||
2 | pidns | ||
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 @@ | |||
1 | CFLAGS += -O2 -g -std=gnu89 -pthread -Wall -Wextra | ||
2 | CFLAGS += -I../../../../usr/include/ | ||
3 | LDFLAGS += -pthread | ||
4 | |||
5 | TEST_PROGS = sync_test | ||
6 | |||
7 | all: $(TEST_PROGS) | ||
8 | |||
9 | include ../lib.mk | ||
10 | |||
11 | OBJS = sync_test.o sync.o | ||
12 | |||
13 | TESTS += sync_alloc.o | ||
14 | TESTS += sync_fence.o | ||
15 | TESTS += sync_merge.o | ||
16 | TESTS += sync_wait.o | ||
17 | TESTS += sync_stress_parallelism.o | ||
18 | TESTS += sync_stress_consumer.o | ||
19 | TESTS += sync_stress_merge.o | ||
20 | |||
21 | sync_test: $(OBJS) $(TESTS) | ||
22 | |||
23 | clean: | ||
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 | |||
37 | int sw_sync_timeline_create(void); | ||
38 | int sw_sync_timeline_is_valid(int fd); | ||
39 | int sw_sync_timeline_inc(int fd, unsigned int count); | ||
40 | void sw_sync_timeline_destroy(int fd); | ||
41 | |||
42 | int sw_sync_fence_create(int fd, const char *name, unsigned int value); | ||
43 | int sw_sync_fence_is_valid(int fd); | ||
44 | void 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 */ | ||
46 | struct 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 | |||
58 | int 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 | |||
68 | int 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 | |||
84 | static 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 | |||
125 | static void sync_file_info_free(struct sync_file_info *info) | ||
126 | { | ||
127 | free((void *)info->sync_fence_info); | ||
128 | free(info); | ||
129 | } | ||
130 | |||
131 | int 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 | |||
146 | int 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 | |||
166 | int sw_sync_timeline_create(void) | ||
167 | { | ||
168 | return open("/sys/kernel/debug/sync/sw_sync", O_RDWR); | ||
169 | } | ||
170 | |||
171 | int 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 | |||
178 | int 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 | |||
189 | void sw_sync_timeline_destroy(int fd) | ||
190 | { | ||
191 | if (sw_sync_timeline_is_valid(fd)) | ||
192 | close(fd); | ||
193 | } | ||
194 | |||
195 | int 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 | |||
211 | int sw_sync_fence_is_valid(int fd) | ||
212 | { | ||
213 | /* Same code! */ | ||
214 | return sw_sync_timeline_is_valid(fd); | ||
215 | } | ||
216 | |||
217 | void 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 | |||
35 | int sync_wait(int fd, int timeout); | ||
36 | int sync_merge(const char *name, int fd1, int fd2); | ||
37 | int sync_fence_size(int fd); | ||
38 | int 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 | |||
32 | int 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 | |||
44 | int 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 | |||
61 | int 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 | |||
32 | int 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 | |||
76 | int 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 | |||
32 | int 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 */ | ||
40 | static 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 | |||
54 | static 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 | |||
63 | static 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 | |||
106 | static 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 | |||
153 | int 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 | |||
36 | int 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 | |||
34 | static struct { | ||
35 | int iterations; | ||
36 | int timeline; | ||
37 | int counter; | ||
38 | } test_data_two_threads; | ||
39 | |||
40 | static 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 | |||
75 | int 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 | |||
36 | static 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 | |||
55 | int 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 | |||
32 | int 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 */ | ||
43 | int test_alloc_timeline(void); | ||
44 | int test_alloc_fence(void); | ||
45 | int test_alloc_fence_negative(void); | ||
46 | |||
47 | /* Fence tests with one timeline */ | ||
48 | int test_fence_one_timeline_wait(void); | ||
49 | int test_fence_one_timeline_merge(void); | ||
50 | |||
51 | /* Fence merge tests */ | ||
52 | int test_fence_merge_same_fence(void); | ||
53 | |||
54 | /* Fence wait tests */ | ||
55 | int test_fence_multi_timeline_wait(void); | ||
56 | |||
57 | /* Stress test - parallelism */ | ||
58 | int test_stress_two_threads_shared_timeline(void); | ||
59 | |||
60 | /* Stress test - consumer */ | ||
61 | int test_consumer_stress_multi_producer_single_consumer(void); | ||
62 | |||
63 | /* Stress test - merging */ | ||
64 | int 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 | |||
17 | threadtest | 17 | threadtest |
18 | valid-adjtimex | 18 | valid-adjtimex |
19 | adjtick | 19 | adjtick |
20 | set-tz | ||