static int init_workspace(workspace *w, size_t size)
{
    void *data;
    int fd;

    fd = ashmem_create_region("system_properties", size);
    if(fd < 0)
        return -1;

    data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(data == MAP_FAILED)
        goto out;

    /* allow the wolves we share with to do nothing but read */
    ashmem_set_prot_region(fd, PROT_READ);

    w->data = data;
    w->size = size;
    w->fd = fd;

    return 0;

out:
    close(fd);
    return -1;
}
static jint android_util_MemoryIntArray_create(JNIEnv* env, jobject clazz, jstring name,
        jint size)
{
    if (name == NULL) {
        jniThrowException(env, "java/io/IOException", "bad name");
        return -1;
    }

    if (size <= 0) {
        jniThrowException(env, "java/io/IOException", "bad size");
        return -1;
    }

    const char* nameStr = env->GetStringUTFChars(name, NULL);
    const int ashmemSize = sizeof(std::atomic_int) * size;
    int fd = ashmem_create_region(nameStr, ashmemSize);
    env->ReleaseStringUTFChars(name, nameStr);

    if (fd < 0) {
        jniThrowException(env, "java/io/IOException", "ashmem creation failed");
        return -1;
    }

    int setProtResult = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
    if (setProtResult < 0) {
        jniThrowException(env, "java/io/IOException", "cannot set ashmem prot mode");
        return -1;
    }

    return fd;
}
static int createAshmemRegionWithData(JNIEnv* env, const void* data, size_t length) {
    int error = 0;
    int fd = ashmem_create_region(NULL, length);
    if (fd < 0) {
        error = errno;
        ALOGE("ashmem_create_region failed: %s", strerror(error));
    } else {
        if (length > 0) {
            void* ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
            if (ptr == MAP_FAILED) {
                error = errno;
                ALOGE("mmap failed: %s", strerror(error));
            } else {
                memcpy(ptr, data, length);
                munmap(ptr, length);
            }
        }

        if (!error) {
            if (ashmem_set_prot_region(fd, PROT_READ) < 0) {
                error = errno;
                ALOGE("ashmem_set_prot_region failed: %s", strerror(errno));
            } else {
                return fd;
            }
        }

        close(fd);
    }

    jniThrowIOException(env, error);
    return -1;
}
Beispiel #4
0
status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {
    String8 ashmemName("CursorWindow: ");
    ashmemName.append(name);

    status_t result;
    int ashmemFd = ashmem_create_region(ashmemName.string(), size);
    if (ashmemFd < 0) {
    	ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, ashmem_create_region return errno = %d",errno);
        result = -errno;
    } else {
        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
        if (result >= 0) {
            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
            if (data == MAP_FAILED) {
            	ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, mmap return errno = %d",errno);
                result = -errno;
            } else {
                result = ashmem_set_prot_region(ashmemFd, PROT_READ);
                if (result >= 0) {
                    CursorWindow* window = new CursorWindow(name, ashmemFd,
                            data, size, false /*readOnly*/);
                    result = window->clear();
                    if (!result) {
                        LOG_WINDOW("Created new CursorWindow: freeOffset=%d, "
                                "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
                                window->mHeader->freeOffset,
                                window->mHeader->numRows,
                                window->mHeader->numColumns,
                                window->mSize, window->mData);
                        *outCursorWindow = window;
                        return OK;
                    }
                    ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, window->clear return errno = %d",errno);
                    delete window;
                } else {
                    ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, ashmeme_set_prot_region return errno = %d",errno);	
                }
            }
            ::munmap(data, size);
        }
        ::close(ashmemFd);
    }
    *outCursorWindow = NULL;
    return result;
}
Beispiel #5
0
int cras_shm_reopen_ro (const char *name, int fd)
{
	/* After mmaping the ashmem read/write, change it's protection
	   bits to disallow further write access. */
	if (ashmem_set_prot_region(fd, PROT_READ) != 0) {
		fd = -errno;
		syslog(LOG_ERR,
		       "failed to ashmem_set_prot_region %s: %s\n",
		       name, strerror(-fd));
	}
	return fd;
}
Beispiel #6
0
    virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) {
        const size_t size = roundToPageSize(bm->getSize());
        int fd = fRec->fFD;
        void* addr = fRec->fAddr;

        SkASSERT(!fRec->fPinned);

        if (-1 == fd) {
            SkASSERT(NULL == addr);
            SkASSERT(0 == fRec->fSize);

            fd = ashmem_create_region(fName, size);
#ifdef DUMP_ASHMEM_LIFECYCLE
            SkDebugf("=== ashmem_create_region %s size=%d fd=%d\n", fName, size, fd);
#endif
            if (-1 == fd) {
                SkDebugf("------- imageref_ashmem create failed <%s> %d\n",
                         fName, size);
                return false;
            }

            int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
            if (err) {
                SkDebugf("------ ashmem_set_prot_region(%d) failed %d\n",
                         fd, err);
                close(fd);
                return false;
            }

            addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
            if (-1 == (long)addr) {
                SkDebugf("---------- mmap failed for imageref_ashmem size=%d\n",
                         size);
                close(fd);
                return false;
            }

            fRec->fFD = fd;
            fRec->fAddr = addr;
            fRec->fSize = size;
        } else {
            SkASSERT(addr);
            SkASSERT(size == fRec->fSize);
            (void)ashmem_pin_region(fd, 0, 0);
        }

        bm->setPixels(addr, ct);
        fRec->fPinned = true;
        return true;
    }
