Assert in rtllocks.cpp LockQueueNode::Copy() function when using recursive_timed_mutex
-
jueves, 19 de abril de 2012 20:09
On my system the following code causes an assert to fire in a Debug build in the CRT file rtlocks.cpp, line 754, in the function Concurrency::details::LockQueueNode::Copy(). In my test If I reduce the number of threads to thread::hardware_concurrency() I don't see the assert fire but I'm not sure if the problem is just less frequent with fewer threads or if it actually goes away. Am I doing something unsafe in this code or is this an issue with the Concurrency Runtime?
#include <chrono> #include <thread> #include <mutex> #include <atomic> #include <vector> #include <iostream> #include <algorithm> #include <cstdlib> #include <cassert> using namespace std; using namespace std::chrono; struct WorkData { atomic<bool> mbShouldQuit; recursive_timed_mutex mMutex; WorkData() : mbShouldQuit(false) {} }; void ThreadSleepRandom(int minSleepMs, int maxSleepMs) { int sleepTimeMs = minSleepMs; if ((maxSleepMs - minSleepMs) > 0) sleepTimeMs += (rand() % (maxSleepMs - minSleepMs)); this_thread::sleep_for(milliseconds(sleepTimeMs)); } intptr_t MutexTestThreadFunction(WorkData* pWorkData) { while (!pWorkData->mbShouldQuit) { const int nRecursiveLockCount(rand() % 3); int nLocks = 0; for (int i = 0; i < nRecursiveLockCount; ++i) { // Do a lock but allow for the possibility of occasional timeout. const auto expectedTime(system_clock::now() + milliseconds(1000)); if (pWorkData->mMutex.try_lock_until(expectedTime)) // If there was no timeout... { ++nLocks; ThreadSleepRandom(10, 20); } } while (nLocks > 0) { --nLocks; pWorkData->mMutex.unlock(); } ThreadSleepRandom(100, 200); } return 0; } void TestThreadMutex() { cout << "Starting " __FUNCTION__ << endl; WorkData workData; const int kThreadCount = 16; vector<thread> threads; for (int i = 0; i < kThreadCount; ++i) { threads.emplace_back(MutexTestThreadFunction, &workData); } const auto testLengthSeconds = 1; ThreadSleepRandom(testLengthSeconds*1000, testLengthSeconds*1000); workData.mbShouldQuit = true; for_each(begin(threads), end(threads), [](thread& t) { t.join(); }); cout << "Ending " __FUNCTION__ << endl << endl; } int main() { TestThreadMutex(); return 0; }
- Editado mattnewport jueves, 19 de abril de 2012 20:11 Removed redundant code
Todas las respuestas
-
jueves, 26 de abril de 2012 19:44
Hi mattnewport,
I believe this is caused by a known internal bug in concurrency::critical_section, which we are working on solution.
thanks for your dogfooding.
Hong
- Marcado como respuesta mattnewport jueves, 26 de abril de 2012 19:54

