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"
12 #include <sys/types.h>
15 #include "mozilla/Ashmem.h"
18 extern "C" int posix_memalign(void** memptr
, size_t alignment
, size_t size
);
21 #define MIN_VOLATILE_ALLOC_SIZE 8192
25 VolatileBuffer::VolatileBuffer()
26 : mMutex("VolatileBuffer"),
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");
38 if (aSize
< MIN_VOLATILE_ALLOC_SIZE
) {
42 mFd
= mozilla::android::ashmem_create(nullptr, mSize
);
47 mBuf
= mmap(nullptr, mSize
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, mFd
, 0);
48 if (mBuf
!= MAP_FAILED
) {
60 posix_memalign(&mBuf
, aAlignment
, aSize
);
62 mBuf
= memalign(aAlignment
, aSize
);
67 VolatileBuffer::~VolatileBuffer() {
68 MOZ_ASSERT(mLockCount
== 0, "Being destroyed with non-zero lock count?");
78 bool VolatileBuffer::Lock(void** aBuf
) {
79 MutexAutoLock
lock(mMutex
);
81 MOZ_ASSERT(mBuf
, "Attempting to lock an uninitialized VolatileBuffer");
84 if (++mLockCount
> 1 || OnHeap()) {
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()) {
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 {
117 return (mSize
+ (PAGE_SIZE
- 1)) & PAGE_MASK
;
120 } // namespace mozilla