forked from OSchip/llvm-project
82 lines
2.3 KiB
C++
82 lines
2.3 KiB
C++
//===-- xray_buffer_queue.cc -----------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file is a part of XRay, a dynamic runtime instruementation system.
|
|
//
|
|
// Defines the interface for a buffer queue implementation.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "xray_buffer_queue.h"
|
|
#include "sanitizer_common/sanitizer_common.h"
|
|
#include "sanitizer_common/sanitizer_libc.h"
|
|
|
|
#include <cstdlib>
|
|
#include <tuple>
|
|
|
|
using namespace __xray;
|
|
using namespace __sanitizer;
|
|
|
|
BufferQueue::BufferQueue(std::size_t B, std::size_t N, bool &Success)
|
|
: BufferSize(B), Buffers(N), Mutex(), OwnedBuffers(), Finalizing{0} {
|
|
for (auto &T : Buffers) {
|
|
void *Tmp = malloc(BufferSize);
|
|
if (Tmp == nullptr) {
|
|
Success = false;
|
|
return;
|
|
}
|
|
|
|
auto &Buf = std::get<0>(T);
|
|
Buf.Buffer = Tmp;
|
|
Buf.Size = B;
|
|
OwnedBuffers.emplace(Tmp);
|
|
}
|
|
Success = true;
|
|
}
|
|
|
|
BufferQueue::ErrorCode BufferQueue::getBuffer(Buffer &Buf) {
|
|
if (__sanitizer::atomic_load(&Finalizing, __sanitizer::memory_order_acquire))
|
|
return ErrorCode::QueueFinalizing;
|
|
__sanitizer::BlockingMutexLock Guard(&Mutex);
|
|
if (Buffers.empty())
|
|
return ErrorCode::NotEnoughMemory;
|
|
auto &T = Buffers.front();
|
|
auto &B = std::get<0>(T);
|
|
Buf = B;
|
|
B.Buffer = nullptr;
|
|
B.Size = 0;
|
|
Buffers.pop_front();
|
|
return ErrorCode::Ok;
|
|
}
|
|
|
|
BufferQueue::ErrorCode BufferQueue::releaseBuffer(Buffer &Buf) {
|
|
if (OwnedBuffers.count(Buf.Buffer) == 0)
|
|
return ErrorCode::UnrecognizedBuffer;
|
|
__sanitizer::BlockingMutexLock Guard(&Mutex);
|
|
|
|
// Now that the buffer has been released, we mark it as "used".
|
|
Buffers.emplace(Buffers.end(), Buf, true /* used */);
|
|
Buf.Buffer = nullptr;
|
|
Buf.Size = 0;
|
|
return ErrorCode::Ok;
|
|
}
|
|
|
|
BufferQueue::ErrorCode BufferQueue::finalize() {
|
|
if (__sanitizer::atomic_exchange(&Finalizing, 1,
|
|
__sanitizer::memory_order_acq_rel))
|
|
return ErrorCode::QueueFinalizing;
|
|
return ErrorCode::Ok;
|
|
}
|
|
|
|
BufferQueue::~BufferQueue() {
|
|
for (auto &T : Buffers) {
|
|
auto &Buf = std::get<0>(T);
|
|
free(Buf.Buffer);
|
|
}
|
|
}
|