134781b253083703502a7874df3619196bc7106cdJohn Reck/*
234781b253083703502a7874df3619196bc7106cdJohn Reck * Copyright (C) 2017 The Android Open Source Project
334781b253083703502a7874df3619196bc7106cdJohn Reck *
434781b253083703502a7874df3619196bc7106cdJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
534781b253083703502a7874df3619196bc7106cdJohn Reck * you may not use this file except in compliance with the License.
634781b253083703502a7874df3619196bc7106cdJohn Reck * You may obtain a copy of the License at
734781b253083703502a7874df3619196bc7106cdJohn Reck *
834781b253083703502a7874df3619196bc7106cdJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
934781b253083703502a7874df3619196bc7106cdJohn Reck *
1034781b253083703502a7874df3619196bc7106cdJohn Reck * Unless required by applicable law or agreed to in writing, software
1134781b253083703502a7874df3619196bc7106cdJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
1234781b253083703502a7874df3619196bc7106cdJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1334781b253083703502a7874df3619196bc7106cdJohn Reck * See the License for the specific language governing permissions and
1434781b253083703502a7874df3619196bc7106cdJohn Reck * limitations under the License.
1534781b253083703502a7874df3619196bc7106cdJohn Reck */
1634781b253083703502a7874df3619196bc7106cdJohn Reck
1734781b253083703502a7874df3619196bc7106cdJohn Reck#include "ProfileDataContainer.h"
1834781b253083703502a7874df3619196bc7106cdJohn Reck
1934781b253083703502a7874df3619196bc7106cdJohn Reck#include <log/log.h>
2034781b253083703502a7874df3619196bc7106cdJohn Reck#include <cutils/ashmem.h>
2134781b253083703502a7874df3619196bc7106cdJohn Reck
2234781b253083703502a7874df3619196bc7106cdJohn Reck#include <sys/mman.h>
2334781b253083703502a7874df3619196bc7106cdJohn Reck
2434781b253083703502a7874df3619196bc7106cdJohn Recknamespace android {
2534781b253083703502a7874df3619196bc7106cdJohn Recknamespace uirenderer {
2634781b253083703502a7874df3619196bc7106cdJohn Reck
2734781b253083703502a7874df3619196bc7106cdJohn Reckvoid ProfileDataContainer::freeData() {
2834781b253083703502a7874df3619196bc7106cdJohn Reck    if (mIsMapped) {
2934781b253083703502a7874df3619196bc7106cdJohn Reck        munmap(mData, sizeof(ProfileData));
3034781b253083703502a7874df3619196bc7106cdJohn Reck    } else {
3134781b253083703502a7874df3619196bc7106cdJohn Reck        delete mData;
3234781b253083703502a7874df3619196bc7106cdJohn Reck    }
3334781b253083703502a7874df3619196bc7106cdJohn Reck    mIsMapped = false;
3434781b253083703502a7874df3619196bc7106cdJohn Reck    mData = nullptr;
3534781b253083703502a7874df3619196bc7106cdJohn Reck}
3634781b253083703502a7874df3619196bc7106cdJohn Reck
3734781b253083703502a7874df3619196bc7106cdJohn Reckvoid ProfileDataContainer::rotateStorage() {
3834781b253083703502a7874df3619196bc7106cdJohn Reck    // If we are mapped we want to stop using the ashmem backend and switch to malloc
3934781b253083703502a7874df3619196bc7106cdJohn Reck    // We are expecting a switchStorageToAshmem call to follow this, but it's not guaranteed
4034781b253083703502a7874df3619196bc7106cdJohn Reck    // If we aren't sitting on top of ashmem then just do a reset() as it's functionally
4134781b253083703502a7874df3619196bc7106cdJohn Reck    // equivalent do a free, malloc, reset.
4234781b253083703502a7874df3619196bc7106cdJohn Reck    if (mIsMapped) {
4334781b253083703502a7874df3619196bc7106cdJohn Reck        freeData();
4434781b253083703502a7874df3619196bc7106cdJohn Reck        mData = new ProfileData;
4534781b253083703502a7874df3619196bc7106cdJohn Reck    }
4634781b253083703502a7874df3619196bc7106cdJohn Reck    mData->reset();
4734781b253083703502a7874df3619196bc7106cdJohn Reck}
4834781b253083703502a7874df3619196bc7106cdJohn Reck
4934781b253083703502a7874df3619196bc7106cdJohn Reckvoid ProfileDataContainer::switchStorageToAshmem(int ashmemfd) {
5034781b253083703502a7874df3619196bc7106cdJohn Reck    int regionSize = ashmem_get_size_region(ashmemfd);
5134781b253083703502a7874df3619196bc7106cdJohn Reck    if (regionSize < 0) {
5234781b253083703502a7874df3619196bc7106cdJohn Reck        int err = errno;
5334781b253083703502a7874df3619196bc7106cdJohn Reck        ALOGW("Failed to get ashmem region size from fd %d, err %d %s", ashmemfd, err, strerror(err));
5434781b253083703502a7874df3619196bc7106cdJohn Reck        return;
5534781b253083703502a7874df3619196bc7106cdJohn Reck    }
5634781b253083703502a7874df3619196bc7106cdJohn Reck    if (regionSize < static_cast<int>(sizeof(ProfileData))) {
5734781b253083703502a7874df3619196bc7106cdJohn Reck        ALOGW("Ashmem region is too small! Received %d, required %u",
5834781b253083703502a7874df3619196bc7106cdJohn Reck                regionSize, static_cast<unsigned int>(sizeof(ProfileData)));
5934781b253083703502a7874df3619196bc7106cdJohn Reck        return;
6034781b253083703502a7874df3619196bc7106cdJohn Reck    }
6134781b253083703502a7874df3619196bc7106cdJohn Reck    ProfileData* newData = reinterpret_cast<ProfileData*>(
6234781b253083703502a7874df3619196bc7106cdJohn Reck            mmap(NULL, sizeof(ProfileData), PROT_READ | PROT_WRITE,
6334781b253083703502a7874df3619196bc7106cdJohn Reck                    MAP_SHARED, ashmemfd, 0));
6434781b253083703502a7874df3619196bc7106cdJohn Reck    if (newData == MAP_FAILED) {
6534781b253083703502a7874df3619196bc7106cdJohn Reck        int err = errno;
6634781b253083703502a7874df3619196bc7106cdJohn Reck        ALOGW("Failed to move profile data to ashmem fd %d, error = %d",
6734781b253083703502a7874df3619196bc7106cdJohn Reck                ashmemfd, err);
6834781b253083703502a7874df3619196bc7106cdJohn Reck        return;
6934781b253083703502a7874df3619196bc7106cdJohn Reck    }
7034781b253083703502a7874df3619196bc7106cdJohn Reck
7134781b253083703502a7874df3619196bc7106cdJohn Reck    newData->mergeWith(*mData);
7234781b253083703502a7874df3619196bc7106cdJohn Reck    freeData();
7334781b253083703502a7874df3619196bc7106cdJohn Reck    mData = newData;
7434781b253083703502a7874df3619196bc7106cdJohn Reck    mIsMapped = true;
7534781b253083703502a7874df3619196bc7106cdJohn Reck}
7634781b253083703502a7874df3619196bc7106cdJohn Reck
7734781b253083703502a7874df3619196bc7106cdJohn Reck} /* namespace uirenderer */
7834781b253083703502a7874df3619196bc7106cdJohn Reck} /* namespace android */