Commit 5f4bb2cd authored by Matthew Fernandez's avatar Matthew Fernandez
Browse files

move migration counter reset to rendezvous interstice

OK, let's unpack that cryptic headline a little... When the seen set exceeds a
certain capacity, it gets expanded. The new set is allocated by one thread and
then all threads participate in the migration of the contents of the old set to
the new one. To arbitrate which thread is operating on any particular chunk of
the old set they use a shared counter, next_migration.

Prior to this commit, the counter was reset immediately preceding a migration.
Following this commit, we do the reset at the other end, after a migration. It
should be clear that the reset has to happen some time (so the counter starts at
zero the next time the set needs to be expanded) but it is valid to do it at
either end. The motivation for moving it to the end, is that we can do it in a
single-threaded context. This is during what I've referred to above as the
"rendezvous interstice." All threads arrive at the post-migration rendezvous
point and block on a condition variable. The last thread to arrive is designated
the "leader" and allowed a window of single-threaded execution before unblocking
all the "followers." By putting the reset in this window, we guarantee it gets
done in a way that (a) will not affect any ongoing migrations and (b) will be
observable by all other threads at the start of the next migration.

"But why did it need to move?" I hear you ask. It was already in a location that
was a single-threaded context enforced by the set expansion mutex. Well, we are
about to introduce an optimisation based on double-checked locking that allows
threads to observe a set expansion has already started without acquiring the set
expansion mutex. That is, they will be able to enter set_migrate having never
acquired the set expansion mutex. This means, if the counter reset was left
where it was, they could start migration work before the counter had been reset.
This could be resolved by moving the counter reset ahead of the write to
next_global_seen (what the DCLP check looks at) and adding some memory barriers
but it's simpler to just move the reset out of this path to a safer location
altogether.

Github: related to #104 "remove set_expand_lock?"
parent 022c3708
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment