/** Increments counter once for each iteration in the iteration space. */ void operator()( tbb::blocked_range<size_t>& range ) const { for( size_t i=range.begin(); i!=range.end(); ++i ) { //! Every 8th access is a write access const bool write = (i%8)==7; bool okay = true; bool lock_kept = true; if( (i/8)&1 ) { // Try implicit acquire and explicit release typename I::mutex_type::scoped_lock lock(invariant.mutex,write); execute_aux(lock, i, write, /*ref*/okay, /*ref*/lock_kept); lock.release(); } else { // Try explicit acquire and implicit release typename I::mutex_type::scoped_lock lock; lock.acquire(invariant.mutex,write); execute_aux(lock, i, write, /*ref*/okay, /*ref*/lock_kept); } if( !okay ) { REPORT( "ERROR for %s at %ld: %s %s %s %s\n",invariant.mutex_name, long(i), write ? "write," : "read,", write ? (i%16==7?"downgrade,":"") : (i%8==3?"upgrade,":""), lock_kept ? "lock kept," : "lock not kept,", // TODO: only if downgrade/upgrade (i/8)&1 ? "impl/expl" : "expl/impl" ); } } }
/** Increments counter once for each iteration in the iteration space. */ void operator()( tbb::blocked_range<size_t>& range ) const { for( size_t i=range.begin(); i!=range.end(); ++i ) { //! Every 8th access is a write access bool write = (i%8)==7; bool okay = true; bool lock_kept = true; if( (i/8)&1 ) { // Try implicit acquire and explicit release typename I::mutex_type::scoped_lock lock(invariant.mutex,write); if( write ) { long my_value = invariant.value[0]; invariant.update(); if( i%16==7 ) { lock_kept = lock.downgrade_to_reader(); if( !lock_kept ) my_value = invariant.value[0] - 1; okay = invariant.value_is(my_value+1); } } else { okay = invariant.is_okay(); if( i%8==3 ) { long my_value = invariant.value[0]; lock_kept = lock.upgrade_to_writer(); if( !lock_kept ) my_value = invariant.value[0]; invariant.update(); okay = invariant.value_is(my_value+1); } } lock.release(); } else { // Try explicit acquire and implicit release typename I::mutex_type::scoped_lock lock; lock.acquire(invariant.mutex,write); if( write ) { long my_value = invariant.value[0]; invariant.update(); if( i%16==7 ) { lock_kept = lock.downgrade_to_reader(); if( !lock_kept ) my_value = invariant.value[0] - 1; okay = invariant.value_is(my_value+1); } } else { okay = invariant.is_okay(); if( i%8==3 ) { long my_value = invariant.value[0]; lock_kept = lock.upgrade_to_writer(); if( !lock_kept ) my_value = invariant.value[0]; invariant.update(); okay = invariant.value_is(my_value+1); } } } if( !okay ) { STD::printf( "ERROR for %s at %ld: %s %s %s %s\n",invariant.mutex_name, long(i), write?"write,":"read,", write?(i%16==7?"downgrade,":""):(i%8==3?"upgrade,":""), lock_kept?"lock kept,":"lock not kept,", (i/8)&1?"imp/exp":"exp/imp" ); } } }