1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 #include <utils/LinearAllocator.h>
19 
20 using namespace android;
21 using namespace android::uirenderer;
22 
23 struct SimplePair {
24     int one = 1;
25     int two = 2;
26 };
27 
28 class SignalingDtor {
29 public:
SignalingDtor()30     SignalingDtor() {
31         mDestroyed = nullptr;
32     }
SignalingDtor(bool * destroyedSignal)33     SignalingDtor(bool* destroyedSignal) {
34         mDestroyed = destroyedSignal;
35         *mDestroyed = false;
36     }
~SignalingDtor()37     virtual ~SignalingDtor() {
38         if (mDestroyed) {
39             *mDestroyed = true;
40         }
41     }
setSignal(bool * destroyedSignal)42     void setSignal(bool* destroyedSignal) {
43         mDestroyed = destroyedSignal;
44     }
45 private:
46     bool* mDestroyed;
47 };
48 
TEST(LinearAllocator,alloc)49 TEST(LinearAllocator, alloc) {
50     LinearAllocator la;
51     EXPECT_EQ(0u, la.usedSize());
52     la.alloc(64);
53     // There's some internal tracking as well as padding
54     // so the usedSize isn't strictly defined
55     EXPECT_LE(64u, la.usedSize());
56     EXPECT_GT(80u, la.usedSize());
57     auto pair = la.alloc<SimplePair>();
58     EXPECT_LE(64u + sizeof(SimplePair), la.usedSize());
59     EXPECT_GT(80u + sizeof(SimplePair), la.usedSize());
60     EXPECT_EQ(1, pair->one);
61     EXPECT_EQ(2, pair->two);
62 }
63 
TEST(LinearAllocator,dtor)64 TEST(LinearAllocator, dtor) {
65     bool destroyed[10];
66     {
67         LinearAllocator la;
68         for (int i = 0; i < 5; i++) {
69             la.alloc<SignalingDtor>()->setSignal(destroyed + i);
70             la.alloc<SimplePair>();
71         }
72         la.alloc(100);
73         for (int i = 0; i < 5; i++) {
74             auto sd = new (la) SignalingDtor(destroyed + 5 + i);
75             la.autoDestroy(sd);
76             new (la) SimplePair();
77         }
78         la.alloc(100);
79         for (int i = 0; i < 10; i++) {
80             EXPECT_FALSE(destroyed[i]);
81         }
82     }
83     for (int i = 0; i < 10; i++) {
84         EXPECT_TRUE(destroyed[i]);
85     }
86 }
87 
TEST(LinearAllocator,rewind)88 TEST(LinearAllocator, rewind) {
89     bool destroyed;
90     {
91         LinearAllocator la;
92         auto addr = la.alloc(100);
93         EXPECT_LE(100u, la.usedSize());
94         la.rewindIfLastAlloc(addr, 100);
95         EXPECT_GT(16u, la.usedSize());
96         size_t emptySize = la.usedSize();
97         auto sigdtor = la.alloc<SignalingDtor>();
98         sigdtor->setSignal(&destroyed);
99         EXPECT_FALSE(destroyed);
100         EXPECT_LE(emptySize, la.usedSize());
101         la.rewindIfLastAlloc(sigdtor);
102         EXPECT_TRUE(destroyed);
103         EXPECT_EQ(emptySize, la.usedSize());
104         destroyed = false;
105     }
106     // Checking for a double-destroy case
107     EXPECT_EQ(destroyed, false);
108 }
109