1363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/* 2363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Copyright 2008 The Android Open Source Project 3363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * 4363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 5363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * found in the LICENSE file. 6363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */ 7363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 8363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/* 9363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Implementation of the user-space ashmem API for devices, which have our 10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version, 11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * used by the simulator. 12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */ 13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <android/ashmem.h> 15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <unistd.h> 17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <string.h> 18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <sys/types.h> 19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <sys/stat.h> 20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <sys/ioctl.h> 21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <fcntl.h> 22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <linux/ashmem.h> 24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 25363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#define ASHMEM_DEVICE "/dev/ashmem" 26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/* 28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * ashmem_create_region - creates a new ashmem region and returns the file 29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * descriptor, or <0 on error 30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * 31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * `name' is an optional label to give the region (visible in /proc/pid/maps) 32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * `size' is the size of the region, in page-aligned bytes 33363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */ 34363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_create_region(const char *name, size_t size) 35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{ 36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int fd, ret; 37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fd = open(ASHMEM_DEVICE, O_RDWR); 39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fd < 0) 40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fd; 41363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (name) { 43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger char buf[ASHMEM_NAME_LEN]; 44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 45363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger strlcpy(buf, name, sizeof(buf)); 46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger ret = ioctl(fd, ASHMEM_SET_NAME, buf); 47363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (ret < 0) 48363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger goto error; 49363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger ret = ioctl(fd, ASHMEM_SET_SIZE, size); 52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (ret < 0) 53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger goto error; 54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 55363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fd; 56363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergererror: 58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger close(fd); 59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return ret; 60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 61363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_set_prot_region(int fd, int prot) 63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{ 64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return ioctl(fd, ASHMEM_SET_PROT_MASK, prot); 65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_pin_region(int fd, size_t offset, size_t len) 68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{ 69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger struct ashmem_pin pin = { offset, len }; 70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return ioctl(fd, ASHMEM_PIN, &pin); 71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 72363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 73363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_unpin_region(int fd, size_t offset, size_t len) 74363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{ 75363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger struct ashmem_pin pin = { offset, len }; 76363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return ioctl(fd, ASHMEM_UNPIN, &pin); 77363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 78363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 79363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_get_size_region(int fd) 80363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{ 81363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return ioctl(fd, ASHMEM_GET_SIZE, NULL); 82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 83096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 84096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerint ashmem_purge_all_caches(int fd) 85096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger{ 86096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return ioctl(fd, ASHMEM_PURGE_ALL_CACHES, NULL); 87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 88