Skip to content

Commit

Permalink
Ball categorymanager data race (#3797)
Browse files Browse the repository at this point in the history
* ball_categorymanager atomic d_ruleSetSequenceNumber

* ball_category prevent data races surrounding d_relevantRuleMask

* ball_category PR fixes, relocate BSLMF_ASSERT

* ball_category PR fixes, relocate BSLMF_ASSERT headers
  • Loading branch information
jfevold-bbg authored and GitHub Enterprise committed Jul 6, 2022
1 parent a38bd15 commit a3b45e6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
10 changes: 9 additions & 1 deletion groups/bal/ball/ball_category.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ BSLS_IDENT_RCSID(ball_category_cpp,"$Id$ $CSID$")

#include <bslim_printer.h>

#include <bslmf_assert.h>
#include <bslmf_issame.h>

#include <bsls_assert.h>

#include <bsl_algorithm.h>
Expand All @@ -20,6 +23,10 @@ namespace ball {
// class Category
// --------------

// d_relevantRuleMask is semantically of type 'RuleSet::MaskType', but needs
// to be atomic. Assert that the type of 'RuleSet::MaskType' hasn't changed.
BSLMF_ASSERT((bsl::is_same<RuleSet::MaskType, unsigned int>::value));

// PRIVATE CREATORS
Category::Category(const char *categoryName,
int recordLevel,
Expand All @@ -38,10 +45,11 @@ Category::Category(const char *categoryName,
triggerAllLevel))
, d_categoryName(categoryName, basicAllocator)
, d_categoryHolder(0)
, d_relevantRuleMask(0)
, d_relevantRuleMask()
, d_ruleThreshold(0)
{
BSLS_ASSERT(categoryName);
bsls::AtomicOperations::initUint(&d_relevantRuleMask, 0);
}

// PRIVATE MANIPULATORS
Expand Down
35 changes: 28 additions & 7 deletions groups/bal/ball/ball_category.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class Category {

CategoryHolder *d_categoryHolder; // linked list of holders of this
// category
mutable RuleSet::MaskType
mutable bsls::AtomicOperations::AtomicTypes::Uint
d_relevantRuleMask; // the mask indicating which rules
// are relevant (i.e., have been
// attached to this category)
Expand Down Expand Up @@ -489,7 +489,7 @@ int Category::ruleThreshold() const
inline
RuleSet::MaskType Category::relevantRuleMask() const
{
return d_relevantRuleMask;
return bsls::AtomicOperations::getUintAcquire(&d_relevantRuleMask);
}

// --------------------
Expand Down Expand Up @@ -577,22 +577,43 @@ void CategoryManagerImpUtil::setRuleThreshold(Category *category,
inline
void CategoryManagerImpUtil::enableRule(Category *category, int ruleIndex)
{
category->d_relevantRuleMask =
bdlb::BitUtil::withBitSet(category->d_relevantRuleMask, ruleIndex);
unsigned int currentMask =
bsls::AtomicOperations::getUintRelaxed(&category->d_relevantRuleMask);
unsigned int expectedMask;
do {
const unsigned int updatedMask = bdlb::BitUtil::withBitSet(currentMask,
ruleIndex);
expectedMask = currentMask;
currentMask = bsls::AtomicOperations::testAndSwapUintAcqRel(
&category->d_relevantRuleMask,
currentMask,
updatedMask);
} while (expectedMask != currentMask);
}

inline
void CategoryManagerImpUtil::disableRule(Category *category, int ruleIndex)
{
category->d_relevantRuleMask =
bdlb::BitUtil::withBitCleared(category->d_relevantRuleMask, ruleIndex);
unsigned int currentMask =
bsls::AtomicOperations::getUintRelaxed(&category->d_relevantRuleMask);
unsigned int expectedMask;
do {
const unsigned int updatedMask =
bdlb::BitUtil::withBitCleared(currentMask, ruleIndex);
expectedMask = currentMask;
currentMask = bsls::AtomicOperations::testAndSwapUintAcqRel(
&category->d_relevantRuleMask,
currentMask,
updatedMask);
} while (expectedMask != currentMask);
}

inline
void CategoryManagerImpUtil::setRelevantRuleMask(Category *category,
RuleSet::MaskType mask)
{
category->d_relevantRuleMask = mask;
bsls::AtomicOperations::setUintRelease(&category->d_relevantRuleMask,
mask);
}

} // close package namespace
Expand Down
3 changes: 2 additions & 1 deletion groups/bal/ball/ball_categorymanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ BSLS_IDENT("$Id: $")
#include <bslmt_readlockguard.h>
#include <bslmt_readerwriterlock.h>

#include <bsls_atomic.h>
#include <bsls_types.h>

#include <bsl_map.h>
Expand All @@ -195,7 +196,7 @@ class CategoryManager {
// indices in
// 'd_categories'

volatile bsls::Types::Int64 d_ruleSetSequenceNumber;
bsls::AtomicInt64 d_ruleSetSequenceNumber;
// sequence number that
// is incremented each
// time the rule set is
Expand Down

0 comments on commit a3b45e6

Please sign in to comment.