Ashmem anonymous shared memory runtime library cutil

Ashmem anonymous shared memory driver

 

Introduction

    It has been said that the ashmem system is divided into three levels, and this article will analyze the implementation in the cutils library.

    The cutils library accesses the driver through the file access operation open, ioctl. In addition, cutils provides five C interfaces to access the driver, ashmem_create_region, ashmen_pin_region, ashmem_unpin_region, ashmem_set_prot_region, ashmem_get_size_region.

The implementation of the cutils     library layer is located at /system/core/libcutils/ashmem-dev.c

 

ashmem_create_region

    This method is used to request the ashmem driver to create a piece of anonymous shared memory for the application and put back its file descriptor.

int ashmem_create_region(const char *name, size_t size)
{
    int ret, save_errno;

    int fd = __ashmem_open();
    if (fd < 0) {
        return fd;
    }

    if (name) {
        char buf[ASHMEM_NAME_LEN] = {0};

        strlcpy(buf, name, sizeof(buf));
        ret = TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_NAME, buf));
        if (ret < 0) {
            goto error;
        }
    }

    ret = TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_SIZE, size));
    if (ret < 0) {
        goto error;
    }

    return fd;

error:
    save_errno = errno;
    close(fd);
    errno = save_errno;
    return ret;
}

    name and size represent the name and size of anonymous shared memory, respectively.

    This place is somewhat different from version 2.3. In version 2.3, we directly use the open function to open the driver file /dev/ashmem. This establishes a relationship with the driver. However, in 8.0, the __ashmem_open method is used to open the driver file (actually the same operation, but with more synchronization locks, retry and exception handling.)

    In the driver explanation, we know that when we call the open function, ashmem_open will be called to create an ashmem_area structure to represent an anonymous shared memory.

    Then use ASHMEM_SET_NAME to set the name through the ioctl command, and use ASHMEM_SET_SIZE to set the size.

ashmem_pin_region

    This method is relatively simple

int ashmem_pin_region(int fd, size_t offset, size_t len)
{
    struct ashmem_pin pin = { offset, len };

    //2.3中不存在,可能会导致错误和被入侵风险,所以此处添加了对fd的类型验证,确保是匿名共享内存的文件描述符
    int ret = __ashmem_is_ashmem(fd, 1);
    if (ret < 0) {
        return ret;
    }

    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin));
}

    Send the io control command ASHMEM_PIN to the file described by fd to lock a small memory area. offset represents the offset position in anonymous memory, and len represents the length.

    

ashmem_unpin_region

int ashmem_unpin_region(int fd, size_t offset, size_t len)
{
    struct ashmem_pin pin = { offset, len };

    int ret = __ashmem_is_ashmem(fd, 1);
    if (ret < 0) {
        return ret;
    }

    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin));
}

    It is basically the same as ashmem_pin_region, except that the ASHMEM_UNPIN command is sent to unlock a memory region.

ashmem_set_prot_region

int ashmem_set_prot_region(int fd, int prot)
{
    int ret = __ashmem_is_ashmem(fd, 1);
    if (ret < 0) {
        return ret;
    }

    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot));
}

    This method is only used to set the access protection bit of anonymous shared memory.

ashmem_get_size_region

    Used to get anonymous shared memory size.

int ashmem_get_size_region(int fd)
{
    int ret = __ashmem_is_ashmem(fd, 1);
    if (ret < 0) {
        return ret;
    }

    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL));
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324955376&siteId=291194637