1 /*
2 * Copyright 2020 Google, Inc
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 <BufferAllocator/BufferAllocatorWrapper.h>
18 #include <errno.h>
19 #include <ion/ion.h>
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/mman.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26
legacy_ion_custom_callback(int ion_fd)27 int legacy_ion_custom_callback(int ion_fd) {
28 int ret = 0;
29 if (!ion_is_legacy(ion_fd)) {
30 perror("error in legacy ion custom callback");
31 ret = errno;
32 } else {
33 printf("in custom legacy ion cpu sync callback\n");
34 }
35
36 return ret;
37 }
38
libdmabufheaptest(bool use_custom_callback)39 void libdmabufheaptest(bool use_custom_callback) {
40 const size_t len = 1024 * 1024;
41 int fd = -1, ret = 0;
42 size_t i = 0;
43 unsigned char* ptr = NULL;
44
45 BufferAllocator* bufferAllocator = CreateDmabufHeapBufferAllocator();
46 if (!bufferAllocator) {
47 printf("unable to get allocator\n");
48 return;
49 }
50
51 /*
52 * Legacy ion devices may have hardcoded heap IDs that do not
53 * match the ion UAPI header. Map heap name 'system' to a heap mask
54 * of all 1s so that these devices will allocate from the first
55 * available heap when asked to allocate from a heap of name 'system'.
56 */
57 ret = MapDmabufHeapNameToIonHeap(bufferAllocator, kDmabufSystemHeapName,
58 "" /* no mapping for non-legacy */,
59 0 /* no mapping for non-legacy ion */,
60 ~0 /* legacy ion heap mask */, 0 /* legacy ion heap flag */);
61 if (ret < 0) {
62 printf("MapDmabufHeapNameToIonHeap failed: %d\n", ret);
63 return;
64 }
65
66 fd = DmabufHeapAlloc(bufferAllocator, kDmabufSystemHeapName, len, 0);
67 if (fd < 0) {
68 printf("Alloc failed: %d\n", fd);
69 return;
70 }
71
72 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
73 if (ptr == MAP_FAILED) {
74 perror("mmap failed\n");
75 return;
76 }
77
78 ret = DmabufHeapCpuSyncStart(bufferAllocator, fd, kSyncReadWrite,
79 use_custom_callback ? legacy_ion_custom_callback : NULL);
80 if (ret) {
81 printf("DmabufHeapCpuSyncStart failed: %d\n", ret);
82 return;
83 }
84
85 for (i = 0; i < len; i++) {
86 ptr[i] = (unsigned char)i;
87 }
88 for (i = 0; i < len; i++) {
89 if (ptr[i] != (unsigned char)i) {
90 printf("%s failed wrote %zu read %d from mapped "
91 "memory\n",
92 __func__, i, ptr[i]);
93 return;
94 }
95 }
96
97 ret = DmabufHeapCpuSyncEnd(bufferAllocator, fd,
98 use_custom_callback ? legacy_ion_custom_callback : NULL);
99 if (ret) {
100 printf("DmabufHeapCpuSyncEnd failed: %d\n", ret);
101 return;
102 }
103
104 munmap(ptr, len);
105 close(fd);
106
107 FreeDmabufHeapBufferAllocator(bufferAllocator);
108 printf("PASSED\n");
109 }
110
main(int argc,char * argv[])111 int main(int argc, char* argv[]) {
112 (void)argc;
113 (void)argv;
114 printf("*****running with custom legacy ion cpu sync callback****\n");
115 libdmabufheaptest(true);
116 printf("****running without custom legacy ion cpu sync callback****\n");
117 libdmabufheaptest(false);
118 return 0;
119 }
120