Beispiel #7
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);
            }
        }
    }
}
get_ashmem(backing_store_ptr info, long total_bytes_needed)
{
  char path[1024];
  snprintf(path, 1023, "%d.tmp.ashmem", getpid());
  int fd = ashmem_create_region(path, total_bytes_needed);
  if (fd == -1) {
      return -1;
  }
  int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
  if (err) {
      return -1;
  }
  info->addr = mmap(NULL, total_bytes_needed, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
  info->size = total_bytes_needed;
  info->temp_file = fd;
  return fd;
}
Beispiel #9
0
int gpu_context_t::alloc_ashmem_buffer(size_t size, unsigned int postfix, void** pBase,
            int* pOffset, int* pFd)
{
    int err = 0;
    int fd = -1;
    void* base = 0;
    int offset = 0;

    char name[ASHMEM_NAME_LEN];
    snprintf(name, ASHMEM_NAME_LEN, "gralloc-buffer-%x", postfix);
    int prot = PROT_READ | PROT_WRITE;
    fd = ashmem_create_region(name, size);
    if (fd < 0) {
        LOGE("couldn't create ashmem (%s)", strerror(errno));
        err = -errno;
    } else {
        if (ashmem_set_prot_region(fd, prot) < 0) {
            LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
                 fd, prot, strerror(errno));
            close(fd);
            err = -errno;
        } else {
            base = mmap(0, size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0);
            if (base == MAP_FAILED) {
                LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
                     fd, size, prot, strerror(errno));
                close(fd);
                err = -errno;
            } else {
                memset((char*)base + offset, 0, size);
            }
        }
    }
    if(err == 0) {
        *pFd = fd;
        *pBase = base;
        *pOffset = offset;
#ifdef HOST
        if (ioctl(fd, ASHMEM_CACHE_INV_RANGE, NULL)) {
            LOGE("ASHMEM_CACHE_INV_RANGE failed fd = %d", fd);
        }
#endif
    }
    return err;
}
static jlong android_util_MemoryIntArray_open(JNIEnv* env, jobject clazz, jint fd,
    jboolean owner, jboolean writable)
{
    if (fd < 0) {
        jniThrowException(env, "java/io/IOException", "bad file descriptor");
        return -1;
    }

    int ashmemSize = ashmem_get_size_region(fd);
    if (ashmemSize <= 0) {
        jniThrowException(env, "java/io/IOException", "bad ashmem size");
        return -1;
    }

    int protMode = (owner || writable) ? (PROT_READ | PROT_WRITE) : PROT_READ;
    void* ashmemAddr = mmap(NULL, ashmemSize, protMode, MAP_SHARED, fd, 0);
    if (ashmemAddr == MAP_FAILED) {
        jniThrowException(env, "java/io/IOException", "cannot mmap ashmem");
        return -1;
    }

    if (owner) {
        int size = ashmemSize / sizeof(std::atomic_int);
        new (ashmemAddr) std::atomic_int[size];
    }

    if (owner && !writable) {
        int setProtResult = ashmem_set_prot_region(fd, PROT_READ);
        if (setProtResult < 0) {
            jniThrowException(env, "java/io/IOException", "cannot set ashmem prot mode");
            return -1;
        }
    }

    return reinterpret_cast<jlong>(ashmemAddr);
}
status_t InputChannel::openInputChannelPair(const String8& name,
        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
    status_t result;

    String8 ashmemName("InputChannel ");
    ashmemName.append(name);
    int serverAshmemFd = ashmem_create_region(ashmemName.string(), DEFAULT_MESSAGE_BUFFER_SIZE);
    if (serverAshmemFd < 0) {
        result = -errno;
        ALOGE("channel '%s' ~ Could not create shared memory region. errno=%d",
                name.string(), errno);
    } else {
        result = ashmem_set_prot_region(serverAshmemFd, PROT_READ | PROT_WRITE);
        if (result < 0) {
            ALOGE("channel '%s' ~ Error %d trying to set protection of ashmem fd %d.",
                    name.string(), result, serverAshmemFd);
        } else {
            // Dup the file descriptor because the server and client input channel objects that
            // are returned may have different lifetimes but they share the same shared memory region.
            int clientAshmemFd;
            clientAshmemFd = dup(serverAshmemFd);
            if (clientAshmemFd < 0) {
                result = -errno;
                ALOGE("channel '%s' ~ Could not dup() shared memory region fd. errno=%d",
                        name.string(), errno);
            } else {
                int forward[2];
                if (pipe(forward)) {
                    result = -errno;
                    ALOGE("channel '%s' ~ Could not create forward pipe.  errno=%d",
                            name.string(), errno);
                } else {
                    int reverse[2];
                    if (pipe(reverse)) {
                        result = -errno;
                        ALOGE("channel '%s' ~ Could not create reverse pipe.  errno=%d",
                                name.string(), errno);
                    } else {
                        String8 serverChannelName = name;
                        serverChannelName.append(" (server)");
                        outServerChannel = new InputChannel(serverChannelName,
                                serverAshmemFd, reverse[0], forward[1]);

                        String8 clientChannelName = name;
                        clientChannelName.append(" (client)");
                        outClientChannel = new InputChannel(clientChannelName,
                                clientAshmemFd, forward[0], reverse[1]);
                        return OK;
                    }
                    ::close(forward[0]);
                    ::close(forward[1]);
                }
                ::close(clientAshmemFd);
            }
        }
        ::close(serverAshmemFd);
    }

    outServerChannel.clear();
    outClientChannel.clear();
    return result;
}