Messages in this thread Patch in this message | | | Date | Mon, 22 Nov 1999 04:04:43 -0200 (BRDT) | From | Marcelo Tosatti <> | Subject | Re: [PATCH] i386 rw semaphore + use for mmap_sem |
| |
On Sun, 21 Nov 1999, Benjamin C.R. LaHaise wrote:
> Hello folks, > > Here's my implementation of rw semaphores for x86. It's 2 instructions > for the non-contended case of down_(read|write) and up_read as I outlined > yesterday. I've still got to test the contention case a bit more to be > satisfied before I remove the readers/writers assertions, but I'd like it > if people could give it an eyeballing and comment. Cheers,
Your code wakes up all writers (if there are any) in read_up. Since just one writer will get the lock, i think its more interesting to wake one process.
diff -Nur linux-2.3.28.orig/arch/i386/kernel/semaphore.c linux/arch/i386/kernel/semaphore.c --- linux-2.3.28.orig/arch/i386/kernel/semaphore.c Mon Nov 22 16:30:07 1999 +++ linux/arch/i386/kernel/semaphore.c Mon Nov 22 16:46:51 1999 @@ -263,6 +263,41 @@ "ret" ); +asm( +".align 4\n" +".globl __rwsem_wake_one\n" +"__rwsem_wake_one:\n\t" + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call rwsem_wake_one\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" + "ret" +); + +struct rw_semaphore *rwsem_wake_one(struct rw_semaphore *sem) +{ + struct task_struct *p; + unsigned long flags; + unsigned int state; + wait_queue_t *curr; + wait_queue_head_t *wait = &sem->wait; + + wq_write_lock_irqsave(&wait->lock, flags); + + curr = list_entry(&wait->task_list.next->next, wait_queue_t, task_list); + + p = curr->task; + state = p->state; + + if (state) + wake_up_process(p); + + wq_write_unlock_irqrestore(&wait->lock, flags); + + return sem; +} + struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem) { wake_up(&sem->wait); diff -Nur linux-2.3.28.orig/include/asm-i386/semaphore.h linux/include/asm-i386/semaphore.h --- linux-2.3.28.orig/include/asm-i386/semaphore.h Mon Nov 22 16:30:07 1999 +++ linux/include/asm-i386/semaphore.h Mon Nov 22 15:24:55 1999 @@ -258,6 +258,8 @@ extern struct rw_semaphore *FASTCALL(down_write_failed(struct rw_semaphore *sem)); extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *sem)); +extern struct rw_semaphore *FASTCALL(rwsem_wake_one(struct rw_semaphore *sem)); + extern inline void down_read(struct rw_semaphore *sem) { __asm__ __volatile__( @@ -311,7 +313,7 @@ "jz 2f\n" /* only do the wake if result == 0 (ie, a writer) */ "1:\n\t" ".section .text.lock,\"ax\"\n" - "2:\tcall __rwsem_wake\n\t" + "2:\tcall __rwsem_wake_one\n\t" "jmp 1b\n" ".previous" ::"a" (sem)
- 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/
| |