[PATCH] replace global semaphore_wake_lock with per-instance locking

Manfred Spraul (manfreds@colorfullife.com)
Sat, 07 Aug 1999 18:55:50 +0200


This is a multi-part message in MIME format.
--------------517FC07920B7D7CEEC9F0006
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I noticed that the current semaphore implementation uses a global
spinlock, but OTHO, the wait queue head which is part of every semaphore
contains a per-instance spinlock.

I haven't done any benchmarks, but I'm sure there will be lots of cache
line contention for the current global spinlock, so this patch replaces
the global spinlock with a per-instance spinlock.

I currently abuse the spinlock which is part of the wait queue head, so
there is no additional memory overhead. If this is considered to ugly,
then I'll add a new spinlock.

Tested for SMP, UP on i386.

--
	Manfred
--------------517FC07920B7D7CEEC9F0006
Content-Type: text/plain; charset=us-ascii;
 name="patch-semaphore"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch-semaphore"

// $Header: /pub/cvs/ms/patches/patch-semaphore,v 1.1 1999/08/07 16:45:16 manfreds Exp $ // Kernel Version: // VERSION = 2 // PATCHLEVEL = 3 // SUBLEVEL = 12 // EXTRAVERSION = diff -r -u -P -x CVS -x *,v 2.3/arch/i386/kernel/process.c build-2.3/arch/i386/kernel/process.c --- 2.3/arch/i386/kernel/process.c Thu Jul 29 15:23:06 1999 +++ build-2.3/arch/i386/kernel/process.c Sat Aug 7 18:07:11 1999 @@ -47,8 +47,6 @@ #include "irq.h" -spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED; - asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); #ifdef CONFIG_APM diff -r -u -P -x CVS -x *,v 2.3/include/asm-i386/semaphore-helper.h build-2.3/include/asm-i386/semaphore-helper.h --- 2.3/include/asm-i386/semaphore-helper.h Tue May 25 15:33:48 1999 +++ build-2.3/include/asm-i386/semaphore-helper.h Sat Aug 7 18:12:53 1999 @@ -18,10 +18,10 @@ { unsigned long flags; - spin_lock_irqsave(&semaphore_wake_lock, flags); + wq_write_lock_irqsave(&sem->wait.lock, flags); if (atomic_read(&sem->count) <= 0) sem->waking++; - spin_unlock_irqrestore(&semaphore_wake_lock, flags); + wq_write_unlock_irqrestore(&sem->wait.lock, flags); } static inline int waking_non_zero(struct semaphore *sem) @@ -29,12 +29,12 @@ unsigned long flags; int ret = 0; - spin_lock_irqsave(&semaphore_wake_lock, flags); + wq_write_lock_irqsave(&sem->wait.lock, flags); if (sem->waking > 0) { sem->waking--; ret = 1; } - spin_unlock_irqrestore(&semaphore_wake_lock, flags); + wq_write_unlock_irqrestore(&sem->wait.lock, flags); return ret; } @@ -54,7 +54,7 @@ unsigned long flags; int ret = 0; - spin_lock_irqsave(&semaphore_wake_lock, flags); + wq_write_lock_irqsave(&sem->wait.lock, flags); if (sem->waking > 0) { sem->waking--; ret = 1; @@ -62,7 +62,7 @@ atomic_inc(&sem->count); ret = -EINTR; } - spin_unlock_irqrestore(&semaphore_wake_lock, flags); + wq_write_unlock_irqrestore(&sem->wait.lock, flags); return ret; } @@ -80,14 +80,14 @@ unsigned long flags; int ret = 1; - spin_lock_irqsave(&semaphore_wake_lock, flags); + wq_write_lock_irqsave(&sem->wait.lock, flags); if (sem->waking <= 0) atomic_inc(&sem->count); else { sem->waking--; ret = 0; } - spin_unlock_irqrestore(&semaphore_wake_lock, flags); + wq_write_unlock_irqrestore(&sem->wait.lock, flags); return ret; } diff -r -u -P -x CVS -x *,v 2.3/include/asm-i386/semaphore.h build-2.3/include/asm-i386/semaphore.h --- 2.3/include/asm-i386/semaphore.h Thu Jul 29 15:23:10 1999 +++ build-2.3/include/asm-i386/semaphore.h Sat Aug 7 18:16:18 1999 @@ -21,6 +21,9 @@ * Optimized "0(ecx)" -> "(ecx)" (the assembler does not * do this). Changed calling sequences from push/jmp to * traditional call/ret. + * 1999-08-07 by Manfred Spraul <manfreds@colorfullife.com> + * replaced the global spinlock in wake_??() with + * per-instance locking. * * If you would like to see an analysis of this implementation, please * ftp to gcom.com and download the file @@ -97,8 +100,6 @@ asmlinkage int __down_interruptible(struct semaphore * sem); asmlinkage int __down_trylock(struct semaphore * sem); asmlinkage void __up(struct semaphore * sem); - -extern spinlock_t semaphore_wake_lock; /* * This is ugly, but we want the default case to fall through.

--------------517FC07920B7D7CEEC9F0006--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/