8269865: Async UL needs to handle ERANGE on exceeding SEM_VALUE_MAX
Reviewed-by: dholmes, pchilanomate
This commit is contained in:
parent
0f5470715e
commit
67273ae63c
@ -27,16 +27,17 @@
|
|||||||
#include "logging/logFileOutput.hpp"
|
#include "logging/logFileOutput.hpp"
|
||||||
#include "logging/logHandle.hpp"
|
#include "logging/logHandle.hpp"
|
||||||
#include "runtime/atomic.hpp"
|
#include "runtime/atomic.hpp"
|
||||||
|
#include "runtime/os.inline.hpp"
|
||||||
|
|
||||||
class AsyncLogWriter::AsyncLogLocker : public StackObj {
|
class AsyncLogWriter::AsyncLogLocker : public StackObj {
|
||||||
public:
|
public:
|
||||||
AsyncLogLocker() {
|
AsyncLogLocker() {
|
||||||
assert(_instance != nullptr, "AsyncLogWriter::_lock is unavailable");
|
assert(_instance != nullptr, "AsyncLogWriter::_lock is unavailable");
|
||||||
_instance->_lock.wait();
|
_instance->_lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
~AsyncLogLocker() {
|
~AsyncLogLocker() {
|
||||||
_instance->_lock.signal();
|
_instance->_lock.unlock();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,7 +52,8 @@ void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buffer.push_back(msg);
|
_buffer.push_back(msg);
|
||||||
_sem.signal();
|
_data_available = true;
|
||||||
|
_lock.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncLogWriter::enqueue(LogFileOutput& output, const LogDecorations& decorations, const char* msg) {
|
void AsyncLogWriter::enqueue(LogFileOutput& output, const LogDecorations& decorations, const char* msg) {
|
||||||
@ -75,7 +77,7 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, LogMessageBuffer::Iterator m
|
|||||||
}
|
}
|
||||||
|
|
||||||
AsyncLogWriter::AsyncLogWriter()
|
AsyncLogWriter::AsyncLogWriter()
|
||||||
: _lock(1), _sem(0), _flush_sem(0),
|
: _flush_sem(0), _lock(), _data_available(false),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_stats(17 /*table_size*/) {
|
_stats(17 /*table_size*/) {
|
||||||
if (os::create_thread(this, os::asynclog_thread)) {
|
if (os::create_thread(this, os::asynclog_thread)) {
|
||||||
@ -125,6 +127,7 @@ void AsyncLogWriter::write() {
|
|||||||
// append meta-messages of dropped counters
|
// append meta-messages of dropped counters
|
||||||
AsyncLogMapIterator dropped_counters_iter(logs);
|
AsyncLogMapIterator dropped_counters_iter(logs);
|
||||||
_stats.iterate(&dropped_counters_iter);
|
_stats.iterate(&dropped_counters_iter);
|
||||||
|
_data_available = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedListIterator<AsyncLogMessage> it(logs.head());
|
LinkedListIterator<AsyncLogMessage> it(logs.head());
|
||||||
@ -152,9 +155,14 @@ void AsyncLogWriter::write() {
|
|||||||
|
|
||||||
void AsyncLogWriter::run() {
|
void AsyncLogWriter::run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
// The value of a semphore cannot be negative. Therefore, the current thread falls asleep
|
{
|
||||||
// when its value is zero. It will be waken up when new messages are enqueued.
|
AsyncLogLocker locker;
|
||||||
_sem.wait();
|
|
||||||
|
while (!_data_available) {
|
||||||
|
_lock.wait(0/* no timeout */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
write();
|
write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +206,8 @@ void AsyncLogWriter::flush() {
|
|||||||
|
|
||||||
// Push directly in-case we are at logical max capacity, as this must not get dropped.
|
// Push directly in-case we are at logical max capacity, as this must not get dropped.
|
||||||
_instance->_buffer.push_back(token);
|
_instance->_buffer.push_back(token);
|
||||||
_instance->_sem.signal();
|
_instance->_data_available = true;
|
||||||
|
_instance->_lock.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
_instance->_flush_sem.wait();
|
_instance->_flush_sem.wait();
|
||||||
|
@ -135,13 +135,10 @@ class AsyncLogWriter : public NonJavaThread {
|
|||||||
class AsyncLogLocker;
|
class AsyncLogLocker;
|
||||||
|
|
||||||
static AsyncLogWriter* _instance;
|
static AsyncLogWriter* _instance;
|
||||||
// _lock(1) denotes a critional region.
|
|
||||||
Semaphore _lock;
|
|
||||||
// _sem is a semaphore whose value denotes how many messages have been enqueued.
|
|
||||||
// It decreases in AsyncLogWriter::run()
|
|
||||||
Semaphore _sem;
|
|
||||||
Semaphore _flush_sem;
|
Semaphore _flush_sem;
|
||||||
|
// Can't use a Monitor here as we need a low-level API that can be used without Thread::current().
|
||||||
|
os::PlatformMonitor _lock;
|
||||||
|
bool _data_available;
|
||||||
volatile bool _initialized;
|
volatile bool _initialized;
|
||||||
AsyncLogMap _stats; // statistics for dropped messages
|
AsyncLogMap _stats; // statistics for dropped messages
|
||||||
AsyncLogBuffer _buffer;
|
AsyncLogBuffer _buffer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user