• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // Unit tests for HandleAllocator.
7 //
8 
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11 
12 #include "libANGLE/HandleAllocator.h"
13 
14 namespace
15 {
16 
TEST(HandleAllocatorTest,ReservationsWithGaps)17 TEST(HandleAllocatorTest, ReservationsWithGaps)
18 {
19     gl::HandleAllocator allocator;
20 
21     std::set<GLuint> allocationList;
22     for (GLuint id = 2; id < 50; id += 2)
23     {
24         allocationList.insert(id);
25     }
26 
27     for (GLuint id : allocationList)
28     {
29         allocator.reserve(id);
30     }
31 
32     std::set<GLuint> allocatedList;
33     for (size_t allocationNum = 0; allocationNum < allocationList.size() * 2; ++allocationNum)
34     {
35         GLuint handle = allocator.allocate();
36         EXPECT_EQ(0u, allocationList.count(handle));
37         EXPECT_EQ(0u, allocatedList.count(handle));
38         allocatedList.insert(handle);
39     }
40 }
41 
TEST(HandleAllocatorTest,Random)42 TEST(HandleAllocatorTest, Random)
43 {
44     gl::HandleAllocator allocator;
45 
46     std::set<GLuint> allocationList;
47     for (size_t iterationCount = 0; iterationCount < 40; ++iterationCount)
48     {
49         for (size_t randomCount = 0; randomCount < 40; ++randomCount)
50         {
51             GLuint randomHandle = (rand() % 1000) + 1;
52             if (allocationList.count(randomHandle) == 0)
53             {
54                 allocator.reserve(randomHandle);
55                 allocationList.insert(randomHandle);
56             }
57         }
58 
59         for (size_t normalCount = 0; normalCount < 40; ++normalCount)
60         {
61             GLuint normalHandle = allocator.allocate();
62             EXPECT_EQ(0u, allocationList.count(normalHandle));
63             allocationList.insert(normalHandle);
64         }
65     }
66 }
67 
TEST(HandleAllocatorTest,Reallocation)68 TEST(HandleAllocatorTest, Reallocation)
69 {
70     // Note: no current test for overflow
71     gl::HandleAllocator limitedAllocator(10);
72 
73     for (GLuint count = 1; count < 10; count++)
74     {
75         GLuint result = limitedAllocator.allocate();
76         EXPECT_EQ(count, result);
77     }
78 
79     for (GLuint count = 1; count < 10; count++)
80     {
81         limitedAllocator.release(count);
82     }
83 
84     for (GLuint count = 2; count < 10; count++)
85     {
86         limitedAllocator.reserve(count);
87     }
88 
89     GLint finalResult = limitedAllocator.allocate();
90     EXPECT_EQ(finalResult, 1);
91 }
92 
93 // The following test covers reserving a handle with max uint value. See http://anglebug.com/1052
TEST(HandleAllocatorTest,ReserveMaxUintHandle)94 TEST(HandleAllocatorTest, ReserveMaxUintHandle)
95 {
96     gl::HandleAllocator allocator;
97 
98     GLuint maxUintHandle = std::numeric_limits<GLuint>::max();
99     allocator.reserve(maxUintHandle);
100 
101     GLuint normalHandle = allocator.allocate();
102     EXPECT_EQ(1u, normalHandle);
103 }
104 
105 // The following test covers reserving a handle with max uint value minus one then max uint value.
TEST(HandleAllocatorTest,ReserveMaxUintHandle2)106 TEST(HandleAllocatorTest, ReserveMaxUintHandle2)
107 {
108     gl::HandleAllocator allocator;
109 
110     GLuint maxUintHandle = std::numeric_limits<GLuint>::max();
111     allocator.reserve(maxUintHandle - 1);
112     allocator.reserve(maxUintHandle);
113 
114     GLuint normalHandle = allocator.allocate();
115     EXPECT_EQ(1u, normalHandle);
116 }
117 
118 // To test if the allocator keep the handle in a sorted order.
TEST(HandleAllocatorTest,SortedOrderHandle)119 TEST(HandleAllocatorTest, SortedOrderHandle)
120 {
121     gl::HandleAllocator allocator;
122 
123     allocator.reserve(3);
124 
125     GLuint allocatedList[5];
126     for (GLuint count = 0; count < 5; count++)
127     {
128         allocatedList[count] = allocator.allocate();
129     }
130 
131     EXPECT_EQ(1u, allocatedList[0]);
132     EXPECT_EQ(2u, allocatedList[1]);
133     EXPECT_EQ(4u, allocatedList[2]);
134     EXPECT_EQ(5u, allocatedList[3]);
135     EXPECT_EQ(6u, allocatedList[4]);
136 }
137 
138 // Tests the reset method.
TEST(HandleAllocatorTest,Reset)139 TEST(HandleAllocatorTest, Reset)
140 {
141     gl::HandleAllocator allocator;
142 
143     for (int iteration = 0; iteration < 1; ++iteration)
144     {
145         allocator.reserve(3);
146         EXPECT_EQ(1u, allocator.allocate());
147         EXPECT_EQ(2u, allocator.allocate());
148         EXPECT_EQ(4u, allocator.allocate());
149         allocator.reset();
150     }
151 }
152 
153 // Covers a particular bug with reserving and allocating sub ranges.
TEST(HandleAllocatorTest,ReserveAndAllocateIterated)154 TEST(HandleAllocatorTest, ReserveAndAllocateIterated)
155 {
156     gl::HandleAllocator allocator;
157 
158     for (int iteration = 0; iteration < 3; ++iteration)
159     {
160         allocator.reserve(5);
161         allocator.reserve(6);
162         GLuint a = allocator.allocate();
163         GLuint b = allocator.allocate();
164         GLuint c = allocator.allocate();
165         allocator.release(c);
166         allocator.release(a);
167         allocator.release(b);
168         allocator.release(5);
169         allocator.release(6);
170     }
171 }
172 
173 // This test reproduces invalid heap bug when reserve resources after release.
TEST(HandleAllocatorTest,ReserveAfterReleaseBug)174 TEST(HandleAllocatorTest, ReserveAfterReleaseBug)
175 {
176     gl::HandleAllocator allocator;
177 
178     for (int iteration = 1; iteration <= 16; ++iteration)
179     {
180         allocator.allocate();
181     }
182 
183     allocator.release(15);
184     allocator.release(16);
185 
186     for (int iteration = 1; iteration <= 14; ++iteration)
187     {
188         allocator.release(iteration);
189     }
190 
191     allocator.reserve(1);
192 
193     allocator.allocate();
194 }
195 
196 }  // anonymous namespace
197