[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCHv1 4/4] spinlock: add fair read-write locks
>>> On 18.12.15 at 15:09, <david.vrabel@xxxxxxxxxx> wrote: > +/** > + * rspin_until_writer_unlock - inc reader count & spin until writer is gone Stale comment - the function doesn't increment anything. Also throughout the file, with Linux coding style converted to Xen style, comment style should be made Xen-like too. > + /* > + * Readers come here when they cannot get the lock without waiting > + */ > + if ( unlikely(in_irq()) ) > + { > + /* > + * Readers in interrupt context will spin until the lock is > + * available without waiting in the queue. > + */ > + smp_rmb(); > + cnts = atomic_read(&lock->cnts); > + rspin_until_writer_unlock(lock, cnts); > + return; > + } I can't immediately see the reason for this re-introduction of unfairness - can you say a word on this, or perhaps extend the comment? > +/** > + * queue_write_lock_slowpath - acquire write lock of a queue rwlock > + * @lock : Pointer to queue rwlock structure > + */ > +void queue_write_lock_slowpath(rwlock_t *lock) > { > - _read_unlock(lock); > - local_irq_enable(); > -} > + u32 cnts; > > -void _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) > -{ > - _read_unlock(lock); > - local_irq_restore(flags); > -} > + /* Put the writer into the wait queue */ > + spin_lock(&lock->lock); > > -void _write_lock(rwlock_t *lock) > -{ > - uint32_t x; > + /* Try to acquire the lock directly if no reader is present */ > + if ( !atomic_read(&lock->cnts) && > + (atomic_cmpxchg(&lock->cnts, 0, _QW_LOCKED) == 0) ) > + goto unlock; > > - check_lock(&lock->debug); > - do { > - while ( (x = lock->lock) & RW_WRITE_FLAG ) > - cpu_relax(); > - } while ( cmpxchg(&lock->lock, x, x|RW_WRITE_FLAG) != x ); > - while ( x != 0 ) > + /* > + * Set the waiting flag to notify readers that a writer is pending, > + * or wait for a previous writer to go away. > + */ > + for (;;) > { > - cpu_relax(); > - x = lock->lock & ~RW_WRITE_FLAG; > - } > - preempt_disable(); > -} > - > -void _write_lock_irq(rwlock_t *lock) > -{ > - uint32_t x; > + cnts = atomic_read(&lock->cnts); > + if ( !(cnts & _QW_WMASK) && > + (atomic_cmpxchg(&lock->cnts, cnts, > + cnts | _QW_WAITING) == cnts) ) > + break; Considering that (at least on x86) cmpxchg is relatively expensive, and that atomic OR would be carried out by some cmpxchg-like mechanism on most other arches anyway, can't this be an atomic OR, followed by a read to check for another active writer? > +unlock: > + spin_unlock(&lock->lock); Labels indented by at least one space please. Also - are you using any of the static functions in spinlock.c? If not, putting the rwlock code in a new rwlock.c would help review quite a bit, since code removal and code addition would then be separate rather than intermixed. > +/* > + * Writer states & reader shift and bias > + */ > +#define _QW_WAITING 1 /* A writer is waiting */ > +#define _QW_LOCKED 0xff /* A writer holds the lock */ > +#define _QW_WMASK 0xff /* Writer mask */ > +#define _QR_SHIFT 8 /* Reader count shift */ > +#define _QR_BIAS (1U << _QR_SHIFT) Is there a particular reason for the 8-bit writer mask (a 2-bit one would seem to suffice)? > +static inline int _write_trylock(rwlock_t *lock) > +{ > + u32 cnts; > + > + cnts = atomic_read(&lock->cnts); > + if ( unlikely(cnts) ) > + return 0; > + > + return likely(atomic_cmpxchg(&lock->cnts, > + cnts, cnts | _QW_LOCKED) == cnts); The | is pointless here considering that cnts is zero. > +static inline void _write_unlock(rwlock_t *lock) > +{ > + /* > + * If the writer field is atomic, it can be cleared directly. > + * Otherwise, an atomic subtraction will be used to clear it. > + */ > + atomic_sub(_QW_LOCKED, &lock->cnts); > +} Ah, I guess the comment here is the explanation for the 8-bit write mask. > +static inline int _rw_is_write_locked(rwlock_t *lock) > +{ > + return atomic_read(&lock->cnts) & _QW_WMASK; > +} This returns true for write-locked or writer-waiting - is this intended? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |