< prev index next >
src/share/vm/utilities/ostream.cpp
Print this page
@@ -25,12 +25,14 @@
#include "precompiled.hpp"
#include "compiler/compileLog.hpp"
#include "gc_implementation/shared/gcId.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/arguments.hpp"
+#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "utilities/defaultStream.hpp"
+#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
#include "utilities/top.hpp"
#include "utilities/xmlstream.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
@@ -799,10 +801,17 @@
gcLogFileStream::gcLogFileStream(const char* file_name) {
_cur_file_num = 0;
_bytes_written = 0L;
_file_name = make_log_name(file_name, NULL);
+ if (AsyncGCLogging) {
+ //the mutex ranks higher than Mutex::safepoint
+ _lock = new Mutex(Mutex::leaf, "GCLogRingBuffer");
+ _reader = new GCLogEvent("gcLogRingBuf0", GCLogBufferSize);
+ _writer = new GCLogEvent("gcLogRingBuf1", GCLogBufferSize);
+ }
+
if (_file_name == NULL) {
warning("Cannot open file %s: file name is too long.\n", file_name);
_need_close = false;
UseGCLogFileRotation = false;
return;
@@ -816,25 +825,57 @@
} else {
_file = fopen(_file_name, "w");
}
if (_file != NULL) {
_need_close = true;
+
+ // temporarily disable AsyncGCLogging, because ThreadLocalStorage::thread()
+ // hasn't been initialized yet.
+ FlagSetting saver(AsyncGCLogging, false);
dump_loggc_header();
} else {
warning("Cannot open file %s due to %s\n", _file_name, strerror(errno));
_need_close = false;
}
}
-void gcLogFileStream::write(const char* s, size_t len) {
+void gcLogFileStream::flush_log() {
+ assert(AsyncGCLogging, "flush_log can only be used when AsyncGCLogging is on!");
+
+ _reader->print_log_on(this);
+ _reader->reset();
+
+ {
+ MutexLockerEx ml(_lock, true/*no_safepoint_check*/);
+ swap(_reader, _writer);
+ }
+}
+
+void gcLogFileStream::write_blocking(const char* s, size_t len) {
+#ifndef PRODUCT
+ if (DelayInGCLogging > 0) {
+ os::naked_short_sleep((jlong)DelayInGCLogging);
+ }
+#endif
+
if (_file != NULL) {
size_t count = fwrite(s, 1, len, _file);
_bytes_written += count;
}
update_position(s, len);
}
+void gcLogFileStream::write(const char* s, size_t len) {
+ if (AsyncGCLogging) {
+ MutexLockerEx ml(_lock, true/*no_safepoint_check*/);
+ _writer->log(NULL, s, len);
+ }
+ else {
+ write_blocking(s, len);
+ }
+}
+
// rotate_log must be called from VMThread at safepoint. In case need change parameters
// for gc log rotation from thread other than VMThread, a sub type of VM_Operation
// should be created and be submitted to VMThread's operation queue. DO NOT call this
// function directly. Currently, it is safe to rotate log at safepoint through VMThread.
// That is, no mutator threads and concurrent GC threads run parallel with VMThread to
@@ -1547,6 +1588,12 @@
int result = os::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in));
return (result >= 0);
}
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+void Test_gcLogFileStream() {
+}
+#endif
#endif
< prev index next >