I would start by debugging the locking code. One way you can do this using output messages and this usually called "printf debugging" since the implementations usually used printf. What I would do is add an output statement similar to what you have in
pop()
:
const T& pop() {
if (!peek()) {
return mEmpty;
}
std::lock_guard<std::mutex> lock(mLock);
if (!peek()) {
return mEmpty;
}
auto masked = mReadPtr & mRingModMask;
std::cout << "task " << taskId << " has acquired the lock and processing " << masked << std::endl << std::flush;
T& ret = mMem[ masked ];
mReadPtr++;
std::cout << "task " << taskId << " is releasing the lock" << std::endl << std::flush;
return ret;
}
then run your program a bit and see if you have interleaved messages. This would indicate the lock is not working correctly. What I mean by interleaved is you should see messages from the same task acquiring and then releasing the lock but if you see messages from other tasks acquiring the lock then you know you have a problem.
If the lock appears to be working correctly then have a look at your use of the
mMem
array's indexes. A segmentation fault can be caused by an invalid array index such as a negative value or one that exceeds
SIZE
. The reason I split out the array index to a variable called
masked
is so you can output its value. You might want to output this in other places too.
One thing that could be happening is your friends machine could be much slower or much faster than yours and it is exacerbating a flaw in your code.
I hope this is helpful for you.