X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Frwsem.c;h=a2d725f944a465e401c91e843ec863c09deae59f;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=465ec725607e35d26e420dc732c5615a74e37343;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/lib/rwsem.c b/lib/rwsem.c index 465ec7256..a2d725f94 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c @@ -8,6 +8,26 @@ #include #include +/* + * Initialize an rwsem: + */ +void __init_rwsem(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key) +{ +#ifdef CONFIG_DEBUG_LOCK_ALLOC + /* + * Make sure we are not reinitializing a held semaphore: + */ + debug_check_no_locks_freed((void *)sem, sizeof(*sem)); + lockdep_init_map(&sem->dep_map, name, key, 0); +#endif + sem->count = RWSEM_UNLOCKED_VALUE; + spin_lock_init(&sem->wait_lock); + INIT_LIST_HEAD(&sem->wait_list); +} + +EXPORT_SYMBOL(__init_rwsem); + struct rwsem_waiter { struct list_head list; struct task_struct *task; @@ -16,17 +36,6 @@ struct rwsem_waiter { #define RWSEM_WAITING_FOR_WRITE 0x00000002 }; -#if RWSEM_DEBUG -#undef rwsemtrace -void rwsemtrace(struct rw_semaphore *sem, const char *str) -{ - printk("sem=%p\n", sem); - printk("(sem)=%08lx\n", sem->count); - if (sem->debug) - printk("[%d] %s({%08lx})\n", current->pid, str, sem->count); -} -#endif - /* * handle the lock release when processes blocked on it that can now run * - if we come here from up_xxxx(), then: @@ -45,8 +54,6 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading) struct list_head *next; signed long oldcount, woken, loop; - rwsemtrace(sem, "Entering __rwsem_do_wake"); - if (downgrading) goto dont_wake_writers; @@ -74,7 +81,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading) */ list_del(&waiter->list); tsk = waiter->task; - mb(); + smp_mb(); waiter->task = NULL; wake_up_process(tsk); put_task_struct(tsk); @@ -117,7 +124,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading) waiter = list_entry(next, struct rwsem_waiter, list); next = waiter->list.next; tsk = waiter->task; - mb(); + smp_mb(); waiter->task = NULL; wake_up_process(tsk); put_task_struct(tsk); @@ -127,7 +134,6 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading) next->prev = &sem->wait_list; out: - rwsemtrace(sem, "Leaving __rwsem_do_wake"); return sem; /* undo the change to count, but check for a transition 1->0 */ @@ -150,7 +156,7 @@ rwsem_down_failed_common(struct rw_semaphore *sem, set_task_state(tsk, TASK_UNINTERRUPTIBLE); /* set up my own style of waitqueue */ - spin_lock(&sem->wait_lock); + spin_lock_irq(&sem->wait_lock); waiter->task = tsk; get_task_struct(tsk); @@ -163,7 +169,7 @@ rwsem_down_failed_common(struct rw_semaphore *sem, if (!(count & RWSEM_ACTIVE_MASK)) sem = __rwsem_do_wake(sem, 0); - spin_unlock(&sem->wait_lock); + spin_unlock_irq(&sem->wait_lock); /* wait to be given the lock */ for (;;) { @@ -186,13 +192,9 @@ rwsem_down_read_failed(struct rw_semaphore *sem) { struct rwsem_waiter waiter; - rwsemtrace(sem, "Entering rwsem_down_read_failed"); - waiter.flags = RWSEM_WAITING_FOR_READ; rwsem_down_failed_common(sem, &waiter, RWSEM_WAITING_BIAS - RWSEM_ACTIVE_BIAS); - - rwsemtrace(sem, "Leaving rwsem_down_read_failed"); return sem; } @@ -204,12 +206,9 @@ rwsem_down_write_failed(struct rw_semaphore *sem) { struct rwsem_waiter waiter; - rwsemtrace(sem, "Entering rwsem_down_write_failed"); - waiter.flags = RWSEM_WAITING_FOR_WRITE; rwsem_down_failed_common(sem, &waiter, -RWSEM_ACTIVE_BIAS); - rwsemtrace(sem, "Leaving rwsem_down_write_failed"); return sem; } @@ -219,17 +218,15 @@ rwsem_down_write_failed(struct rw_semaphore *sem) */ struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem) { - rwsemtrace(sem, "Entering rwsem_wake"); + unsigned long flags; - spin_lock(&sem->wait_lock); + spin_lock_irqsave(&sem->wait_lock, flags); /* do nothing if list empty */ if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 0); - spin_unlock(&sem->wait_lock); - - rwsemtrace(sem, "Leaving rwsem_wake"); + spin_unlock_irqrestore(&sem->wait_lock, flags); return sem; } @@ -241,24 +238,20 @@ struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem) */ struct rw_semaphore fastcall *rwsem_downgrade_wake(struct rw_semaphore *sem) { - rwsemtrace(sem, "Entering rwsem_downgrade_wake"); + unsigned long flags; - spin_lock(&sem->wait_lock); + spin_lock_irqsave(&sem->wait_lock, flags); /* do nothing if list empty */ if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 1); - spin_unlock(&sem->wait_lock); + spin_unlock_irqrestore(&sem->wait_lock, flags); - rwsemtrace(sem, "Leaving rwsem_downgrade_wake"); return sem; } -EXPORT_SYMBOL_NOVERS(rwsem_down_read_failed); -EXPORT_SYMBOL_NOVERS(rwsem_down_write_failed); -EXPORT_SYMBOL_NOVERS(rwsem_wake); -EXPORT_SYMBOL_NOVERS(rwsem_downgrade_wake); -#if RWSEM_DEBUG -EXPORT_SYMBOL(rwsemtrace); -#endif +EXPORT_SYMBOL(rwsem_down_read_failed); +EXPORT_SYMBOL(rwsem_down_write_failed); +EXPORT_SYMBOL(rwsem_wake); +EXPORT_SYMBOL(rwsem_downgrade_wake);