CINXE.COM
Eliminating Data Races in Firefox - A Technical Report - Mozilla Hacks - the Web developer blog
<!doctype html> <html lang="en-US"> <head data-template-path="https://hacks.mozilla.org/wp-content/themes/Hax"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="google-site-verification" content="w2ocEMd5yV9IsGCjhq-7ls67r4VH-Ob6oWdiZpqjN8U"> <meta name="title" content="Eliminating Data Races in Firefox – A Technical Report – Mozilla Hacks - the Web developer blog"> <meta property="og:site_name" content="Mozilla Hacks – the Web developer blog"> <meta property="og:url" content="https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report"> <meta property="og:title" content="Eliminating Data Races in Firefox – A Technical Report – Mozilla Hacks - the Web developer blog"> <meta property="og:description" content="We successfully deployed ThreadSanitizer in the Firefox project to eliminate data races in our remaining C/C++ components."> <meta property="og:image" content="https://hacks.mozilla.org/wp-content/uploads/2021/03/tsan-sample-race.png"> <meta property="og:image:width" content="1273"> <meta property="og:image:height" content="668"> <meta property="twitter:title" content="Eliminating Data Races in Firefox – A Technical Report – Mozilla Hacks - the Web developer blog"> <meta property="twitter:description" content="We successfully deployed ThreadSanitizer in the Firefox project to eliminate data races in our remaining C/C++ components."> <meta name="twitter:card" content="summary_large_image"> <meta property="twitter:image" content="https://hacks.mozilla.org/wp-content/uploads/2021/03/tsan-sample-race.png"> <meta name="twitter:site" content="@mozhacks"> <link href='//fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic' rel='stylesheet' type='text/css'> <link rel="stylesheet" href="https://hacks.mozilla.org/wp-content/themes/Hax/css/font-awesome.min.css"> <link rel="stylesheet" href="https://hacks.mozilla.org/wp-content/themes/Hax/style.css"> <link rel="stylesheet" href="//cdn.jsdelivr.net/highlight.js/8.6.0/styles/solarized_light.min.css"> <script type="text/javascript"> window.hacks = {}; // http://cfsimplicity.com/61/removing-analytics-clutter-from-campaign-urls var removeUtms = function(){ var l = window.location; if( l.hash.indexOf( "utm" ) != -1 ){ var anchor = l.hash.match(/#(?!utm)[^&]+/); anchor = anchor? anchor[0]: ''; if(!anchor && window.history.replaceState){ history.replaceState({},'', l.pathname + l.search); } else { l.hash = anchor; } }; }; var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-35433268-8'], ['_setAllowAnchor', true]); _gaq.push (['_gat._anonymizeIp']); _gaq.push(['_trackPageview']); _gaq.push( removeUtms ); (function(d, k) { var ga = d.createElement(k); ga.type = 'text/javascript'; ga.async = true; ga.src = 'https://ssl.google-analytics.com/ga.js'; var s = d.getElementsByTagName(k)[0]; s.parentNode.insertBefore(ga, s); })(document, 'script'); </script> <script async src="https://www.googletagmanager.com/gtag/js?id=G-5WVW12ST9K"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-5WVW12ST9K'); </script> <meta name='robots' content='index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1' /> <!-- This site is optimized with the Yoast SEO plugin v22.6 - https://yoast.com/wordpress/plugins/seo/ --> <title>Eliminating Data Races in Firefox - A Technical Report - Mozilla Hacks - the Web developer blog</title> <meta name="description" content="We successfully deployed ThreadSanitizer in the Firefox project to eliminate data races in our remaining C/C++ components." /> <link rel="canonical" href="https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/" /> <meta name="twitter:label1" content="Written by" /> <meta name="twitter:data1" content="Christian Holler, Aria Beingessner, Kris Wright" /> <meta name="twitter:label2" content="Est. reading time" /> <meta name="twitter:data2" content="12 minutes" /> <script type="application/ld+json" class="yoast-schema-graph">{"@context":"https://schema.org","@graph":[{"@type":"WebPage","@id":"https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/","url":"https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/","name":"Eliminating Data Races in Firefox - A Technical Report - Mozilla Hacks - the Web developer blog","isPartOf":{"@id":"https://hacks.mozilla.org/#website"},"primaryImageOfPage":{"@id":"https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#primaryimage"},"image":{"@id":"https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#primaryimage"},"thumbnailUrl":"https://hacks.mozilla.org/wp-content/uploads/2021/03/tsan-sample-race.png","datePublished":"2021-04-06T15:21:46+00:00","dateModified":"2021-04-07T11:06:22+00:00","author":{"@id":"https://hacks.mozilla.org/#/schema/person/87357de5d3d1c796997db25508ea2927"},"description":"We successfully deployed ThreadSanitizer in the Firefox project to eliminate data races in our remaining C/C++ components.","breadcrumb":{"@id":"https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#primaryimage","url":"https://hacks.mozilla.org/wp-content/uploads/2021/03/tsan-sample-race.png","contentUrl":"https://hacks.mozilla.org/wp-content/uploads/2021/03/tsan-sample-race.png","width":1273,"height":668},{"@type":"BreadcrumbList","@id":"https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://hacks.mozilla.org/"},{"@type":"ListItem","position":2,"name":"Articles","item":"https://hacks.mozilla.org/articles/"},{"@type":"ListItem","position":3,"name":"Eliminating Data Races in Firefox – A Technical Report"}]},{"@type":"WebSite","@id":"https://hacks.mozilla.org/#website","url":"https://hacks.mozilla.org/","name":"Mozilla Hacks - the Web developer blog","description":"hacks.mozilla.org","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://hacks.mozilla.org/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https://hacks.mozilla.org/#/schema/person/87357de5d3d1c796997db25508ea2927","name":"Christian Holler","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https://hacks.mozilla.org/#/schema/person/image/f3a9ef9fb4976f62d7fbcbe9a4f0416d","url":"https://hacks.mozilla.org/wp-content/uploads/2024/06/cropped-export2-small-square-96x96.jpg","contentUrl":"https://hacks.mozilla.org/wp-content/uploads/2024/06/cropped-export2-small-square-96x96.jpg","caption":"Christian Holler"},"description":"Christian is a Firefox Tech Lead and Principal Engineer at Mozilla.","sameAs":["https://x.com/mozdeco"],"url":"https://hacks.mozilla.org/author/chollermozilla-com/"}]}</script> <!-- / Yoast SEO plugin. --> <link rel="alternate" type="application/rss+xml" title="Mozilla Hacks - the Web developer blog » Feed" href="https://hacks.mozilla.org/feed/" /> <link rel="alternate" type="application/rss+xml" title="Mozilla Hacks - the Web developer blog » Comments Feed" href="https://hacks.mozilla.org/comments/feed/" /> <link rel="alternate" type="application/rss+xml" title="Mozilla Hacks - the Web developer blog » Eliminating Data Races in Firefox – A Technical Report Comments Feed" href="https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/feed/" /> <link rel='stylesheet' id='wp-block-library-css' href='https://hacks.mozilla.org/wp-includes/css/dist/block-library/style.min.css?ver=6.6.1' type='text/css' media='all' /> <style id='co-authors-plus-coauthors-style-inline-css' type='text/css'> .wp-block-co-authors-plus-coauthors.is-layout-flow [class*=wp-block-co-authors-plus]{display:inline} </style> <style id='co-authors-plus-avatar-style-inline-css' type='text/css'> .wp-block-co-authors-plus-avatar :where(img){height:auto;max-width:100%;vertical-align:bottom}.wp-block-co-authors-plus-coauthors.is-layout-flow .wp-block-co-authors-plus-avatar :where(img){vertical-align:middle}.wp-block-co-authors-plus-avatar:is(.alignleft,.alignright){display:table}.wp-block-co-authors-plus-avatar.aligncenter{display:table;margin-inline:auto} </style> <style id='co-authors-plus-image-style-inline-css' type='text/css'> .wp-block-co-authors-plus-image{margin-bottom:0}.wp-block-co-authors-plus-image :where(img){height:auto;max-width:100%;vertical-align:bottom}.wp-block-co-authors-plus-coauthors.is-layout-flow .wp-block-co-authors-plus-image :where(img){vertical-align:middle}.wp-block-co-authors-plus-image:is(.alignfull,.alignwide) :where(img){width:100%}.wp-block-co-authors-plus-image:is(.alignleft,.alignright){display:table}.wp-block-co-authors-plus-image.aligncenter{display:table;margin-inline:auto} </style> <link rel='stylesheet' id='prismatic-blocks-css' href='https://hacks.mozilla.org/wp-content/plugins/prismatic/css/styles-blocks.css?ver=6.6.1' type='text/css' media='all' /> <style id='safe-svg-svg-icon-style-inline-css' type='text/css'> .safe-svg-cover{text-align:center}.safe-svg-cover .safe-svg-inside{display:inline-block;max-width:100%}.safe-svg-cover svg{height:100%;max-height:100%;max-width:100%;width:100%} </style> <style id='classic-theme-styles-inline-css' type='text/css'> /*! This file is auto-generated */ .wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none} </style> <style id='global-styles-inline-css' type='text/css'> :root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1);--wp--preset--shadow--crisp: 6px 6px 0px rgba(0, 0, 0, 1);}:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;} :where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;} :where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;} :root :where(.wp-block-pullquote){font-size: 1.5em;line-height: 1.6;} </style> <script type="text/javascript" src="https://hacks.mozilla.org/wp-includes/js/jquery/jquery.min.js?ver=3.7.1" id="jquery-core-js"></script> <script type="text/javascript" src="https://hacks.mozilla.org/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1" id="jquery-migrate-js"></script> <script type="text/javascript" src="https://hacks.mozilla.org/wp-content/themes/Hax/js/analytics.js?ver=6.6.1" id="analytics-js"></script> <link rel="https://api.w.org/" href="https://hacks.mozilla.org/wp-json/" /><link rel="alternate" title="JSON" type="application/json" href="https://hacks.mozilla.org/wp-json/wp/v2/posts/47163" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://hacks.mozilla.org/xmlrpc.php?rsd" /> <link rel='shortlink' href='https://hacks.mozilla.org/?p=47163' /> <link rel="alternate" title="oEmbed (JSON)" type="application/json+oembed" href="https://hacks.mozilla.org/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fhacks.mozilla.org%2F2021%2F04%2Feliminating-data-races-in-firefox-a-technical-report%2F" /> <link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="https://hacks.mozilla.org/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fhacks.mozilla.org%2F2021%2F04%2Feliminating-data-races-in-firefox-a-technical-report%2F&format=xml" /> </head> <body> <div class="outer-wrapper"> <header class="section section--fullwidth header"> <div class="masthead row"> <div class="branding block block--3"> <h1> <a href="https://hacks.mozilla.org"> <img class="branding__logo" src="https://hacks.mozilla.org/wp-content/themes/Hax/img/mdn-logo-mono.svg"> <img class="branding__wordmark" src="https://hacks.mozilla.org/wp-content/themes/Hax/img/wordmark.svg" alt="Mozilla"> <span class="branding__title">Hac<span class="logo-askew">k</span>s</span> </a> </h1> </div> <div class="search block block--2"> <form class="search__form" method="get" action="https://hacks.mozilla.org/"> <input type="search" name="s" class="search__input" placeholder="Search Mozilla Hacks" value=""> <i class="fa fa-search search__badge"></i> </form> </div> <nav class="social"> <a class="social__link youtube" href="http://www.youtube.com/user/mozhacks" title="YouTube"><i class="fa fa-youtube" aria-hidden="true"></i><span>Hacks on YouTube</span></a> <a class="social__link twitter" href="https://twitter.com/mozhacks" title="Twitter"><i class="fa fa-twitter" aria-hidden="true"></i><span>@mozhacks on Twitter</span></a> <a class="social__link rss" href="https://hacks.mozilla.org/feed/" title="RSS Feed"><i class="fa fa-rss" aria-hidden="true"></i><span>Hacks RSS Feed</span></a> <a class="fx-button" href="https://www.mozilla.org/firefox/download/thanks/?utm_source=hacks.mozilla.org&utm_medium=referral&utm_campaign=header-download-button&utm_content=header-download-button">Download Firefox</a> </nav> </div> </header> <div id="content-head" class="section"> <h1 class="post__title">Eliminating Data Races in Firefox – A Technical Report</h1> <div class="byline"> <h3 class="post__author"> <img alt='Avatar photo' src='https://hacks.mozilla.org/wp-content/uploads/2024/06/cropped-export2-small-square-64x64.jpg' srcset='https://hacks.mozilla.org/wp-content/uploads/2024/06/cropped-export2-small-square-128x128.jpg 2x' class='avatar avatar-64 photo' height='64' width='64' decoding='async'/> By <a class="url" href="https://hacks.mozilla.org/author/chollermozilla-com/">Christian Holler</a>, <a class="url" href="https://gankra.github.io/blah/" rel="external me">Aria Beingessner</a>, <a class="url" href="https://hacks.mozilla.org/author/kwrightmozilla-com/">Kris Wright</a> </h2> <div class="post__meta"> Posted on <abbr class="published" title="2021-04-06T08:21:46-07:00"> April 6, 2021 </abbr> <span class="entry-cat">in <a href="https://hacks.mozilla.org/category/developer-tools/" rel="category tag" title="View all posts in Developer Tools" >Developer Tools</a>, <a href="https://hacks.mozilla.org/category/featured/" rel="category tag" title="View all posts in Featured Article" >Featured Article</a>, <a href="https://hacks.mozilla.org/category/firefox/" rel="category tag" title="View all posts in Firefox" >Firefox</a>, and <a href="https://hacks.mozilla.org/category/security/" rel="category tag" title="View all posts in Security" >Security</a> </span> <div class="socialshare" data-type="bubbles"></div> </div> </div> </div> <main id="content-main" class="section article"> <article class="post" role="article"> <p>We successfully deployed <em>ThreadSanitizer</em> in the Firefox project to eliminate data races in our remaining C/C++ components. In the process, we found several impactful bugs and can safely say that data races are often underestimated in terms of their impact on program correctness. We recommend that all multithreaded C/C++ projects adopt the ThreadSanitizer tool to enhance code quality.<br /> <span id="more-47163"></span></p> <h2>What is ThreadSanitizer?</h2> <p><a href="https://clang.llvm.org/docs/ThreadSanitizer.html" target="_blank" rel="noopener">ThreadSanitizer</a> (TSan) is compile-time instrumentation to detect <i>data races</i> according to the <a href="https://en.cppreference.com/w/cpp/language/memory_model">C/C++ memory model</a> on Linux. It is important to note that these data races are considered <i>undefined behavior</i> within the C/C++ specification. As such, the compiler is free to assume that data races do not happen and perform optimizations under that assumption. Detecting bugs resulting from such optimizations can be hard, and data races often have an intermittent nature due to thread scheduling.</p> <p>Without a tool like ThreadSanitizer, even the most experienced developers can spend hours on locating such a bug. With ThreadSanitizer, you get a comprehensive data race report that often contains all of the information needed to fix the problem.</p> <p style="text-align: center;"><img decoding="async" src="https://hacks.mozilla.org/wp-content/uploads/2021/03/tsan-sample-race.png" alt="An example for a ThreadSanitizer report, showing where each thread is reading/writing, the location they both access and where the threads were created." width="636" height="50%" /> <small>ThreadSanitizer Output for <a href="https://gist.github.com/choller/d625ecb4f245a4f466758b00dc254291" target="_blank" rel="noopener">this example program</a> (shortened for article)</small></p> <p>One important property of TSan is that, when properly deployed, the data race detection does not produce false positives. This is incredibly important for tool adoption, as developers quickly lose faith in tools that produce uncertain results.</p> <p>Like other sanitizers, TSan is built into Clang and can be used with any recent Clang/LLVM toolchain. If your C/C++ project already uses e.g. AddressSanitizer (which we also highly recommend), deploying ThreadSanitizer will be very straightforward from a toolchain perspective.</p> <h2>Challenges in Deployment</h2> <h4>Benign vs. Impactful Bugs</h4> <p>Despite ThreadSanitizer being a very well designed tool, we had to overcome a variety of challenges at Mozilla during the deployment phase. The most significant issue we faced was that it is really difficult to prove that data races are actually harmful at all and that they impact the everyday use of Firefox. In particular, the term “<i>benign</i>” came up often. Benign data races acknowledge that a particular data race is actually a race, but assume that it does not have any negative side effects.</p> <p>While benign data races do exist, we found (in agreement with previous work on this subject <a href="https://software.intel.com/content/www/us/en/develop/blogs/benign-data-races-what-could-possibly-go-wrong.html">[1]</a> <a href="https://www.usenix.org/legacy/event/hotpar11/tech/final_files/Boehm.pdf">[2]</a>) that data races are very easily misclassified as benign. The reasons for this are clear: It is hard to reason about what compilers can and will optimize, and confirmation for certain “benign” data races requires you to look at the assembler code that the compiler finally produces.</p> <p>Needless to say, this procedure is often much more time consuming than fixing the actual data race and also not future-proof. As a result, we decided that the ultimate goal should be a <b>“no data races” policy</b> that declares even benign data races as undesirable due to their risk of misclassification, the required time for investigation and the potential risk from future compilers (with better optimizations) or future platforms (e.g. ARM).</p> <p>However, it was clear that establishing such a policy would require a lot of work, both on the technical side as well as in convincing developers and management. In particular, we could not expect a large amount of resources to be dedicated to fixing data races with no clear product impact. This is where TSan’s <b>suppression list</b> came in handy:</p> <p>We knew we had to stop the influx of new data races but at the same time get the tool usable without fixing all legacy issues. The suppression list (in particular <a href="https://searchfox.org/mozilla-central/rev/f47a4b67643b3048ef9a2e2ac0c34edf6d1ebff3/mozglue/build/TsanOptions.cpp">the version compiled into Firefox</a>) allowed us to temporarily ignore data races once we had them on file and ultimately <a href="https://treeherder.mozilla.org/jobs?repo=mozilla-central&searchStr=tsan" target="_blank" rel="noopener">bring up a TSan build of Firefox in CI</a> that would automatically avoid further regressions. Of course, security bugs required specialized handling, but were usually easy to recognize (e.g. racing on non-thread safe pointers) and were fixed quickly without suppressions.</p> <p>To help us understand the impact of our work, we maintained an internal list of all the most serious races that TSan detected (ones that had side-effects or could cause crashes). This data helped convince developers that the tool was making their lives easier while also clearly justifying the work to management.</p> <p>In addition to this qualitative data, we also decided for a more quantitative approach: We looked at all the bugs we found over a year and how they were classified. Of the 64 bugs we looked at, 34% were classified as “benign” and 22% were “impactful” (the rest hadn’t been classified).</p> <p>We knew there was a certain amount of misclassified benign issues to be expected, but what we really wanted to know was: Do benign issues pose a risk to the project? Assuming that all of these issues truly had no impact on the product, are we wasting a lot of resources on fixing them? Thankfully, we found that <b>the majority of these fixes were trivial and/or improved code quality</b>.</p> <p>The trivial fixes were mostly turning non-atomic variables into atomics (20%), adding permanent suppressions for upstream issues that we couldn’t address immediately (15%), or removing overly complicated code (20%). Only 45% of the benign fixes actually required some sort of more elaborate patch (as in, the diff was larger than just a few lines of code and did not just remove code).</p> <p>We concluded that the risk of benign issues being a major resource sink was not an issue and well acceptable for the overall gains that the project provided.</p> <h4>False Positives?</h4> <p>As mentioned in the beginning, TSan does not produce false positive data race reports <i>when properly deployed</i>, which includes instrumenting all code that is loaded into the process and avoiding primitives that TSan doesn’t understand (such as <a href="https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence">atomic fences</a>). For most projects these conditions are trivial, but larger projects like Firefox require a bit more work. Thankfully this work largely amounted to a few lines in TSan’s robust suppression system.</p> <p>Instrumenting all code in Firefox isn’t currently possible because it needs to use shared system libraries like GTK and X11. Fortunately, TSan offers the “called_from_lib” feature that can be used <a href="https://searchfox.org/mozilla-central/rev/f47a4b67643b3048ef9a2e2ac0c34edf6d1ebff3/mfbt/TsanOptions.h#42" target="_blank" rel="noopener">in the suppression list</a> to ignore any calls originating from those shared libraries. Our other major source of uninstrumented code was build flags not being properly passed around, which was especially problematic for Rust code (see the Rust section below).</p> <p>As for unsupported primitives, the only issue we ran into was the lack of support for fences. Most fences were the result of <a href="https://doc.rust-lang.org/1.50.0/src/alloc/sync.rs.html#1440-1468" target="_blank" rel="noopener">a standard atomic reference counting idiom</a> which could be trivially <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1600312" target="_blank" rel="noopener">replaced</a> with an atomic load in TSan builds. Unfortunately, fences are fundamental to the design of the <a href="https://crates.io/crates/crossbeam" target="_blank" rel="noopener">crossbeam crate</a> (a foundational concurrency library in Rust), and the only solution for this was <a href="https://github.com/crossbeam-rs/crossbeam/issues/589#issuecomment-720972996" target="_blank" rel="noopener">a suppression</a>.</p> <p>We also found that there is a (well known) <a href="https://github.com/google/sanitizers/issues/814" target="_blank" rel="noopener">false positive in deadlock detection</a> that is however very easy to spot and also does not affect data race detection/reporting at all. In a nutshell, any deadlock report that only involves a single thread is likely this false positive.</p> <p>The only true false positive we found so far turned out to be a rare bug in TSan and was fixed in the tool itself. However, developers <b>claimed</b> on various occasions that a particular report must be a false positive. In all of these cases, it turned out that TSan was indeed right and the problem was just very subtle and hard to understand. This is again confirming that we need tools like TSan to help us eliminate this class of bugs.</p> <h2>Interesting Bugs</h2> <p>Currently, the TSan bug-o-rama contains around 20 bugs. We’re still working on fixes for some of these bugs and would like to point out several particularly interesting/impactful ones.</p> <h4>Beware Bitfields</h4> <p>Bitfields are a handy little convenience to save space for storing lots of different small values. For instance, rather than having 30 bools taking up 240 bytes, they can all be packed into 4 bytes. For the most part this works fine, but it has one nasty consequence: different pieces of data now alias. This means that accessing “neighboring” bitfields is actually accessing the same memory, and therefore a potential data race.</p> <p>In practical terms, this means that if two threads are writing to two neighboring bitfields, one of the writes can get lost, as both of those writes are actually read-modify-write operations of all the bitfields:</p> <p><script src="https://gist.github.com/choller/daa318bcd343e0d4ab24281cdc4be453.js"></script></p> <p>If you’re familiar with bitfields and actively thinking about them, this might be obvious, but when you’re just saying myVal.isInitialized = true you may not think about or even realize that you’re accessing a bitfield.</p> <p>We have had many instances of this problem, but let’s look at <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1601940">bug 1601940</a> and its (trimmed) race report:</p> <p><script src="https://gist.github.com/choller/770be7221ad70e76b7fbd924424236fc.js"></script></p> <p>When we first saw this report, it was puzzling because the two threads in question touch different fields (<a href="https://searchfox.org/mozilla-central/rev/ea63a0888d406fae720cf24f4727d87569a8cab5/gfx/layers/apz/src/AsyncPanZoomController.h#1605" target="_blank" rel="noopener">mAsyncTransformAppliedToContent</a> vs. <a href="https://searchfox.org/mozilla-central/rev/ea63a0888d406fae720cf24f4727d87569a8cab5/gfx/layers/apz/src/AsyncPanZoomController.cpp#4218" target="_blank" rel="noopener">mTestAttributeAppliers</a>). However, as it turns out, these two fields are both <a href="https://searchfox.org/mozilla-central/rev/ea63a0888d406fae720cf24f4727d87569a8cab5/gfx/layers/apz/src/AsyncPanZoomController.h#1623-1626" target="_blank" rel="noopener">adjacent bitfields in the class</a>.</p> <p>This was causing intermittent failures in our CI and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1601940#c3" target="_blank" rel="noopener">cost a maintainer of this code valuable time</a>. We find this bug particularly interesting because it demonstrates how hard it is to diagnose data races without appropriate tooling and we found more instances of this type of bug (racy bitfield write/write) in our codebase. One of the other instances even had the potential to cause network loads to supply invalid cache content, another hard-to-debug situation, especially when it is intermittent and therefore not easily reproducible.</p> <p>We encountered this enough that we eventually introduced a <a href="https://searchfox.org/mozilla-central/rev/26330a08b1f9d06938faa0aa5e0f8c7a58064aa2/mfbt/AtomicBitfields.h" target="_blank" rel="noopener">MOZ_ATOMIC_BITFIELDS</a> macro that generates bitfields with atomic load/store methods. This allowed us to quickly fix problematic bitfields for the maintainers of each component without having to redesign their types.</p> <h4>Oops That Wasn’t Supposed To Be Multithreaded</h4> <p>We also found several instances of components which were explicitly designed to be single-threaded accidentally being used by multiple threads, such as <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1681950" target="_blank" rel="noopener">bug 1681950</a>:</p> <p><script src="https://gist.github.com/choller/cfc1611b3cf5f46c0bd68450e1d72abe.js"></script></p> <p>The race itself here is rather simple, we are racing on the same file through stat64 and understanding the report was not the problem this time. However, as can be seen from frame 10, this call originates from the <code>PreferencesWriter</code>, which is responsible for writing changes to the prefs.js file, the central storage for Firefox preferences.</p> <p>It was never intended for this to be called on multiple threads at the same time and we believe that this had the potential to corrupt the prefs.js file. As a result, during the next startup the file would fail to load and be discarded (reset to default prefs). Over the years, we’ve had quite a few bug reports related to this file magically losing its custom preferences but we were never able to find the root cause. We now believe that this bug is at least partially responsible for these losses.</p> <p>We think this is a particularly good example of a failure for two reasons: it was a race that had more harmful effects than just a crash, and it caught a larger logic error of something being used outside of its original design parameters.</p> <h4>Late-Validated Races</h4> <p>On several occasions we encountered a pattern that lies on the boundary of benign that we think merits some extra attention: intentionally racily reading a value, but then later doing checks that properly validate it. For instance, code like:</p> <p><script src="https://gist.github.com/choller/a76d62ec9b9635cbe289c3176a8c08f1.js"></script></p> <p>See for example, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1153409#c4" target="_blank" rel="noopener">this instance we encountered in SQLite</a>.</p> <p><i>Please Don’t Do This</i>. These patterns are really fragile and they’re ultimately undefined behavior, even if they <i>generally </i>work right. Just write proper atomic code — you’ll usually find that the performance is perfectly fine.</p> <h2>What about Rust?</h2> <p>Another difficulty that we had to solve during TSan deployment was due to part of our codebase now being written in Rust, which has much less mature support for sanitizers. This meant that we spent a significant portion of our bringup with all Rust code suppressed while that tooling was still being developed.</p> <p>We weren’t particularly concerned with our Rust code having a lot of races, but rather races in C++ code being obfuscated by passing through Rust. In fact, we strongly recommend writing new projects entirely in Rust to avoid data races altogether.</p> <p>The hardest part in particular is the need to rebuild the Rust standard library with TSan instrumentation. On nightly there is an unstable feature, -Zbuild-std, that lets us do exactly that, but it still has a lot of rough edges.</p> <p>Our biggest hurdle with build-std was that it’s currently incompatible with vendored build environments, which Firefox uses. Fixing this isn’t simple because cargo’s tools for patching in dependencies aren’t designed for affecting only a subgraph (i.e. just std and not your own code). So far, we have mitigated this by maintaining a small set of patches on top of rustc/cargo which implement this well-enough for Firefox but need <a href="https://github.com/rust-lang/wg-cargo-std-aware/issues/23">further work to go upstream</a>.</p> <p>But with build-std hacked into working for us we were able to instrument our Rust code and were happy to find that there were very few problems! Most of the things we discovered were C++ races that happened to pass through some Rust code and had therefore been hidden by our blanket suppressions.</p> <p>We did however find two pure Rust races:</p> <p>The first was <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1674770" target="_blank" rel="noopener">bug 1674770</a>, which was a bug in the parking_lot library. This Rust library provides synchronization primitives and other concurrency tools and is written and maintained by experts. We did not investigate the impact but the issue was a couple atomic orderings being too weak and <a href="https://github.com/Amanieu/parking_lot/pull/260" target="_blank" rel="noopener">was fixed</a> quickly by the authors. This is yet another example that proves how difficult it is to write bug-free concurrent code.</p> <p>The second was <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1686158" target="_blank" rel="noopener">bug 1686158</a>, which was some code in WebRender’s software OpenGL shim. They were maintaining some hand-rolled shared-mutable state using raw atomics for part of the implementation but forgot to make one of the fields atomic. This was easy enough to fix.</p> <p>Overall Rust appears to be fulfilling one of its original design goals: allowing us to write more concurrent code safely. Both WebRender and Stylo are very large and pervasively multi-threaded, but have had minimal threading issues. What issues we did find were mistakes in the implementations of low-level and explicitly unsafe multithreading abstractions — and those mistakes were simple to fix.</p> <p>This is in contrast to many of our C++ races, which often involved things being randomly accessed on different threads with unclear semantics, necessitating non-trivial refactorings of the code.</p> <h2>Conclusion</h2> <p>Data races are an underestimated problem. Due to their complexity and intermittency, we often struggle to identify them, locate their cause and judge their impact correctly. In many cases, this is also a time-consuming process, wasting valuable resources. ThreadSanitizer has proven to be not just <b>effective in locating data races </b>and<b> providing adequate debug information</b>, but also to be <b>practical</b> even on a project as large as Firefox.</p> <h2>Acknowledgements</h2> <p>We would like to thank the authors of ThreadSanitizer for providing the tool and in particular Dmitry Vyukov (Google) for helping us with some complex, Firefox-specific edge cases during deployment.</p> <section class="about"> <h2 class="about__header">About Christian Holler </h3> <p>Christian is a Firefox Tech Lead and Principal Engineer at Mozilla.</p> <ul class="author-meta fa-ul"><li><i class="fa-li fa fa-twitter"></i><a href="http://twitter.com/mozdeco" class="twitter" rel="me">@mozdeco</a></li></ul> <p><a class="url" href="https://hacks.mozilla.org/author/chollermozilla-com/">More articles by Christian Holler…</a></p> <h2 class="about__header">About <a class="url" href="https://gankra.github.io/blah/" rel="external me"> Aria Beingessner </a> </h3> <ul class="author-meta fa-ul"><li><i class="fa-li fa fa-globe"></i><a href="https://gankra.github.io/blah/" class="website" rel="me">https://gankra.github.io/blah/</a></li></ul> <p><a class="url" href="https://hacks.mozilla.org/author/abeingessnermozilla-com/">More articles by Aria Beingessner…</a></p> <h2 class="about__header">About Kris Wright </h3> <p><a class="url" href="https://hacks.mozilla.org/author/kwrightmozilla-com/">More articles by Kris Wright…</a></p> </section> </article> <section class="promo"> <form id="newsletterForm" name="newsletter-form" class="newsletter block block--1 block--polite" action="https://www.mozilla.org/en-US/newsletter/" method="post"> <h2 class="heading">Discover great resources for web development</h2> <p class="newsletter__description">Sign up for the Mozilla Developer Newsletter:</p> <input id="fmt" name="fmt" value="H" type="hidden"> <input id="newsletterNewslettersInput" name="newsletters" value="app-dev" type="hidden"> <div id="newsletterErrors" class="newsletter__errors"></div> <div id="newsletterEmail" class="form__row"> <label for="newsletterEmailInput" class="offscreen">E-mail</label> <input id="newsletterEmailInput" name="email" class="newsletter__input" required="" placeholder="you@example.com" size="30" type="email"> </div> <div id="newsletterPrivacy" class="form__row form__fineprint"> <input id="newsletterPrivacyInput" name="privacy" required="" type="checkbox"> <label for="newsletterPrivacyInput"> I'm okay with Mozilla handling my info as explained in this <a href="https://www.mozilla.org/privacy/">Privacy Policy</a>. </label> </div> <button id="newsletter-submit" type="submit" class="button positive">Sign up now</button> </form> <div id="newsletterThanks" class="newsletter newsletter--thanks block block--1 block--polite hidden"> <h2 class="heading">Thanks! Please check your inbox to confirm your subscription.</h2> <p>If you haven’t previously confirmed a subscription to a Mozilla-related newsletter you may have to do so. Please check your inbox or your spam filter for an email from us. </p> </div> </section> <section class="discussion"> <hr class="dino"> <div class="comments"> <header class="comments__head"> <h3>5 comments</h3> </header> <ol class="comments__list" class="hfeed"> <li id="comment-26951" class="comment even thread-even depth-1"> <b class="comment__title vcard"> <cite class="author fn">David</cite> </b> <blockquote class="comment__body"> <p>Why would 30 bools take up 240 bytes? That’s 8 bytes each. I would normally expect them to take up 1 byte each, for 30 bytes total. Using a basic 32 bit int (such as old Visual C++ used) would be 4 bytes each. Would it be using a full native pointer field per bool? That sounds insane.</p> </blockquote> <a class="comment__meta" href="https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#comment-26951" rel="bookmark" title="Permanent link to this comment by David"><abbr class="published" title="2021-04-06">April 6th, 2021</abbr> at 19:50</a> <p class="comment__util"> </p> </li><!-- #comment-## --> <li id="comment-26952" class="comment odd alt thread-odd thread-alt depth-1"> <b class="comment__title vcard"> <cite class="author fn">Juraj M.</cite> </b> <blockquote class="comment__body"> <p>Is there a timeline or plan to refactor everything to Rust?<br /> And how far are you now?</p> </blockquote> <a class="comment__meta" href="https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#comment-26952" rel="bookmark" title="Permanent link to this comment by Juraj M."><abbr class="published" title="2021-04-07">April 7th, 2021</abbr> at 00:13</a> <p class="comment__util"> </p> </li><!-- #comment-## --> <li id="comment-26954" class="comment even thread-even depth-1"> <b class="comment__title vcard"> <cite class="author fn">Louis</cite> </b> <blockquote class="comment__body"> <p>I’m not sure I understand why the MOZ_ATOMIC_BITFIELDS fix is needed. According to the linked C++ memory model[0], a memory location is “[…] the largest contiguous sequence of bit fields of non-zero length”. </p> <p>So redefining the bitfields to be split by dummy zero-length members would be enough to ensure that each bitfield is a separate location. It would avoid data races. </p> <p>The only issue I can think of is that the compiler might decide that the way to make this happen is to allocate each bitfield to a different byte, negating the size saving.</p> <p>What am I missing :) ?</p> <p>[0] <a href="https://en.cppreference.com/w/cpp/language/memory_model" rel="nofollow ugc">https://en.cppreference.com/w/cpp/language/memory_model</a></p> </blockquote> <a class="comment__meta" href="https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#comment-26954" rel="bookmark" title="Permanent link to this comment by Louis"><abbr class="published" title="2021-04-07">April 7th, 2021</abbr> at 03:59</a> <p class="comment__util"> </p> </li><!-- #comment-## --> <li id="comment-26958" class="comment odd alt thread-odd thread-alt depth-1"> <b class="comment__title vcard"> <cite class="author fn">Meder Bakirov</cite> </b> <blockquote class="comment__body"> <p>Linux Documentation:</p> <p><a href="https://github.com/torvalds/linux/blob/3a22981230f997846d1cfeb8eadcda8bcc0f7ea8/Documentation/memory-barriers.txt#L314" rel="nofollow ugc">https://github.com/torvalds/linux/blob/3a22981230f997846d1cfeb8eadcda8bcc0f7ea8/Documentation/memory-barriers.txt#L314</a></p> <p>(*) These guarantees do not apply to bitfields, because compilers often<br /> generate code to modify these using non-atomic read-modify-write<br /> sequences. Do not attempt to use bitfields to synchronize parallel<br /> algorithms.</p> </blockquote> <a class="comment__meta" href="https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#comment-26958" rel="bookmark" title="Permanent link to this comment by Meder Bakirov"><abbr class="published" title="2021-04-07">April 7th, 2021</abbr> at 15:35</a> <p class="comment__util"> </p> </li><!-- #comment-## --> <li id="comment-26962" class="comment even thread-even depth-1"> <b class="comment__title vcard"> <cite class="author fn">Steve Fink</cite> </b> <blockquote class="comment__body"> <p>Since both gcc and clang appear to support statement expressions, that racy-init.cpp could just do `static bool unused = ({ /* initialization code * });` and with c++11 or later, it would be threadsafe. (It’ll do an acquire/release to make sure the initialization happens once only.) Or you could declare an object that does the initialization in its constructor.</p> <p>So these days, it’d actually be easier to write a correct version. (If you happen to know the sekrit c++11 trick!)</p> </blockquote> <a class="comment__meta" href="https://hacks.mozilla.org/2021/04/eliminating-data-races-in-firefox-a-technical-report/#comment-26962" rel="bookmark" title="Permanent link to this comment by Steve Fink"><abbr class="published" title="2021-04-08">April 8th, 2021</abbr> at 11:42</a> <p class="comment__util"> </p> </li><!-- #comment-## --> </ol> </div> <p class="comments__closed"><b>Comments are closed for this article.</b></p> </main><!-- /#content-main --> <footer class="footer section section--fullwidth"> <div class="row"> <p class="block block--1"> Except where otherwise noted, content on this site is licensed under the <a href="https://creativecommons.org/licenses/by-sa/3.0/" rel="license external">Creative Commons Attribution Share-Alike License v3.0</a> or any later version. </p> <img class="footer__logo" alt="the Mozilla dino logo" src="https://hacks.mozilla.org/wp-content/themes/Hax/img/dino.svg"> </div> </footer> </div> <script> // External links should open in a new tab. (function () { var postLinks = document.querySelectorAll('#content-main a'); var origin = location.origin; for (var i = 0; i < postLinks.length; i++) { var link = postLinks[i]; if (link.origin !== origin && !link.getAttribute('target')) { link.setAttribute('target', '_blank'); } } })(); window.addEventListener('load', function () { if (document.querySelector('#newsletterForm')) { var script = document.createElement('script'); var path = document.head.getAttribute('data-template-path'); script.setAttribute('src', path + '/js/newsletter.js'); document.head.appendChild(script); } }); </script> </body> </html>