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(fd: timelines[0], name: "fence" , value: 0); |
52 | valid = sw_sync_fence_is_valid(fd: 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(fd: timeline, name: "fence" , value: sync_point); |
76 | merged = sync_merge(name: "merge" , fd1: tmpfence, fd2: fence); |
77 | sw_sync_fence_destroy(fd: tmpfence); |
78 | sw_sync_fence_destroy(fd: fence); |
79 | fence = merged; |
80 | |
81 | valid = sw_sync_fence_is_valid(fd: 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(fd: fence, timeout: 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(fd: timelines[i], count: fence_map[i]); |
102 | } |
103 | } |
104 | |
105 | /* Check that the fence is triggered. */ |
106 | ret = sync_wait(fd: fence, timeout: 0); |
107 | ASSERT(ret > 0, "Failure triggering fence\n" ); |
108 | |
109 | sw_sync_fence_destroy(fd: fence); |
110 | |
111 | for (i = 0; i < timeline_count; i++) |
112 | sw_sync_timeline_destroy(fd: timelines[i]); |
113 | |
114 | return 0; |
115 | } |
116 | |