/* * Copyright (C) 2010 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. */ #ifndef GRALLOC_QSD8K_PMEMALLOC_H #define GRALLOC_QSD8K_PMEMALLOC_H #include <limits.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> /** * An interface to the PMEM allocators. */ class PmemAllocator { public: virtual ~PmemAllocator(); // Only valid after init_pmem_area() has completed successfully. virtual void* get_base_address() = 0; virtual int alloc_pmem_buffer(size_t size, int usage, void** pBase, int* pOffset, int* pFd) = 0; virtual int free_pmem_buffer(size_t size, void* base, int offset, int fd) = 0; }; /** * A PMEM allocator that allocates the entire pmem memory from the kernel and * then uses a user-space allocator to suballocate from that. This requires * that the PMEM device driver have kernel allocation disabled. */ class PmemUserspaceAllocator: public PmemAllocator { public: class Deps { public: class Allocator { public: virtual ~Allocator(); virtual ssize_t setSize(size_t size) = 0; virtual size_t size() const = 0; virtual ssize_t allocate(size_t size, uint32_t flags = 0) = 0; virtual ssize_t deallocate(size_t offset) = 0; }; virtual ~Deps(); // pmem virtual size_t getPmemTotalSize(int fd, size_t* size) = 0; virtual int connectPmem(int fd, int master_fd) = 0; virtual int mapPmem(int fd, int offset, size_t size) = 0; virtual int unmapPmem(int fd, int offset, size_t size) = 0; // C99 virtual int getErrno() = 0; // POSIX virtual void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset) = 0; virtual int open(const char* pathname, int flags, int mode) = 0; virtual int close(int fd) = 0; }; PmemUserspaceAllocator(Deps& deps, Deps::Allocator& allocator, const char* pmemdev); virtual ~PmemUserspaceAllocator(); // Only valid after init_pmem_area() has completed successfully. virtual void* get_base_address(); virtual int init_pmem_area_locked(); virtual int init_pmem_area(); virtual int alloc_pmem_buffer(size_t size, int usage, void** pBase, int* pOffset, int* pFd); virtual int free_pmem_buffer(size_t size, void* base, int offset, int fd); #ifndef ANDROID_OS // DO NOT USE: For testing purposes only. void set_master_values(int fd, void* base) { master_fd = fd; master_base = base; } #endif // ANDROID_OS private: enum { MASTER_FD_INIT = -1, }; Deps& deps; Deps::Allocator& allocator; pthread_mutex_t lock; const char* pmemdev; int master_fd; void* master_base; }; /** * A PMEM allocator that allocates each individual allocation from the kernel * (using the kernel's allocator). This requires the kernel driver for the * particular PMEM device being allocated from to support kernel allocation. */ class PmemKernelAllocator: public PmemAllocator { public: class Deps { public: virtual ~Deps(); // C99 virtual int getErrno() = 0; // POSIX virtual void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset) = 0; virtual int munmap(void* start, size_t length) = 0; virtual int open(const char* pathname, int flags, int mode) = 0; virtual int close(int fd) = 0; }; PmemKernelAllocator(Deps& deps, const char* pmemdev); virtual ~PmemKernelAllocator(); // Only valid after init_pmem_area() has completed successfully. virtual void* get_base_address(); virtual int alloc_pmem_buffer(size_t size, int usage, void** pBase, int* pOffset, int* pFd); virtual int free_pmem_buffer(size_t size, void* base, int offset, int fd); private: Deps& deps; const char* pmemdev; }; #endif // GRALLOC_QSD8K_PMEMALLOC_H