--- /dev/null 2016-10-25 08:46:44.038854975 +0200 +++ new/src/share/vm/evtrace/traceBufferQueue.cpp 2016-10-25 10:40:13.545780417 +0200 @@ -0,0 +1,93 @@ +/* + * 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++; +}