Mir

Merge lp:~vanvugt/mir/better-scaling-test into lp:mir

Proposed by Daniel van Vugt on 2015-08-24
Status: Merged
Approved by: Daniel van Vugt on 2015-08-27
Approved revision: 2876
Merged at revision: 2884
Proposed branch: lp:~vanvugt/mir/better-scaling-test
Merge into: lp:mir
Diff against target: 185 lines (+93/-48)
1 file modified
tests/unit-tests/compositor/test_buffer_queue.cpp (+93/-48)
To merge this branch: bzr merge lp:~vanvugt/mir/better-scaling-test
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Approve on 2015-08-26
Alan Griffiths 2015-08-24 Approve on 2015-08-26
PS Jenkins bot continuous-integration Approve on 2015-08-25
Review via email: mp+268894@code.launchpad.net

Commit Message

Rewrite unit test: queue_size_scales_with_client_performance
so that it is not dependent on real time and threads racing
each other.

The robustness of this test was an issue for later related work.
It started failing spuriously (LP: #1487197) so the test needed
some improving.

To post a comment you must log in.
Alan Griffiths (alan-griffiths) wrote :

I think this is OK, but I'm having trouble being sure.

review: Approve
Kevin DuBois (kdub) wrote :

alright

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/unit-tests/compositor/test_buffer_queue.cpp'
2--- tests/unit-tests/compositor/test_buffer_queue.cpp 2015-08-21 02:02:07 +0000
3+++ tests/unit-tests/compositor/test_buffer_queue.cpp 2015-08-25 02:45:03 +0000
4@@ -194,17 +194,6 @@
5 }
6 }
7
8-std::chrono::milliseconds const throttled_compositor_rate(10);
9-void throttled_compositor_thread(mc::BufferQueue &bundle,
10- std::atomic<bool> &done)
11-{
12- while (!done)
13- {
14- bundle.compositor_release(bundle.compositor_acquire(nullptr));
15- std::this_thread::sleep_for(throttled_compositor_rate);
16- }
17-}
18-
19 void overlapping_compositor_thread(mc::BufferQueue &bundle,
20 std::atomic<bool> &done)
21 {
22@@ -216,7 +205,7 @@
23 {
24 b[i^1] = bundle.compositor_acquire(nullptr);
25 bundle.compositor_release(b[i]);
26- std::this_thread::sleep_for(throttled_compositor_rate);
27+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
28 i ^= 1;
29 }
30
31@@ -1530,62 +1519,118 @@
32 TEST_P(WithThreeOrMoreBuffers, queue_size_scales_with_client_performance)
33 {
34 q.allow_framedropping(false);
35-
36- std::atomic<bool> done(false);
37- auto unblock = [&done] { done = true; };
38-
39- // To emulate a "fast" client we use a "slow" compositor
40- mt::AutoUnblockThread compositor(unblock,
41- throttled_compositor_thread, std::ref(q), std::ref(done));
42-
43 std::unordered_set<mg::Buffer *> buffers_acquired;
44
45 int const delay = 3;
46 q.set_scaling_delay(delay);
47
48- for (int frame = 0; frame < 10; frame++)
49+ for (int frame = 0; frame < 10;)
50 {
51- auto handle = client_acquire_async(q);
52- handle->wait_for(std::chrono::seconds(1));
53- ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
54-
55- if (frame > delay)
56- buffers_acquired.insert(handle->buffer());
57- handle->release_buffer();
58+ std::shared_ptr<AcquireWaitHandle> client;
59+ do
60+ {
61+ client = client_acquire_async(q);
62+ if (client->has_acquired_buffer())
63+ {
64+ if (frame > delay)
65+ buffers_acquired.insert(client->buffer());
66+ client->release_buffer();
67+ client.reset();
68+ }
69+ } while (!client);
70+
71+ while (q.buffers_ready_for_compositor(nullptr))
72+ {
73+ q.compositor_release(q.compositor_acquire(nullptr));
74+ ++frame;
75+ }
76+
77+ if (client->has_acquired_buffer())
78+ {
79+ if (frame > delay)
80+ buffers_acquired.insert(client->buffer());
81+ client->release_buffer();
82+ client.reset();
83+ }
84 }
85 // Expect double-buffers for fast clients
86 EXPECT_THAT(buffers_acquired.size(), Eq(2));
87
88 // Now check what happens if the client becomes slow...
89 buffers_acquired.clear();
90- for (int frame = 0; frame < 10; frame++)
91+ for (int frame = 0; frame < 10;)
92 {
93- auto handle = client_acquire_async(q);
94- handle->wait_for(std::chrono::seconds(1));
95- ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
96-
97- if (frame > delay)
98- buffers_acquired.insert(handle->buffer());
99-
100- // Client is just too slow to keep up:
101- std::this_thread::sleep_for(throttled_compositor_rate * 1.5);
102-
103- handle->release_buffer();
104+ std::shared_ptr<AcquireWaitHandle> client;
105+ do
106+ {
107+ client = client_acquire_async(q);
108+ if (client->has_acquired_buffer())
109+ {
110+ if (frame > delay)
111+ buffers_acquired.insert(client->buffer());
112+ client->release_buffer();
113+ client.reset();
114+ }
115+ } while (!client);
116+
117+ while (q.buffers_ready_for_compositor(nullptr))
118+ {
119+ q.compositor_release(q.compositor_acquire(nullptr));
120+ ++frame;
121+ }
122+
123+ if (client->has_acquired_buffer())
124+ {
125+ if (frame > delay)
126+ buffers_acquired.insert(client->buffer());
127+ client->release_buffer();
128+ client.reset();
129+ }
130+
131+ // Balance compositor consumption with client production:
132+ while (q.buffers_ready_for_compositor(nullptr))
133+ {
134+ q.compositor_release(q.compositor_acquire(nullptr));
135+ ++frame;
136+ }
137+
138+ // Imbalance: Compositor is now requesting more than the client does:
139+ q.compositor_release(q.compositor_acquire(nullptr));
140+ ++frame;
141 }
142 // Expect at least triple buffers for sluggish clients
143 EXPECT_THAT(buffers_acquired.size(), Ge(3));
144
145 // And what happens if the client becomes fast again?...
146 buffers_acquired.clear();
147- for (int frame = 0; frame < 10; frame++)
148+ for (int frame = 0; frame < 10;)
149 {
150- auto handle = client_acquire_async(q);
151- handle->wait_for(std::chrono::seconds(1));
152- ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
153-
154- if (frame > delay)
155- buffers_acquired.insert(handle->buffer());
156- handle->release_buffer();
157+ std::shared_ptr<AcquireWaitHandle> client;
158+ do
159+ {
160+ client = client_acquire_async(q);
161+ if (client->has_acquired_buffer())
162+ {
163+ if (frame > delay)
164+ buffers_acquired.insert(client->buffer());
165+ client->release_buffer();
166+ client.reset();
167+ }
168+ } while (!client);
169+
170+ while (q.buffers_ready_for_compositor(nullptr))
171+ {
172+ q.compositor_release(q.compositor_acquire(nullptr));
173+ ++frame;
174+ }
175+
176+ if (client->has_acquired_buffer())
177+ {
178+ if (frame > delay)
179+ buffers_acquired.insert(client->buffer());
180+ client->release_buffer();
181+ client.reset();
182+ }
183 }
184 // Expect double-buffers for fast clients
185 EXPECT_THAT(buffers_acquired.size(), Eq(2));

Subscribers

People subscribed via source and target branches