Skip to content

Commit 8207d38

Browse files
committed
ARCv3: optimize rw lock in case of implementation with SW spinlocks
Micro optimizations of rw locks implementation with SW spinlocks. Poll rw-lock without spinlocks on each iteration. Don't use spinlock and don't turn IRQs off until not decide to write. Signed-off-by: Pavel Kozlov <pavel.kozlov@synopsys.com>
1 parent 825b43e commit 8207d38

File tree

1 file changed

+22
-24
lines changed

1 file changed

+22
-24
lines changed

arch/arc/include/asm/spinlock.h

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -299,22 +299,23 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
299299
{
300300
int ret = 0;
301301
unsigned long flags;
302-
303-
local_irq_save(flags);
304-
arch_spin_lock(&(rw->lock_mutex));
302+
int old = rw->counter;
305303

306304
/*
307305
* zero means writer holds the lock exclusively, deny Reader.
308306
* Otherwise grant lock to first/subseq reader
309307
*/
310-
if (rw->counter > 0) {
311-
rw->counter--;
312-
ret = 1;
308+
if (old > 0) {
309+
local_irq_save(flags);
310+
arch_spin_lock(&(rw->lock_mutex));
311+
if (rw->counter == old) {
312+
rw->counter--;
313+
ret = 1;
314+
}
315+
arch_spin_unlock(&(rw->lock_mutex));
316+
local_irq_restore(flags);
313317
}
314318

315-
arch_spin_unlock(&(rw->lock_mutex));
316-
local_irq_restore(flags);
317-
318319
return ret;
319320
}
320321

@@ -323,22 +324,19 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
323324
{
324325
int ret = 0;
325326
unsigned long flags;
326-
327-
local_irq_save(flags);
328-
arch_spin_lock(&(rw->lock_mutex));
329-
330-
/*
331-
* If reader(s) hold lock (lock < __ARCH_RW_LOCK_UNLOCKED__),
332-
* deny writer. Otherwise if unlocked grant to writer
333-
* Hence the claim that Linux rwlocks are unfair to writers.
334-
* (can be starved for an indefinite time by readers).
335-
*/
336-
if (rw->counter == __ARCH_RW_LOCK_UNLOCKED__) {
337-
rw->counter = 0;
338-
ret = 1;
327+
int old = rw->counter;
328+
329+
if (old == __ARCH_RW_LOCK_UNLOCKED__) {
330+
local_irq_save(flags);
331+
arch_spin_lock(&(rw->lock_mutex));
332+
333+
if (rw->counter == old) {
334+
rw->counter = 0;
335+
ret = 1;
336+
}
337+
arch_spin_unlock(&(rw->lock_mutex));
338+
local_irq_restore(flags);
339339
}
340-
arch_spin_unlock(&(rw->lock_mutex));
341-
local_irq_restore(flags);
342340

343341
return ret;
344342
}

0 commit comments

Comments
 (0)