Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2017 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 #define LOG_TAG "Memory"
     18 
     19 #include "Memory.h"
     20 
     21 #include "HalInterfaces.h"
     22 #include "Utils.h"
     23 
     24 namespace android {
     25 namespace nn {
     26 
     27 int Memory::create(uint32_t size) {
     28     mHidlMemory = allocateSharedMemory(size);
     29     mMemory = mapMemory(mHidlMemory);
     30     if (mMemory == nullptr) {
     31         LOG(ERROR) << "Memory::create failed";
     32         return ANEURALNETWORKS_OP_FAILED;
     33     }
     34     return ANEURALNETWORKS_NO_ERROR;
     35 }
     36 
     37 bool Memory::validateSize(uint32_t offset, uint32_t length) const {
     38     if (offset + length > mHidlMemory.size()) {
     39         LOG(ERROR) << "Request size larger than the memory size.";
     40         return false;
     41     } else {
     42         return true;
     43     }
     44 }
     45 
     46 MemoryFd::~MemoryFd() {
     47     // Delete the native_handle.
     48     if (mHandle) {
     49         int fd = mHandle->data[0];
     50         if (fd != -1) {
     51             close(fd);
     52         }
     53         native_handle_delete(mHandle);
     54     }
     55 }
     56 
     57 int MemoryFd::set(size_t size, int prot, int fd, size_t offset) {
     58     if (fd < 0) {
     59         LOG(ERROR) << "ANeuralNetworksMemory_createFromFd invalid fd " << fd;
     60         return ANEURALNETWORKS_UNEXPECTED_NULL;
     61     }
     62     if (size == 0 || fd < 0) {
     63         LOG(ERROR) << "Invalid size or fd";
     64         return ANEURALNETWORKS_BAD_DATA;
     65     }
     66     int dupfd = dup(fd);
     67     if (dupfd == -1) {
     68         LOG(ERROR) << "Failed to dup the fd";
     69         return ANEURALNETWORKS_UNEXPECTED_NULL;
     70     }
     71 
     72     if (mHandle) {
     73         native_handle_delete(mHandle);
     74     }
     75     mHandle = native_handle_create(1, 3);
     76     if (mHandle == nullptr) {
     77         LOG(ERROR) << "Failed to create native_handle";
     78         return ANEURALNETWORKS_UNEXPECTED_NULL;
     79     }
     80     mHandle->data[0] = dupfd;
     81     mHandle->data[1] = prot;
     82     mHandle->data[2] = (int32_t)(uint32_t)(offset & 0xffffffff);
     83 #if defined(__LP64__)
     84     mHandle->data[3] = (int32_t)(uint32_t)(offset >> 32);
     85 #else
     86     mHandle->data[3] = 0;
     87 #endif
     88     mHidlMemory = hidl_memory("mmap_fd", mHandle, size);
     89     return ANEURALNETWORKS_NO_ERROR;
     90 }
     91 
     92 int MemoryFd::getPointer(uint8_t** buffer) const {
     93     if (mHandle == nullptr) {
     94         LOG(ERROR) << "Memory not initialized";
     95         return ANEURALNETWORKS_UNEXPECTED_NULL;
     96     }
     97 
     98     int fd = mHandle->data[0];
     99     int prot = mHandle->data[1];
    100     size_t offset = getSizeFromInts(mHandle->data[2], mHandle->data[3]);
    101     void* data = mmap(nullptr, mHidlMemory.size(), prot, MAP_SHARED, fd, offset);
    102     if (data == MAP_FAILED) {
    103         LOG(ERROR) << "Can't mmap the file descriptor.";
    104         return ANEURALNETWORKS_UNMAPPABLE;
    105     } else {
    106         *buffer = static_cast<uint8_t*>(data);
    107         return ANEURALNETWORKS_NO_ERROR;
    108     }
    109 }
    110 
    111 uint32_t MemoryTracker::add(const Memory* memory) {
    112     VLOG(MODEL) << __func__ << " for " << memory;
    113     // See if we already have this memory. If so,
    114     // return its index.
    115     auto i = mKnown.find(memory);
    116     if (i != mKnown.end()) {
    117         return i->second;
    118     }
    119     VLOG(MODEL) << "It's new";
    120     // It's a new one.  Save it an assign an index to it.
    121     size_t next = mKnown.size();
    122     if (next > 0xFFFFFFFF) {
    123         LOG(ERROR) << "ANeuralNetworks more than 2^32 memories.";
    124         return ANEURALNETWORKS_BAD_DATA;
    125     }
    126     uint32_t idx = static_cast<uint32_t>(next);
    127     mKnown[memory] = idx;
    128     mMemories.push_back(memory);
    129     return idx;
    130 }
    131 
    132 } // namespace nn
    133 } // namespace android
    134