[webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Steve Block
I have a question about whether WebCore code makes assumptions about
the atomicity of certain read/write operations.

The particular instance I'm interested in is IconDatabase, where
m_threadTerminationRequested is written to from the main thread (in
close() for example) and read from the DB thread (in
syncThreadMainLoop()) without any locking.  It looks like the code is
written such that there's no particular synchronization requirement in
terms of the order in which the value is set and read. But there's a
risk of a garbled read in the case of a simultaneous read and write
from the two threads.

I assume that the lack of locking is an intentional decision, based on
the fact that on all relevant architectures, a boolean read/write is
atomic?

Is this a general WebCore policy? It would be great if somebody could
confirm this, or point out why I'm wrong.

Thanks,
Steve

-- 
Google UK Limited
Registered Office: Belgrave House, 76 Buckingham Palace Road, London SW1W 9TQ
Registered in England Number: 3977902
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Brady Eidson

On Dec 15, 2010, at 4:28 AM, Steve Block wrote:

> I have a question about whether WebCore code makes assumptions about
> the atomicity of certain read/write operations.
> 
> The particular instance I'm interested in is IconDatabase, where
> m_threadTerminationRequested is written to from the main thread (in
> close() for example) and read from the DB thread (in
> syncThreadMainLoop()) without any locking.  It looks like the code is
> written such that there's no particular synchronization requirement in
> terms of the order in which the value is set and read. But there's a
> risk of a garbled read in the case of a simultaneous read and write
> from the two threads.
> 
> I assume that the lack of locking is an intentional decision, based on
> the fact that on all relevant architectures, a boolean read/write is
> atomic?

Correct - or, at least, at the time it was correct.  Have you discovered a 
relevant architecture where it is no longer correct?

> Is this a general WebCore policy? It would be great if somebody could
> confirm this, or point out why I'm wrong.

I wouldn't be surprised if there were other examples of an unprotected thread 
shared boolean in either WebCore or any platform's WebKit.

I *would* be surprised if there was an example of *any other data type* that 
was shared between threads unprotected.

That said, I don't think we have any general WebCore policies about multithread 
practices.  There might be value in such a document.

~Brady

> 
> Thanks,
> Steve
> 
> -- 
> Google UK Limited
> Registered Office: Belgrave House, 76 Buckingham Palace Road, London SW1W 9TQ
> Registered in England Number: 3977902

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Brady Eidson

On Dec 15, 2010, at 8:47 AM, Brady Eidson wrote:

> 
> On Dec 15, 2010, at 4:28 AM, Steve Block wrote:
> 
>> I have a question about whether WebCore code makes assumptions about
>> the atomicity of certain read/write operations.
>> 
>> The particular instance I'm interested in is IconDatabase, where
>> m_threadTerminationRequested is written to from the main thread (in
>> close() for example) and read from the DB thread (in
>> syncThreadMainLoop()) without any locking.  It looks like the code is
>> written such that there's no particular synchronization requirement in
>> terms of the order in which the value is set and read. But there's a
>> risk of a garbled read in the case of a simultaneous read and write
>> from the two threads.
>> 
>> I assume that the lack of locking is an intentional decision, based on
>> the fact that on all relevant architectures, a boolean read/write is
>> atomic?
> 
> Correct - or, at least, at the time it was correct.  Have you discovered a 
> relevant architecture where it is no longer correct?
> 
>> Is this a general WebCore policy? It would be great if somebody could
>> confirm this, or point out why I'm wrong.
> 
> I wouldn't be surprised if there were other examples of an unprotected thread 
> shared boolean in either WebCore or any platform's WebKit.

In hindsight I realize my response involved assumptions about this code that 
were known to me but not to the general audience, so I'll followup more 
thoroughly.

The boolean in question isn't both checked and set at the same time - it's not 
an acquired resource.  One thread sets it, the other checks it.  My belief is 
that this is safe for booleans, but I would love to hear where I'm wrong.

Additionally, while there isn't a guard specifically around the boolean, there 
is the "m_syncLock" Mutex which is implicitly guarding operations on this bool, 
so the "thread safety of a bool?" argument becomes somewhat moot.

If there's a specific race condition in this code you've spotted, I'd love to 
hear how it would manifest!

Thanks,
~Brady


> I *would* be surprised if there was an example of *any other data type* that 
> was shared between threads unprotected.
> 
> That said, I don't think we have any general WebCore policies about 
> multithread practices.  There might be value in such a document.
> 
> ~Brady
> 
>> 
>> Thanks,
>> Steve
>> 
>> -- 
>> Google UK Limited
>> Registered Office: Belgrave House, 76 Buckingham Palace Road, London SW1W 9TQ
>> Registered in England Number: 3977902
> 
> ___
> webkit-dev mailing list
> webkit-dev@lists.webkit.org
> http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Stephan Aßmus

Hi,

Am 15.12.2010 18:43, schrieb Brady Eidson:

On Dec 15, 2010, at 8:47 AM, Brady Eidson wrote:

On Dec 15, 2010, at 4:28 AM, Steve Block wrote:
I wouldn't be surprised if there were other examples of an unprotected thread 
shared boolean in either WebCore or any platform's WebKit.


In hindsight I realize my response involved assumptions about this code that 
were known to me but not to the general audience, so I'll followup more 
thoroughly.

The boolean in question isn't both checked and set at the same time - it's not 
an acquired resource.  One thread sets it, the other checks it.  My belief is 
that this is safe for booleans, but I would love to hear where I'm wrong.


I have seen this particular technique quite often before. The only thing 
one needs to watch out for is to declare such a boolean volatile (which 
I believe this code does, if memory serves). Otherwise the thread which 
polls the condition may read from a cached location and miss the change. 
Worst that can happen on a hypothecial architecture where writing a byte 
is not atomic is that the changed condition takes affect one loop cycle 
later.


Best regards,
-Stephan
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Brady Eidson

On Dec 15, 2010, at 11:11 AM, Steve Block wrote:

> Thanks for the reply Brady.
> 
>> The boolean in question isn't both checked and set at the same time - it's 
>> not an acquired resource.  One
>> thread sets it, the other checks it.
> I don't follow. If it's set from one thread and checked from another
> thread without locks, how can you guarantee this (other than with
> application logic)?

I don't understand your question - "how can you guarantee this?"

>> Additionally, while there isn't a guard specifically around the boolean, 
>> there is the "m_syncLock" Mutex
>> which is implicitly guarding operations on this bool, so the "thread safety 
>> of a bool?" argument becomes
>> somewhat moot.
> Ah, so you're saying that there's application logic using m_syncLock
> to prevent the boolean from being written and read at the same time? I
> didn't spot that.

It doesn't matter if it's written and read at the same time in this case - but 
after every write on the main thread, the background thread is signaled to 
read, so that read will always happen after the write.

~Brady

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Steve Block
>>> The boolean in question isn't both checked and set at the same time - it's 
>>> not an acquired resource.  One
>>> thread sets it, the other checks it.
>> I don't follow. If it's set from one thread and checked from another
>> thread without locks, how can you guarantee this (other than with
>> application logic)?
> I don't understand your question - "how can you guarantee this?"
I meant 'how can you guarantee that the boolean isn't both checked and
set at the same time, given that you don't use locks'. But it looks
like you're saying that this is guaranteed by higher-level application
logic, as you describe below.

> It doesn't matter if it's written and read at the same time in this case - 
> but after every write on the main
> thread, the background thread is signaled to read, so that read will always 
> happen after the write.
OK, makes sense.

Thanks,
Steve
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Steve Block
Thanks for the reply Brady.

> The boolean in question isn't both checked and set at the same time - it's 
> not an acquired resource.  One
> thread sets it, the other checks it.
I don't follow. If it's set from one thread and checked from another
thread without locks, how can you guarantee this (other than with
application logic)?

> Additionally, while there isn't a guard specifically around the boolean, 
> there is the "m_syncLock" Mutex
> which is implicitly guarding operations on this bool, so the "thread safety 
> of a bool?" argument becomes
> somewhat moot.
Ah, so you're saying that there's application logic using m_syncLock
to prevent the boolean from being written and read at the same time? I
didn't spot that.

> I have seen this particular technique quite often before. The only thing one
> needs to watch out for is to declare such a boolean volatile (which I
> believe this code does, if memory serves). Otherwise the thread which polls
> the condition may read from a cached location and miss the change.
The boolean in question isn't volatile. This isn't a problem because
as I mentioned, there's no requirement for a given write to be picked
up by a particular read. If a read 'misses' a write, we'll pick it up
later.

Steve
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Maciej Stachowiak

On Dec 15, 2010, at 8:47 AM, Brady Eidson wrote:

> 
> On Dec 15, 2010, at 4:28 AM, Steve Block wrote:
> 
>> I have a question about whether WebCore code makes assumptions about
>> the atomicity of certain read/write operations.
>> 
>> The particular instance I'm interested in is IconDatabase, where
>> m_threadTerminationRequested is written to from the main thread (in
>> close() for example) and read from the DB thread (in
>> syncThreadMainLoop()) without any locking.  It looks like the code is
>> written such that there's no particular synchronization requirement in
>> terms of the order in which the value is set and read. But there's a
>> risk of a garbled read in the case of a simultaneous read and write
>> from the two threads.
>> 
>> I assume that the lack of locking is an intentional decision, based on
>> the fact that on all relevant architectures, a boolean read/write is
>> atomic?
> 
> Correct - or, at least, at the time it was correct.  Have you discovered a 
> relevant architecture where it is no longer correct?
> 
>> Is this a general WebCore policy? It would be great if somebody could
>> confirm this, or point out why I'm wrong.
> 
> I wouldn't be surprised if there were other examples of an unprotected thread 
> shared boolean in either WebCore or any platform's WebKit.
> 
> I *would* be surprised if there was an example of *any other data type* that 
> was shared between threads unprotected.
> 
> That said, I don't think we have any general WebCore policies about 
> multithread practices.  There might be value in such a document.

One possibility is to check the perf impact os using atomic read/write 
primitives; if it doesn't have a performance cost, it might be safer to do it 
that way.

 - Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-15 Thread Alexey Proskuryakov

15.12.2010, в 10:36, Stephan Aßmus написал(а):

> The only thing one needs to watch out for is to declare such a boolean 
> volatile (which I believe this code does, if memory serves). Otherwise the 
> thread which polls the condition may read from a cached location and miss the 
> change. Worst that can happen on a hypothecial architecture where writing a 
> byte is not atomic is that the changed condition takes affect one loop cycle 
> later.


The behavior of volatile depends on the compiler - there is no guarantee that a 
memory barrier will be emitted. Historically, volatile existed not for 
multiprocessor systems, but for special addresses in address space (like memory 
mapped I/O), where it is important to actually access the address each time, 
and not than keep a local variable in a boolean.

There is code in WebKit that doesn't care about the other thread immediately 
seeing the change of a boolean value, and just hopes that it will propagate 
soon enough in practice. I remember implementing worker thread termination in 
that way. This code is of course formally wrong.

- WBR, Alexey Proskuryakov

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Atomic read/write operations and thread safety

2010-12-16 Thread Mikhail Naganov
In MSDN there is a widely cited article about lockless programming on
x86 and Xbox: http://msdn.microsoft.com/en-us/library/ee418650(v=vs.85).aspx

In short: using boolean as a flag for thread termination is OK. Using
boolean as a guard for multi-threaded access to data isn't OK, as read
/ write reordering can be made both by C++ compiler and CPU.

On Thu, Dec 16, 2010 at 00:34, Alexey Proskuryakov  wrote:
>
> 15.12.2010, в 10:36, Stephan Aßmus написал(а):
>
>> The only thing one needs to watch out for is to declare such a boolean 
>> volatile (which I believe this code does, if memory serves). Otherwise the 
>> thread which polls the condition may read from a cached location and miss 
>> the change. Worst that can happen on a hypothecial architecture where 
>> writing a byte is not atomic is that the changed condition takes affect one 
>> loop cycle later.
>
>
> The behavior of volatile depends on the compiler - there is no guarantee that 
> a memory barrier will be emitted. Historically, volatile existed not for 
> multiprocessor systems, but for special addresses in address space (like 
> memory mapped I/O), where it is important to actually access the address each 
> time, and not than keep a local variable in a boolean.
>
> There is code in WebKit that doesn't care about the other thread immediately 
> seeing the change of a boolean value, and just hopes that it will propagate 
> soon enough in practice. I remember implementing worker thread termination in 
> that way. This code is of course formally wrong.
>
> - WBR, Alexey Proskuryakov
>
> ___
> webkit-dev mailing list
> webkit-dev@lists.webkit.org
> http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
>
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev