Closed Bug 1278502 Opened 9 years ago Closed 9 years ago

TSan: data races netwerk/cache2/CacheFileIOManager.{h,cpp} on CacheFileHandle::{mSpecialFile, mInvalid}

Categories

(Core :: Networking: Cache, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla50
Tracking Status
firefox50 --- fixed

People

(Reporter: jseward, Assigned: jseward)

Details

(Whiteboard: [necko-active])

Attachments

(2 files)

TSan reports data races on CacheFileHandle::{mSpecialFile, mInvalid} for more or less any surfing performed with a TSan-enabled Firefox build. It is easy to reproduce. As far as I can tell, CacheFileHandle::mSpecialFile and CacheFileHandle::mInvalid are properly synchronised from a logical point of view. mSpecialFile is accessed only on the main thread and mInvalid only on the IO thread. However, because they are declared as single-bit booleans and they fall in the same byte, the hardware cannot update them atomically (independently) and so TSan correctly reports a race on the containing byte.
Attached file TSan complaint
Assignee: nobody → michal.novotny
Whiteboard: [necko-active]
Attached patch Proposed fixSplinter Review
This puts mSpecialFile into its own byte, so that it isn't in the same byte as mInvalid et al. I also put mPriority into its own byte for consistency. This isn't (as far as I can see) actually necessary, but there's no loss either, because once mSpecialFile is in its own byte then the compiler will allocate a whole byte for "mPriority : 1" anyway.
Hmm.. so the compiler doesn't recognize that the first two are bool const, while the rest is a r/w bool? That's odd. Could we just move the two flags your are converting somewhere around the class so that those are separated? Or make them uint16_t or so? Not sure what's better for performance.
Assignee: michal.novotny → jseward
(In reply to Honza Bambas (:mayhemer) from comment #3) > Hmm.. so the compiler doesn't recognize that the first two are bool const, > while the rest is a r/w bool? That's odd. It can recognise them as bool const, sure, but why should that imply that it should put them in separate bytes? I don't see that. > Could we just move the two flags > your are converting somewhere around the class so that those are separated? > Or make them uint16_t or so? Not sure what's better for performance. I seriously doubt you can detect any performance change unless these flags are being set and queried millions of times per second. That said: Changing them to be non-bitfields actually improves performance, because it means assigments are a single store instruction instead of the read-shift-AND-OR-write sequence which is what the bitfield version requires, and similarly for uses of the value. 8 bit loads/stores are just as cheap as 16 bit load/stores, so I don't think uint16_t is going to help at all. I can move the flags around if you really want, in the hope of finding some combination that works, but that (presumably) makes the .h file harder to understand, and I don't even know if it will succeed. Do you want me to try anyway?
Comment on attachment 8760681 [details] [diff] [review] Proposed fix Review of attachment 8760681 [details] [diff] [review]: ----------------------------------------------------------------- (In reply to Honza Bambas (:mayhemer) from comment #3) > Could we just move the two flags your are converting somewhere around > the class so that those are separated? I like the patch how it is, feel free to land it. If Honza really needs these flags packed into a single byte the following should work, right? bool const mPriority : 1; bool const mSpecialFile : 1; bool : 0; // These bit flags are all accessed only on the IO thread bool mInvalid : 1;
Attachment #8760681 - Flags: review+
Honza, are you ok with the patch as-is or do you want me to work on it further, per comment 4 ?
Flags: needinfo?(honzab.moz)
(In reply to Julian Seward [:jseward] from comment #4) > (In reply to Honza Bambas (:mayhemer) from comment #3) > > Hmm.. so the compiler doesn't recognize that the first two are bool const, > > while the rest is a r/w bool? That's odd. > > It can recognise them as bool const, sure, but why should that imply that it > should put them in separate bytes? I don't see that. It's a different type actually, but whatever. > > > Could we just move the two flags > > your are converting somewhere around the class so that those are separated? > > Or make them uint16_t or so? Not sure what's better for performance. > > I seriously doubt you can detect any performance change unless these flags > are > being set and queried millions of times per second. That said: > > Changing them to be non-bitfields actually improves performance, because it > means assigments are a single store instruction instead of the > read-shift-AND-OR-write sequence which is what the bitfield version requires, > and similarly for uses of the value. These two are const, so only read (AND/TEST). > > 8 bit loads/stores are just as cheap as 16 bit load/stores, so I don't think > uint16_t is going to help at all. > > I can move the flags around if you really want, in the hope of finding some > combination that works, but that (presumably) makes the .h file harder to > understand, > and I don't even know if it will succeed. Do you want me to try anyway? No, let's go with it as it is, despite that I think it's just waste of memory for nothing... (In reply to Julian Seward [:jseward] from comment #6) > Honza, are you ok with the patch as-is or do you want me to work > on it further, per comment 4 ? Rather per comment 5 if that works ;) But don't waste that much time on this detail. Up to you.
Flags: needinfo?(honzab.moz)
Pushed by jseward@mozilla.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/1f812f8563fb TSan: data races netwerk/cache2/CacheFileIOManager.{h,cpp} on CacheFileHandle::{mSpecialFile, mInvalid}. r=michal.novotny.
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla50
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: