cpp/mmapbuf/MmapBufferManager.cpp (98 lines of code) (raw):

/** * Copyright 2004-present, Facebook, Inc. * * 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. */ #include "MmapBufferManager.h" #include <errno.h> #include <unistd.h> #include <cstring> #include <memory> #include <stdexcept> #include <system_error> #include <fb/log.h> #include <profilo/logger/buffer/RingBuffer.h> #include <profilo/mmapbuf/header/MmapBufferHeader.h> namespace facebook { namespace profilo { namespace mmapbuf { fbjni::local_ref<JBuffer::javaobject> MmapBufferManager::allocateBufferAnonymousForJava(int32_t buffer_size) { return JBuffer::makeJBuffer(allocateBufferAnonymous(buffer_size)); } std::shared_ptr<Buffer> MmapBufferManager::allocateBufferAnonymous( int32_t buffer_size) { std::shared_ptr<Buffer> buffer = nullptr; try { buffer = std::make_shared<Buffer>((size_t)buffer_size); } catch (std::exception& ex) { FBLOGE("%s", ex.what()); return nullptr; } registerBuffer(buffer); return buffer; } fbjni::local_ref<JBuffer::javaobject> MmapBufferManager::allocateBufferFileForJava( int32_t buffer_size, const std::string& path) { auto buffer = allocateBufferFile(buffer_size, path); if (buffer == nullptr) { throw std::invalid_argument("Could not allocate file-backed buffer"); } return JBuffer::makeJBuffer(buffer); } std::shared_ptr<Buffer> MmapBufferManager::allocateBufferFile( int32_t buffer_size, const std::string& path) { std::shared_ptr<Buffer> buffer = nullptr; try { buffer = std::make_shared<Buffer>(path, (size_t)buffer_size); } catch (std::system_error& ex) { FBLOGE("%s", ex.what()); return nullptr; } registerBuffer(buffer); // Pass the buffer to the global singleton return buffer; } void MmapBufferManager::registerBuffer(std::shared_ptr<Buffer> buffer) { buffer->prefix->header.bufferVersion = RingBuffer::kVersion; buffer->prefix->header.size = buffer->entryCount; buffer->prefix->header.pid = getpid(); { WriterLock lock(&buffers_lock_); buffers_.push_back(buffer); } } fbjni::local_ref<MmapBufferManager::jhybriddata> MmapBufferManager::initHybrid( fbjni::alias_ref<jclass>) { return makeCxxInstance(); } bool MmapBufferManager::deallocateBufferForJava(JBuffer* buffer) { return deallocateBuffer(buffer->get()); } bool MmapBufferManager::deallocateBuffer(std::shared_ptr<Buffer> buffer) { WriterLock lock(&buffers_lock_); auto iter = std::find(buffers_.begin(), buffers_.end(), buffer); if (iter == buffers_.end()) { return false; } buffers_.erase(iter); return true; } void MmapBufferManager::forEachBuffer(std::function<void(Buffer&)> fn) { ReaderLock lock(&buffers_lock_); for (auto& buf : buffers_) { fn(*buf); } } void MmapBufferManager::registerNatives() { registerHybrid({ makeNativeMethod("initHybrid", MmapBufferManager::initHybrid), makeNativeMethod( "nativeAllocateBuffer", MmapBufferManager::allocateBufferFileForJava), makeNativeMethod( "nativeAllocateBuffer", MmapBufferManager::allocateBufferAnonymousForJava), makeNativeMethod( "nativeDeallocateBuffer", MmapBufferManager::deallocateBufferForJava), }); } } // namespace mmapbuf } // namespace profilo } // namespace facebook