Last active
December 19, 2015 01:19
-
-
Save awreece/5874585 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
increment_version() // Block all incoming readers. | |
while (num_readers() != 0) {} // Wait for all current readers to finish. | |
old_val = val | |
val = NULL | |
increment_version() // Allow readers again. | |
if old_val->refcount == 1 | |
free(old_val) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Top: | |
while ((version = read_version()) & 1) {} // Wait for there to be no writers. | |
// BUG(awreece) There is a race here - if a writer comes in at the last moment | |
// when there were previously no readers, it would assume there were | |
// no readers and the reader would assume there were no writers. | |
increment_num_readers() // Tell the world there is one more reader. | |
ret_val = val | |
ret_val->ref_count++ // Incr refcount before signalling writers. | |
memory_barrier() // Make sure the world can see the bump to refcount before they see we're done. | |
decrement_num_readers() | |
if (read_version() != version) { | |
if (--ret_val->ref_count == 0) | |
free(ret_val) // We may have to clean up after racing with a delete. | |
goto Top | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I feel like I really just wanted an rwspinlock. A nice rwlock implementation I saw recently was the Go rwlock which reduces the no contention reader case to a single pair of atomic adds: