Bug 59984

Summary: Need a way to determine if the main thread has been initialized.
Product: WebKit Reporter: David Levin <levin>
Component: Web Template FrameworkAssignee: David Levin <levin>
Status: RESOLVED INVALID    
Severity: Normal CC: ap, barraclough, jchaffraix
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: OS X 10.5   
Bug Depends on:    
Bug Blocks: 31639    
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch levin: review-

Description David Levin 2011-05-02 17:08:57 PDT
wtf may be used without initializing the main thread. Due to these cases, it would be useful to know if the main thread has been initialized before calling isMainThread.
Comment 1 David Levin 2011-05-04 15:17:10 PDT
Created attachment 92327 [details]
Patch
Comment 2 Darin Adler 2011-05-04 15:22:27 PDT
Comment on attachment 92327 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=92327&action=review

> Source/JavaScriptCore/wtf/MainThread.cpp:253
> +bool internalIsMainThreadInitialized()
> +{
> +#ifndef NDEBUG
> +    return mainThreadInitialized;
> +#else
> +    return false;
> +#endif
> +}

It doesn’t make sense to have this return false in NDEBUG builds. Maybe put a CRASH() here instead or in addition?
Comment 3 Alexey Proskuryakov 2011-05-04 16:15:47 PDT
Comment on attachment 92327 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=92327&action=review

> Source/JavaScriptCore/wtf/MainThread.cpp:246
> +bool internalIsMainThreadInitialized()

It's slightly inelegant to have a function that returns a boolean, but only "true" results can be trusted. Trusting a "false" results would be a race condition.

Can this be changed into a check-style function that asserts internally?
Comment 4 Alexey Proskuryakov 2011-05-04 16:18:03 PDT
Comment on attachment 92327 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=92327&action=review

> Source/JavaScriptCore/wtf/MainThread.cpp:248
> +#ifndef NDEBUG

Another extremely minor nit. ASSERTION_ENABLED is not exactly the same as !NDEBUG. People sometimes want to build release mode with assertions - I know that I did that once, with a significant but practical amount of code changes.
Comment 5 David Levin 2011-05-04 16:36:00 PDT
(In reply to comment #3)
> (From update of attachment 92327 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=92327&action=review
> 
> > Source/JavaScriptCore/wtf/MainThread.cpp:246
> > +bool internalIsMainThreadInitialized()
> 
> It's slightly inelegant to have a function that returns a boolean, but only "true" results can be trusted. 

Per discussion in irc, will change the name to mayCallIsMainThread.

(In reply to comment #4)
> (From update of attachment 92327 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=92327&action=review
> 
> > Source/JavaScriptCore/wtf/MainThread.cpp:248
> > +#ifndef NDEBUG
> 
> Another extremely minor nit. ASSERTION_ENABLED is not exactly the same as !NDEBUG. People sometimes want to build release mode with assertions - I know that I did that once, with a significant but practical amount of code changes.

Thanks. Will fix.
Comment 6 David Levin 2011-05-04 17:04:51 PDT
Comment on attachment 92327 [details]
Patch

Changing to "isKnownAsMainThread" which will change the code some.
Comment 7 David Levin 2011-05-04 18:05:36 PDT
Created attachment 92352 [details]
Patch
Comment 8 David Levin 2011-05-04 18:28:59 PDT
Created attachment 92354 [details]
Patch
Comment 9 David Levin 2011-05-04 23:42:03 PDT
Comment on attachment 92354 [details]
Patch

I should add a similar atomicIncrement to initializeMainThreadToProcessMainThreadOnce().
Comment 10 David Levin 2011-05-05 11:10:56 PDT
Created attachment 92433 [details]
Patch
Comment 11 Alexey Proskuryakov 2011-05-05 12:15:14 PDT
Comment on attachment 92433 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=92433&action=review

> Source/JavaScriptCore/ChangeLog:13
> +        (WTF::initializeMainThreadOnce): Ditto (for OSX).
> +        (WTF::initializeMainThreadToProcessMainThreadOnce): Ditto (for OSX).

"OS X".

> Source/JavaScriptCore/wtf/MainThread.cpp:76
> +static int mainThreadInitialized;

It's quite confusing to have both mainThreadInitialized and initializedMainThread in this code.

> Source/JavaScriptCore/wtf/MainThread.cpp:113
> +    // Flush all writes and set mainThreadInitialized to 1 to indicate that the initialization has been done.
> +    atomicIncrement(&mainThreadInitialized);

Not sure if the fact that setting a variable named mainThreadInitialized to 1 indicates that the initialization has been done needs a comment.

That said, I can see why the use of atomicIncrement to insert a memory barrier needs some explanation. But after an IRC discussion, I also don't think that it's doing the job. There is no way to guarantee memory consistency without a memory barrier on a thread that checks mainThreadInitialized - it's not enough to use on the thread that changes it.

Also, I'm not sure if we want or do guarantee a full memory barrier in atomicIncrement implementations. Clearly, it's not required to increment one integer.

> Source/JavaScriptCore/wtf/MainThread.cpp:257
> +    CRASH();

This probably need a comment.
Comment 12 David Levin 2011-07-12 14:52:03 PDT
Instead of doing this, I'm looking into making current thread much faster.

currentThread takes about 3x the time of isMainThread in debug and more than 2x in release, which is the reason for preferring to use isMainThread when possible.

On the other hand, if currentThread were faster than it is now, then this issue may go away.