update folly::RWSpinLock
update folly::RWSpinLock

1. add sched_yield in RWTicketSpinLock

Summary:
This diff makes RWTicketSpinLock eventually start calling
sched_yield() during shared and aggressive exclusive lock access, to
avoid pathologies that can arise when the number of threads far
exceeds the number of actual cores.

2. Fixed a potential deadlock in folly::RWSpinLock

Summary:
The current UpgradedHolder implementation may lead to a deadlock when upgrading from a reader lock, because it is blocking.

A reader that has failed to set the UPGRADED bit may block the
winner (upgrader) that has successfully set the UPGRADED bit, while
waiting to upgrade in an infinite loop without releasing its own
reader lock. The upgrader needs to wait for all reader locks to be
released before it can move forward.

This is the code pattern:

{
ReadHolder reader(lock);
UpgradedHolder upgrader(std::move(reader));
WriteHolder writer(std::move(upgrader));
}

To avoid this to happen, removed UpgradedHolder(ReadHolder&&)
constructor and the function that impelments it
unlock_shared_and_lock_upgrade. This would require a programmer explicitly
release a read lock before acquiring an upgrade lock, therefore
avoid the above mentioned deadlock.

In addition, the current folly::RWSpinLock::try_lock_shared()
implementation does not check the UPGRADED bit at all. The UPGRADED bit can be used to avoid starving writers.  This diff fixed this by correctly checking the UPGRADED bit.

pombredanne/izenelib,pombredanne/izenelib,izenecloud/izenelib,izenecloud/izenelib,pombredanne/izenelib,izenecloud/izenelib,izenecloud/izenelib,pombredanne/izenelib