ProfileDataContainer.cpp revision 34781b253083703502a7874df3619196bc7106cd
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#include "ProfileDataContainer.h" 18 19#include <log/log.h> 20#include <cutils/ashmem.h> 21 22#include <sys/mman.h> 23 24namespace android { 25namespace uirenderer { 26 27void ProfileDataContainer::freeData() { 28 if (mIsMapped) { 29 munmap(mData, sizeof(ProfileData)); 30 } else { 31 delete mData; 32 } 33 mIsMapped = false; 34 mData = nullptr; 35} 36 37void ProfileDataContainer::rotateStorage() { 38 // If we are mapped we want to stop using the ashmem backend and switch to malloc 39 // We are expecting a switchStorageToAshmem call to follow this, but it's not guaranteed 40 // If we aren't sitting on top of ashmem then just do a reset() as it's functionally 41 // equivalent do a free, malloc, reset. 42 if (mIsMapped) { 43 freeData(); 44 mData = new ProfileData; 45 } 46 mData->reset(); 47} 48 49void ProfileDataContainer::switchStorageToAshmem(int ashmemfd) { 50 int regionSize = ashmem_get_size_region(ashmemfd); 51 if (regionSize < 0) { 52 int err = errno; 53 ALOGW("Failed to get ashmem region size from fd %d, err %d %s", ashmemfd, err, strerror(err)); 54 return; 55 } 56 if (regionSize < static_cast<int>(sizeof(ProfileData))) { 57 ALOGW("Ashmem region is too small! Received %d, required %u", 58 regionSize, static_cast<unsigned int>(sizeof(ProfileData))); 59 return; 60 } 61 ProfileData* newData = reinterpret_cast<ProfileData*>( 62 mmap(NULL, sizeof(ProfileData), PROT_READ | PROT_WRITE, 63 MAP_SHARED, ashmemfd, 0)); 64 if (newData == MAP_FAILED) { 65 int err = errno; 66 ALOGW("Failed to move profile data to ashmem fd %d, error = %d", 67 ashmemfd, err); 68 return; 69 } 70 71 newData->mergeWith(*mData); 72 freeData(); 73 mData = newData; 74 mIsMapped = true; 75} 76 77} /* namespace uirenderer */ 78} /* namespace android */