lkml.org 
[lkml]   [1999]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [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/

\
 
 \ /
  Last update: 2005-03-22 13:55    [W:0.062 / U:0.580 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site