/*
* Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved.
*
* This file is part of the Lock Contention Tracing Subsystem for the HotSpot
* Virtual Machine, which is developed at Christian Doppler Laboratory on
* Monitoring and Evolution of Very-Large-Scale Software Systems. Please
* contact us at if you need additional information
* or have any questions.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work. If not, see .
*
*/
#include "evtrace/traceBufferQueue.hpp"
#include "evtrace/traceBuffer.hpp"
class TraceBufferQueue::SpinLocker: public StackObj {
private:
TraceBufferQueue * const _queue;
public:
SpinLocker(TraceBufferQueue *q, const char *s) : _queue(q) {
Thread::SpinAcquire(&_queue->_mtx, s);
}
~SpinLocker() {
Thread::SpinRelease(&_queue->_mtx);
}
};
TraceBufferQueue::TraceBufferQueue()
: _head(NULL),
_tail(NULL),
_mtx(0),
_enqueue_ops(0),
_dequeue_ops(0)
{
}
TraceBufferQueue::~TraceBufferQueue() {
}
size_t TraceBufferQueue::count() {
SpinLocker sl(this, "TraceBufferQueue - count");
return (_enqueue_ops - _dequeue_ops);
}
TraceBuffer * TraceBufferQueue::try_dequeue() {
TraceBuffer *buffer = NULL;
{
SpinLocker sl(this, "TraceBufferQueue - try_dequeue");
if (_head != NULL) {
buffer = _head;
_head = _head->queue_next;
if (_head == NULL) {
_tail = NULL;
}
_dequeue_ops++;
}
}
if (buffer != NULL) {
buffer->queue_next = NULL;
}
return buffer;
}
void TraceBufferQueue::enqueue(TraceBuffer * const buffer) {
assert(buffer != NULL, "sanity");
assert(buffer->queue_next == NULL, "queue linkage");
SpinLocker sl(this, "TraceBufferQueue - enqueue");
if (_tail != NULL) {
_tail->queue_next = buffer;
} else {
_head = buffer;
}
_tail = buffer;
_enqueue_ops++;
}