no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / memory / volatile / VolatileBufferAshmem.cpp
blob99a0d1307fb0363b500ef03d8f51225463804117
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "VolatileBuffer.h"
6 #include "mozilla/Assertions.h"
7 #include "mozilla/mozalloc.h"
9 #include <fcntl.h>
10 #include <sys/mman.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
15 #include "mozilla/Ashmem.h"
17 #ifdef MOZ_MEMORY
18 extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size);
19 #endif
21 #define MIN_VOLATILE_ALLOC_SIZE 8192
23 namespace mozilla {
25 VolatileBuffer::VolatileBuffer()
26 : mMutex("VolatileBuffer"),
27 mBuf(nullptr),
28 mSize(0),
29 mLockCount(0),
30 mFd(-1) {}
32 bool VolatileBuffer::Init(size_t aSize, size_t aAlignment) {
33 MOZ_ASSERT(!mSize && !mBuf, "Init called twice");
34 MOZ_ASSERT(!(aAlignment % sizeof(void*)),
35 "Alignment must be multiple of pointer size");
37 mSize = aSize;
38 if (aSize < MIN_VOLATILE_ALLOC_SIZE) {
39 goto heap_alloc;
42 mFd = mozilla::android::ashmem_create(nullptr, mSize);
43 if (mFd < 0) {
44 goto heap_alloc;
47 mBuf = mmap(nullptr, mSize, PROT_READ | PROT_WRITE, MAP_SHARED, mFd, 0);
48 if (mBuf != MAP_FAILED) {
49 return true;
52 heap_alloc:
53 mBuf = nullptr;
54 if (mFd >= 0) {
55 close(mFd);
56 mFd = -1;
59 #ifdef MOZ_MEMORY
60 posix_memalign(&mBuf, aAlignment, aSize);
61 #else
62 mBuf = memalign(aAlignment, aSize);
63 #endif
64 return !!mBuf;
67 VolatileBuffer::~VolatileBuffer() {
68 MOZ_ASSERT(mLockCount == 0, "Being destroyed with non-zero lock count?");
70 if (OnHeap()) {
71 free(mBuf);
72 } else {
73 munmap(mBuf, mSize);
74 close(mFd);
78 bool VolatileBuffer::Lock(void** aBuf) {
79 MutexAutoLock lock(mMutex);
81 MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
83 *aBuf = mBuf;
84 if (++mLockCount > 1 || OnHeap()) {
85 return true;
88 // Zero offset and zero length means we want to pin/unpin the entire thing.
89 struct ashmem_pin pin = {0, 0};
90 return ioctl(mFd, ASHMEM_PIN, &pin) == ASHMEM_NOT_PURGED;
93 void VolatileBuffer::Unlock() {
94 MutexAutoLock lock(mMutex);
96 MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
97 if (--mLockCount || OnHeap()) {
98 return;
101 struct ashmem_pin pin = {0, 0};
102 ioctl(mFd, ASHMEM_UNPIN, &pin);
105 bool VolatileBuffer::OnHeap() const { return mFd < 0; }
107 size_t VolatileBuffer::HeapSizeOfExcludingThis(
108 MallocSizeOf aMallocSizeOf) const {
109 return OnHeap() ? aMallocSizeOf(mBuf) : 0;
112 size_t VolatileBuffer::NonHeapSizeOfExcludingThis() const {
113 if (OnHeap()) {
114 return 0;
117 return (mSize + (PAGE_SIZE - 1)) & PAGE_MASK;
120 } // namespace mozilla