1 /*
2  * Copyright (C) 2013 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 <sys/mman.h>
18 
19 #include <gtest/gtest.h>
20 
21 #include <ion/ion.h>
22 #include "ion_test_fixture.h"
23 
24 class Allocate : public IonAllHeapsTest {
25 };
26 
TEST_F(Allocate,Allocate)27 TEST_F(Allocate, Allocate)
28 {
29     static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
30     for (unsigned int heapMask : m_allHeaps) {
31         for (size_t size : allocationSizes) {
32             SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
33             SCOPED_TRACE(::testing::Message() << "size " << size);
34             ion_user_handle_t handle = 0;
35             ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle));
36             ASSERT_TRUE(handle != 0);
37             ASSERT_EQ(0, ion_free(m_ionFd, handle));
38         }
39     }
40 }
41 
TEST_F(Allocate,AllocateCached)42 TEST_F(Allocate, AllocateCached)
43 {
44     static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
45     for (unsigned int heapMask : m_allHeaps) {
46         for (size_t size : allocationSizes) {
47             SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
48             SCOPED_TRACE(::testing::Message() << "size " << size);
49             ion_user_handle_t handle = 0;
50             ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED, &handle));
51             ASSERT_TRUE(handle != 0);
52             ASSERT_EQ(0, ion_free(m_ionFd, handle));
53         }
54     }
55 }
56 
TEST_F(Allocate,AllocateCachedNeedsSync)57 TEST_F(Allocate, AllocateCachedNeedsSync)
58 {
59     static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
60     for (unsigned int heapMask : m_allHeaps) {
61         for (size_t size : allocationSizes) {
62             SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
63             SCOPED_TRACE(::testing::Message() << "size " << size);
64             ion_user_handle_t handle = 0;
65             ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED_NEEDS_SYNC, &handle));
66             ASSERT_TRUE(handle != 0);
67             ASSERT_EQ(0, ion_free(m_ionFd, handle));
68         }
69     }
70 }
71 
TEST_F(Allocate,RepeatedAllocate)72 TEST_F(Allocate, RepeatedAllocate)
73 {
74     static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
75     for (unsigned int heapMask : m_allHeaps) {
76         for (size_t size : allocationSizes) {
77             SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
78             SCOPED_TRACE(::testing::Message() << "size " << size);
79             ion_user_handle_t handle = 0;
80 
81             for (unsigned int i = 0; i < 1024; i++) {
82                 SCOPED_TRACE(::testing::Message() << "iteration " << i);
83                 ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle));
84                 ASSERT_TRUE(handle != 0);
85                 ASSERT_EQ(0, ion_free(m_ionFd, handle));
86             }
87         }
88     }
89 }
90 
TEST_F(Allocate,Zeroed)91 TEST_F(Allocate, Zeroed)
92 {
93     void *zeroes = calloc(4096, 1);
94 
95     for (unsigned int heapMask : m_allHeaps) {
96         SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
97         int fds[16];
98         for (unsigned int i = 0; i < 16; i++) {
99             int map_fd = -1;
100 
101             ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, 0, &map_fd));
102             ASSERT_GE(map_fd, 0);
103 
104             void *ptr = NULL;
105             ptr = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, map_fd, 0);
106             ASSERT_TRUE(ptr != NULL);
107 
108             memset(ptr, 0xaa, 4096);
109 
110             ASSERT_EQ(0, munmap(ptr, 4096));
111             fds[i] = map_fd;
112         }
113 
114         for (unsigned int i = 0; i < 16; i++) {
115             ASSERT_EQ(0, close(fds[i]));
116         }
117 
118         int newIonFd = ion_open();
119         int map_fd = -1;
120 
121         ASSERT_EQ(0, ion_alloc_fd(newIonFd, 4096, 0, heapMask, 0, &map_fd));
122         ASSERT_GE(map_fd, 0);
123 
124         void *ptr = NULL;
125         ptr = mmap(NULL, 4096, PROT_READ, MAP_SHARED, map_fd, 0);
126         ASSERT_TRUE(ptr != NULL);
127 
128         ASSERT_EQ(0, memcmp(ptr, zeroes, 4096));
129 
130         ASSERT_EQ(0, munmap(ptr, 4096));
131         ASSERT_EQ(0, close(map_fd));
132     }
133 
134     free(zeroes);
135 
136 }
137 
TEST_F(Allocate,Large)138 TEST_F(Allocate, Large)
139 {
140     for (unsigned int heapMask : m_allHeaps) {
141             SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
142         ion_user_handle_t handle = 0;
143         ASSERT_EQ(-ENOMEM, ion_alloc(m_ionFd, 3UL*1024*1024*1024, 0, heapMask, 0, &handle));
144     }
145 }
146