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"
10 #include <linux/ashmem.h>
13 #include <sys/types.h>
17 extern "C" int posix_memalign(void** memptr
, size_t alignment
, size_t size
);
20 #define MIN_VOLATILE_ALLOC_SIZE 8192
24 VolatileBuffer::VolatileBuffer()
25 : mMutex("VolatileBuffer")
34 VolatileBuffer::Init(size_t aSize
, size_t aAlignment
)
36 MOZ_ASSERT(!mSize
&& !mBuf
, "Init called twice");
37 MOZ_ASSERT(!(aAlignment
% sizeof(void *)),
38 "Alignment must be multiple of pointer size");
41 if (aSize
< MIN_VOLATILE_ALLOC_SIZE
) {
45 mFd
= open("/" ASHMEM_NAME_DEF
, O_RDWR
);
50 if (ioctl(mFd
, ASHMEM_SET_SIZE
, mSize
) < 0) {
54 mBuf
= mmap(nullptr, mSize
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, mFd
, 0);
55 if (mBuf
!= MAP_FAILED
) {
67 posix_memalign(&mBuf
, aAlignment
, aSize
);
69 mBuf
= memalign(aAlignment
, aSize
);
74 VolatileBuffer::~VolatileBuffer()
76 MOZ_ASSERT(mLockCount
== 0, "Being destroyed with non-zero lock count?");
87 VolatileBuffer::Lock(void** aBuf
)
89 MutexAutoLock
lock(mMutex
);
91 MOZ_ASSERT(mBuf
, "Attempting to lock an uninitialized VolatileBuffer");
94 if (++mLockCount
> 1 || OnHeap()) {
98 // Zero offset and zero length means we want to pin/unpin the entire thing.
99 struct ashmem_pin pin
= { 0, 0 };
100 return ioctl(mFd
, ASHMEM_PIN
, &pin
) == ASHMEM_NOT_PURGED
;
104 VolatileBuffer::Unlock()
106 MutexAutoLock
lock(mMutex
);
108 MOZ_ASSERT(mLockCount
> 0, "VolatileBuffer unlocked too many times!");
109 if (--mLockCount
|| OnHeap()) {
113 struct ashmem_pin pin
= { 0, 0 };
114 ioctl(mFd
, ASHMEM_UNPIN
, &pin
);
118 VolatileBuffer::OnHeap() const
124 VolatileBuffer::HeapSizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const
126 return OnHeap() ? aMallocSizeOf(mBuf
) : 0;
130 VolatileBuffer::NonHeapSizeOfExcludingThis() const
136 return (mSize
+ (PAGE_SIZE
- 1)) & PAGE_MASK
;
139 } // namespace mozilla