-
Notifications
You must be signed in to change notification settings - Fork 196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use simple mutexes for cases where RDLOCK is not native. #23
Conversation
This is exactly the same as using two mutexes because for RDLOCK you do LOCK(lock->read); for WRLOCK you do LOCK(lock->read); the second lock on ->write is irrelevant because it exists within this mutex always. So it is simpler & faster to use just a single lock. Once that is in place, the RDLOCK for the native READLOCK has a race condition ref_count++ | ref_count-- for the cache entry can run in two parallel processes with ambigous results. The gcc/vc++ intrinsics for the atomic increments remove this race condition __sync_add_and_fetch(ref_count) | __sync_sub_and_fetch(ref_count) will run safely in parallel, as they lock each other out during the read-modify-write sections.
The reason two mutex are used is to simplify logic, assume a rwlock always exists, and prefer readers. If you can produce test results that I can see that say that using a single mutex keeps the application moving faster I'd be interested to see them, but during testing it did not seem to be the case. |
is not compatable with APC
To avoid negative now - dtime, now should be updated as often as possible. A cache item could be deleted by another thread/process.
@t3rmin4t0r and @weltling It does appear, on 'code' examination that most of the above have been included in the later releases (in various misc. modified code additions)! So why is this pull #23 still showing a open status? |
I have implemented the simpler mutex for seven branch, I'm still looking at the other race condition thing ... I will eventually backport to 5 branch before doing a final release for 5 series ... |
The seven branch now has these, and hopefully some other problems solved ... |
@t3rmin4t0r omg ... I just realised what this was trying to fix ... I feel stupid ... |
I've genuinely fixed it now ... @t3rmin4t0r I just didn't realise I had omitted to put the atomics back in when I tore apart APC to make APCu ... a stupid stupid mistake, my fault ... |
This is exactly the same as using two mutexes because
for RDLOCK you do
LOCK(lock->read);
for WRLOCK you do
LOCK(lock->read);
the second lock on ->write is irrelevant because it exists within this mutex always.
So it is simpler & faster to use just a single lock.
Once that is in place, the RDLOCK for the native READLOCK has a race condition
ref_count++ | ref_count--
for the cache entry can run in two parallel processes with ambigous results.
The gcc/vc++ intrinsics for the atomic increments remove this race condition
__sync_add_and_fetch(ref_count) | __sync_sub_and_fetch(ref_count)
will run safely in parallel, as they lock each other out during the read-modify-write sections.