RFR: 8229517: Support for optional asynchronous/buffered logging [v2]

Xin Liu xliu at openjdk.java.net
Mon Apr 5 06:52:22 UTC 2021


On Fri, 26 Mar 2021 09:12:05 GMT, Volker Simonis <simonis at openjdk.org> wrote:

>> Xin Liu has updated the pull request incrementally with two additional commits since the last revision:
>> 
>>  - 8229517: Support for optional asynchronous/buffered logging
>>    
>>    add a constraint for the option LogAsyncInterval.
>>  - 8229517: Support for optional asynchronous/buffered logging
>>    
>>    LogMessage supports async_mode.
>>    remove the option AsyncLogging
>>    renanme  the option GCLogBufferSize to AsyncLogBufferSize
>>    move drop_log() to LogAsyncFlusher.
>
> src/hotspot/share/logging/logFileOutput.cpp line 322:
> 
>> 320: 
>> 321:   LogAsyncFlusher* flusher = LogAsyncFlusher::instance();
>> 322:   if (_async_mode && flusher != NULL) {
> 
> Why you don't check for `flusher == NULL` in `LogAsyncFlusher::instance()` and call `LogAsyncFlusher::initialize()` in case it is NULL. I think it's no difference where the NULL check is and doing it in `LogAsyncFlusher::instance()` will save you from calling `LogAsyncFlusher::initialize()` in `init_globals()`.
> 
> Put `LogAsyncFlusher::instance()` into the `if (_async_mode)` block and add an assertion that `flusher != NULL`.

hi, @simonis  and @tstuefe 

The purpose of nullcheck here is to circumvent the problem of circular dependency which also mentioned by Thomas.  Logging subsystem as a low-level infrastructure could be invoked as early as `LogConfiguration::initialize` has done in `Threads::create_vm()`. At this time, mutex and Thread haven't been initialized, therefore, I can't initialize `LogAsyncFlusher` appropriately. 

The reason I provide separated APIs `LogAsyncFlusher::initialize()` & `LogAsyncFlusher::instance()` because I need to separate log subsystems into 2 phrases. LogAsyncFlusher::initialize() marks an important point. Before this point, logging subsystem can only use synchronous mode no matter what. After this point, async_mode takes effect because buffer has been established.  That is to say, all code in this PR can only take over logging after that point.  

I read Thomas concerned about fancy calls such as strdup, os::malloc etc.  Instead of designing async-logging absolutely self-contained and low-level, I chose a common technique called 'lazy-initialization'.  I don't think async mode is absolutely necessary in the startup time of hotspot. The gain is obvious. I can use hotspot's established constructs to simplify the implementation. 

May I ask you and Thomas to comment on this design? If it works, I will add more comments about it.

> test/hotspot/gtest/logging/test_asynclog.cpp line 168:
> 
>> 166:   EXPECT_FALSE(file_contains_substring(TestLogFileName, "log_trace-test")); // trace message is masked out
>> 167:   EXPECT_TRUE(file_contains_substring(TestLogFileName, "log_debug-test"));
>> 168: }
> 
> Should have a newline at the end.

noted.

-------------

PR: https://git.openjdk.java.net/jdk/pull/3135


More information about the hotspot-dev mailing list