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