123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define LOG_TAG "MemoryHeapBase"
- #include <stdlib.h>
- #include <stdint.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/ioctl.h>
- #include <cutils/log.h>
- #include <cutils/ashmem.h>
- #include <cutils/atomic.h>
- #include <binder/MemoryHeapBase.h>
- namespace android {
- // ---------------------------------------------------------------------------
- MemoryHeapBase::MemoryHeapBase()
- : mFD(-1), mSize(0), mBase(MAP_FAILED),
- mDevice(NULL), mNeedUnmap(false), mOffset(0)
- {
- }
- MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false), mOffset(0)
- {
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
- ALOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
- if (fd >= 0) {
- if (mapfd(fd, size) == NO_ERROR) {
- if (flags & READ_ONLY) {
- ashmem_set_prot_region(fd, PROT_READ);
- }
- }
- }
- }
- MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false), mOffset(0)
- {
- int open_flags = O_RDWR;
- if (flags & NO_CACHING)
- open_flags |= O_SYNC;
- int fd = open(device, open_flags);
- ALOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
- if (fd >= 0) {
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- if (mapfd(fd, size) == NO_ERROR) {
- mDevice = device;
- }
- }
- }
- MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags, uint32_t offset)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false), mOffset(0)
- {
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- mapfd(dup(fd), size, offset);
- }
- status_t MemoryHeapBase::init(int fd, void *base, int size, int flags, const char* device)
- {
- if (mFD != -1) {
- return INVALID_OPERATION;
- }
- mFD = fd;
- mBase = base;
- mSize = size;
- mFlags = flags;
- mDevice = device;
- return NO_ERROR;
- }
- status_t MemoryHeapBase::mapfd(int fd, size_t size, uint32_t offset)
- {
- if (size == 0) {
- // try to figure out the size automatically
- struct stat sb;
- if (fstat(fd, &sb) == 0)
- size = sb.st_size;
- // if it didn't work, let mmap() fail.
- }
- if ((mFlags & DONT_MAP_LOCALLY) == 0) {
- void* base = (uint8_t*)mmap(0, size,
- PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
- if (base == MAP_FAILED) {
- ALOGE("mmap(fd=%d, size=%u) failed (%s)",
- fd, uint32_t(size), strerror(errno));
- close(fd);
- return -errno;
- }
- //ALOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
- mBase = base;
- mNeedUnmap = true;
- } else {
- mBase = 0; // not MAP_FAILED
- mNeedUnmap = false;
- }
- mFD = fd;
- mSize = size;
- mOffset = offset;
- return NO_ERROR;
- }
- MemoryHeapBase::~MemoryHeapBase()
- {
- dispose();
- }
- void MemoryHeapBase::dispose()
- {
- int fd = android_atomic_or(-1, &mFD);
- if (fd >= 0) {
- if (mNeedUnmap) {
- //ALOGD("munmap(fd=%d, base=%p, size=%lu)", fd, mBase, mSize);
- munmap(mBase, mSize);
- }
- mBase = 0;
- mSize = 0;
- close(fd);
- }
- }
- int MemoryHeapBase::getHeapID() const {
- return mFD;
- }
- void* MemoryHeapBase::getBase() const {
- return mBase;
- }
- size_t MemoryHeapBase::getSize() const {
- return mSize;
- }
- uint32_t MemoryHeapBase::getFlags() const {
- return mFlags;
- }
- const char* MemoryHeapBase::getDevice() const {
- return mDevice;
- }
- uint32_t MemoryHeapBase::getOffset() const {
- return mOffset;
- }
- // ---------------------------------------------------------------------------
- }; // namespace android
|