@ -89,8 +89,6 @@ static void CheckSumG0G1(void *v) {
}
static void TestMu ( TestContext * cxt , int c ) {
SetInvariantChecked ( false ) ;
cxt - > mu . EnableInvariantDebugging ( CheckSumG0G1 , cxt ) ;
for ( int i = 0 ; i ! = cxt - > iterations ; i + + ) {
absl : : MutexLock l ( & cxt - > mu ) ;
int a = cxt - > g0 + 1 ;
@ -100,8 +98,6 @@ static void TestMu(TestContext *cxt, int c) {
}
static void TestTry ( TestContext * cxt , int c ) {
SetInvariantChecked ( false ) ;
cxt - > mu . EnableInvariantDebugging ( CheckSumG0G1 , cxt ) ;
for ( int i = 0 ; i ! = cxt - > iterations ; i + + ) {
do {
std : : this_thread : : yield ( ) ;
@ -122,8 +118,6 @@ static void TestR20ms(TestContext *cxt, int c) {
}
static void TestRW ( TestContext * cxt , int c ) {
SetInvariantChecked ( false ) ;
cxt - > mu . EnableInvariantDebugging ( CheckSumG0G1 , cxt ) ;
if ( ( c & 1 ) = = 0 ) {
for ( int i = 0 ; i ! = cxt - > iterations ; i + + ) {
absl : : WriterMutexLock l ( & cxt - > mu ) ;
@ -356,67 +350,57 @@ static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
cv - > Signal ( ) ;
}
// Basis for the parameterized tests configured below.
static int RunTest ( void ( * test ) ( TestContext * cxt , int ) , int threads ,
int iterations , int operations ) {
TestContext cxt ;
// Code common to RunTest() and RunTestWithInvariantDebugging().
static int RunTestCommon ( TestContext * cxt , void ( * test ) ( TestContext * cxt , int ) ,
int threads , int iterations , int operations ) {
absl : : Mutex mu2 ;
absl : : CondVar cv2 ;
int c0 ;
int c1 ;
// run with large thread count for full test and to get timing
# if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
absl : : EnableMutexInvariantDebugging ( false ) ;
# endif
c0 = 0 ;
c1 = 0 ;
cxt . g0 = 0 ;
cxt . g1 = 0 ;
cxt . iterations = iterations ;
cxt . threads = threads ;
int c0 = 0 ;
int c1 = 0 ;
cxt - > g0 = 0 ;
cxt - > g1 = 0 ;
cxt - > iterations = iterations ;
cxt - > threads = threads ;
absl : : synchronization_internal : : ThreadPool tp ( threads ) ;
for ( int i = 0 ; i ! = threads ; i + + ) {
tp . Schedule ( std : : bind ( & EndTest , & c0 , & c1 , & mu2 , & cv2 ,
std : : function < void ( int ) > (
std : : bind ( test , & cxt , std : : placeholders : : _1 ) ) ) ) ;
std : : bind ( test , cxt , std : : placeholders : : _1 ) ) ) ) ;
}
mu2 . Lock ( ) ;
while ( c1 ! = threads ) {
cv2 . Wait ( & mu2 ) ;
}
mu2 . Unlock ( ) ;
int saved_g0 = cxt . g0 ;
return cxt - > g0 ;
}
// run again with small number of iterations to test invariant checking
// Basis for the parameterized tests configured below.
static int RunTest ( void ( * test ) ( TestContext * cxt , int ) , int threads ,
int iterations , int operations ) {
TestContext cxt ;
return RunTestCommon ( & cxt , test , threads , iterations , operations ) ;
}
// Like RunTest(), but sets an invariant on the tested Mutex and
// verifies that the invariant check happened. The invariant function
// will be passed the TestContext* as its arg and must call
// SetInvariantChecked(true);
# if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
static int RunTestWithInvariantDebugging ( void ( * test ) ( TestContext * cxt , int ) ,
int threads , int iterations ,
int operations ,
void ( * invariant ) ( void * ) ) {
absl : : EnableMutexInvariantDebugging ( true ) ;
# endif
SetInvariantChecked ( true ) ;
c0 = 0 ;
c1 = 0 ;
cxt . g0 = 0 ;
cxt . g1 = 0 ;
cxt . iterations = ( iterations > 10 ? 10 : iterations ) ;
cxt . threads = threads ;
for ( int i = 0 ; i ! = threads ; i + + ) {
tp . Schedule ( std : : bind ( & EndTest , & c0 , & c1 , & mu2 , & cv2 ,
std : : function < void ( int ) > (
std : : bind ( test , & cxt , std : : placeholders : : _1 ) ) ) ) ;
}
mu2 . Lock ( ) ;
while ( c1 ! = threads ) {
cv2 . Wait ( & mu2 ) ;
}
mu2 . Unlock ( ) ;
# if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
SetInvariantChecked ( false ) ;
TestContext cxt ;
cxt . mu . EnableInvariantDebugging ( invariant , & cxt ) ;
int ret = RunTestCommon ( & cxt , test , threads , iterations , operations ) ;
ABSL_RAW_CHECK ( GetInvariantChecked ( ) , " Invariant not checked " ) ;
# endif
return saved_g0 ;
absl : : EnableMutexInvariantDebugging ( false ) ; // Restore.
return ret ;
}
# endif
// --------------------------------------------------------
// Test for fix of bug in TryRemove()
@ -1463,6 +1447,13 @@ TEST_P(MutexVariableThreadCountTest, Mutex) {
int iterations = ScaleIterations ( 10000000 ) / threads ;
int operations = threads * iterations ;
EXPECT_EQ ( RunTest ( & TestMu , threads , iterations , operations ) , operations ) ;
# if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
iterations = std : : min ( iterations , 10 ) ;
operations = threads * iterations ;
EXPECT_EQ ( RunTestWithInvariantDebugging ( & TestMu , threads , iterations ,
operations , CheckSumG0G1 ) ,
operations ) ;
# endif
}
TEST_P ( MutexVariableThreadCountTest , Try ) {
@ -1470,6 +1461,13 @@ TEST_P(MutexVariableThreadCountTest, Try) {
int iterations = 1000000 / threads ;
int operations = iterations * threads ;
EXPECT_EQ ( RunTest ( & TestTry , threads , iterations , operations ) , operations ) ;
# if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
iterations = std : : min ( iterations , 10 ) ;
operations = threads * iterations ;
EXPECT_EQ ( RunTestWithInvariantDebugging ( & TestTry , threads , iterations ,
operations , CheckSumG0G1 ) ,
operations ) ;
# endif
}
TEST_P ( MutexVariableThreadCountTest , R20ms ) {
@ -1484,6 +1482,13 @@ TEST_P(MutexVariableThreadCountTest, RW) {
int iterations = ScaleIterations ( 20000000 ) / threads ;
int operations = iterations * threads ;
EXPECT_EQ ( RunTest ( & TestRW , threads , iterations , operations ) , operations / 2 ) ;
# if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
iterations = std : : min ( iterations , 10 ) ;
operations = threads * iterations ;
EXPECT_EQ ( RunTestWithInvariantDebugging ( & TestRW , threads , iterations ,
operations , CheckSumG0G1 ) ,
operations / 2 ) ;
# endif
}
TEST_P ( MutexVariableThreadCountTest , Await ) {