18b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet/* 28b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * Copyright (C) 2017 The Android Open Source Project 38b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * 48b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * Licensed under the Apache License, Version 2.0 (the "License"); 58b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * you may not use this file except in compliance with the License. 68b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * You may obtain a copy of the License at 78b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * 88b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * http://www.apache.org/licenses/LICENSE-2.0 98b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * 108b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * Unless required by applicable law or agreed to in writing, software 118b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * distributed under the License is distributed on an "AS IS" BASIS, 128b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * See the License for the specific language governing permissions and 148b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * limitations under the License. 158b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet */ 168b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 178b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#define LOG_TAG "Memory" 188b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 198b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#include "Memory.h" 208b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 218b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#include "HalInterfaces.h" 228b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#include "Utils.h" 238b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 248b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletnamespace android { 258b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletnamespace nn { 268b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 278b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletint Memory::create(uint32_t size) { 288b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet mHidlMemory = allocateSharedMemory(size); 298b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet mMemory = mapMemory(mHidlMemory); 308b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet if (mMemory == nullptr) { 318b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet LOG(ERROR) << "Memory::create failed"; 32a144106df8f9b82251a5e584b1b083fb39d33b88Przemyslaw Szczepaniak return ANEURALNETWORKS_OUT_OF_MEMORY; 338b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet } 348b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet return ANEURALNETWORKS_NO_ERROR; 358b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet} 368b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 37e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouilletbool Memory::validateSize(uint32_t offset, uint32_t length) const { 38e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (offset + length > mHidlMemory.size()) { 39e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet LOG(ERROR) << "Request size larger than the memory size."; 40e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return false; 41e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } else { 42e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return true; 43e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 44e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet} 45e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet 46e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc BrouilletMemoryFd::~MemoryFd() { 47fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross // Unmap the memory. 48fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross if (mMapping) { 49fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross munmap(mMapping, mHidlMemory.size()); 50fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross } 51e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet // Delete the native_handle. 52e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (mHandle) { 53e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet int fd = mHandle->data[0]; 54e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (fd != -1) { 55e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet close(fd); 56e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 57e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet native_handle_delete(mHandle); 58e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 59e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet} 60e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet 61e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouilletint MemoryFd::set(size_t size, int prot, int fd, size_t offset) { 62e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (fd < 0) { 63e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet LOG(ERROR) << "ANeuralNetworksMemory_createFromFd invalid fd " << fd; 64e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_UNEXPECTED_NULL; 65e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 66e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (size == 0 || fd < 0) { 67e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet LOG(ERROR) << "Invalid size or fd"; 68e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_BAD_DATA; 69e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 70e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet int dupfd = dup(fd); 71e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (dupfd == -1) { 72e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet LOG(ERROR) << "Failed to dup the fd"; 73e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_UNEXPECTED_NULL; 74e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 75e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet 76fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross if (mMapping) { 77fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross if (munmap(mMapping, mHidlMemory.size()) != 0) { 78fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross LOG(ERROR) << "Failed to remove the existing mapping"; 79fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross // This is not actually fatal. 80fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross } 81fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross mMapping = nullptr; 82fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross } 83e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (mHandle) { 84e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet native_handle_delete(mHandle); 85e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 86e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet mHandle = native_handle_create(1, 3); 87e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (mHandle == nullptr) { 88e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet LOG(ERROR) << "Failed to create native_handle"; 89e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_UNEXPECTED_NULL; 90e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 91e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet mHandle->data[0] = dupfd; 92e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet mHandle->data[1] = prot; 93e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet mHandle->data[2] = (int32_t)(uint32_t)(offset & 0xffffffff); 94e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet#if defined(__LP64__) 95e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet mHandle->data[3] = (int32_t)(uint32_t)(offset >> 32); 96e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet#else 97e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet mHandle->data[3] = 0; 98e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet#endif 99e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet mHidlMemory = hidl_memory("mmap_fd", mHandle, size); 100e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_NO_ERROR; 101e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet} 102e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet 103e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouilletint MemoryFd::getPointer(uint8_t** buffer) const { 104fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross if (mMapping) { 105fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross *buffer = mMapping; 106fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross return ANEURALNETWORKS_NO_ERROR; 107fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross } 108fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross 109e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (mHandle == nullptr) { 110e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet LOG(ERROR) << "Memory not initialized"; 111e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_UNEXPECTED_NULL; 112e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 113e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet 114e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet int fd = mHandle->data[0]; 115e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet int prot = mHandle->data[1]; 116e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet size_t offset = getSizeFromInts(mHandle->data[2], mHandle->data[3]); 117e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet void* data = mmap(nullptr, mHidlMemory.size(), prot, MAP_SHARED, fd, offset); 118e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (data == MAP_FAILED) { 11906b5a0a85abe10b618a3a5ed023ac5c74678647eDavid Gross LOG(ERROR) << "MemoryFd::getPointer(): Can't mmap the file descriptor."; 120e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_UNMAPPABLE; 121e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } else { 122fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross mMapping = *buffer = static_cast<uint8_t*>(data); 123e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_NO_ERROR; 124e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 125e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet} 126e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet 1278b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletuint32_t MemoryTracker::add(const Memory* memory) { 12864031fa26110e6d57896bfdbe1cd58e69cde3dbbMiao Wang VLOG(MODEL) << __func__ << "(" << SHOW_IF_DEBUG(memory) << ")"; 1298b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // See if we already have this memory. If so, 1308b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // return its index. 1318b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet auto i = mKnown.find(memory); 1328b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet if (i != mKnown.end()) { 1338b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet return i->second; 1348b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet } 1351da8fed77c5c296afa18f754ec3616e7f02a4cfdJean-Luc Brouillet VLOG(MODEL) << "It's new"; 1368b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // It's a new one. Save it an assign an index to it. 1378b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet size_t next = mKnown.size(); 1388b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet if (next > 0xFFFFFFFF) { 1398b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet LOG(ERROR) << "ANeuralNetworks more than 2^32 memories."; 1408b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet return ANEURALNETWORKS_BAD_DATA; 1418b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet } 1428b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet uint32_t idx = static_cast<uint32_t>(next); 1438b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet mKnown[memory] = idx; 1448b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet mMemories.push_back(memory); 1458b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet return idx; 1468b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet} 1478b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 1488b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet} // namespace nn 1498b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet} // namespace android 150