X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FRWSpinLock.h;h=eea433cfd0d38374598596f05883873f89f3bfe3;hb=114e32af8fd5d8e04683df4073d73e0652f09fff;hp=2e7bbba2a27508fc3bba72e5c4aea029e1082245;hpb=99cbb9cec777f20b2f6f5cad92709f1a032f2ad8;p=folly.git diff --git a/folly/RWSpinLock.h b/folly/RWSpinLock.h index 2e7bbba2..eea433cf 100644 --- a/folly/RWSpinLock.h +++ b/folly/RWSpinLock.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2016 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,22 @@ */ /* + * N.B. You most likely do _not_ want to use RWSpinLock or any other + * kind of spinlock. Use SharedMutex instead. + * + * In short, spinlocks in preemptive multi-tasking operating systems + * have serious problems and fast mutexes like SharedMutex are almost + * certainly the better choice, because letting the OS scheduler put a + * thread to sleep is better for system responsiveness and throughput + * than wasting a timeslice repeatedly querying a lock held by a + * thread that's blocked, and you can't prevent userspace + * programs blocking. + * + * Spinlocks in an operating system kernel make much more sense than + * they do in userspace. + * + * ------------------------------------------------------------------- + * * Two Read-Write spin lock implementations. * * Ref: http://locklessinc.com/articles/locks @@ -24,12 +40,14 @@ * are very compact (4/8 bytes), so are suitable for per-instance * based locking, particularly when contention is not expected. * - * In most cases, RWSpinLock is a reasonable choice. It has minimal - * overhead, and comparable contention performance when the number of - * competing threads is less than or equal to the number of logical - * CPUs. Even as the number of threads gets larger, RWSpinLock can - * still be very competitive in READ, although it is slower on WRITE, - * and also inherently unfair to writers. + * For a spinlock, RWSpinLock is a reasonable choice. (See the note + * about for why a spin lock is frequently a bad idea generally.) + * RWSpinLock has minimal overhead, and comparable contention + * performance when the number of competing threads is less than or + * equal to the number of logical CPUs. Even as the number of + * threads gets larger, RWSpinLock can still be very competitive in + * READ, although it is slower on WRITE, and also inherently unfair + * to writers. * * RWTicketSpinLock shows more balanced READ/WRITE performance. If * your application really needs a lot more threads, and a @@ -63,8 +81,7 @@ * @author Xin Liu */ -#ifndef FOLLY_RWSPINLOCK_H_ -#define FOLLY_RWSPINLOCK_H_ +#pragma once /* ======================================================================== @@ -119,6 +136,7 @@ pthread_rwlock_t Read 728698 24us 101ns 7.28ms 194us */ #include +#include #if defined(__GNUC__) && \ (defined(__i386) || FOLLY_X64 || \ @@ -132,7 +150,7 @@ pthread_rwlock_t Read 728698 24us 101ns 7.28ms 194us #endif // iOS doesn't define _mm_cvtsi64_si128 and friends -#if (FOLLY_SSE >= 2) && !TARGET_OS_IPHONE +#if (FOLLY_SSE >= 2) && !FOLLY_MOBILE #define RW_SPINLOCK_USE_SSE_INSTRUCTIONS_ #else #undef RW_SPINLOCK_USE_SSE_INSTRUCTIONS_ @@ -439,12 +457,6 @@ class RWSpinLock { RWSpinLock* lock_; }; - // Synchronized<> adaptors - friend void acquireRead(RWSpinLock& l) { return l.lock_shared(); } - friend void acquireReadWrite(RWSpinLock& l) { return l.lock(); } - friend void releaseRead(RWSpinLock& l) { return l.unlock_shared(); } - friend void releaseReadWrite(RWSpinLock& l) { return l.unlock(); } - private: std::atomic bits_; }; @@ -742,20 +754,6 @@ class RWTicketSpinLockT { friend class ReadHolder; RWSpinLock *lock_; }; - - // Synchronized<> adaptors. - friend void acquireRead(RWTicketSpinLockT& mutex) { - mutex.lock_shared(); - } - friend void acquireReadWrite(RWTicketSpinLockT& mutex) { - mutex.lock(); - } - friend void releaseRead(RWTicketSpinLockT& mutex) { - mutex.unlock_shared(); - } - friend void releaseReadWrite(RWTicketSpinLockT& mutex) { - mutex.unlock(); - } }; typedef RWTicketSpinLockT<32> RWTicketSpinLock32; @@ -768,5 +766,3 @@ typedef RWTicketSpinLockT<64> RWTicketSpinLock64; #ifdef RW_SPINLOCK_USE_X86_INTRINSIC_ #undef RW_SPINLOCK_USE_X86_INTRINSIC_ #endif - -#endif // FOLLY_RWSPINLOCK_H_