/* * release a write lock on the semaphore */ void __up_write(struct rw_semaphore *sem) { unsigned long flags; spin_lock_irqsave(&sem->wait_lock, flags); sem->activity = 0; if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 1); spin_unlock_irqrestore(&sem->wait_lock, flags); }
/* * downgrade a write lock into a read lock * - just wake up any readers at the front of the queue */ void __downgrade_write(struct rw_anon_semaphore *sem) { unsigned long flags; raw_spin_lock_irqsave(&sem->wait_lock, flags); sem->activity = 1; if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 0); raw_spin_unlock_irqrestore(&sem->wait_lock, flags); }
/* * release a write lock on the semaphore */ void fastcall __up_write(struct rw_semaphore *sem) { rwsemtrace(sem,"Entering __up_write"); spin_lock(&sem->wait_lock); sem->activity = 0; if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem); spin_unlock(&sem->wait_lock); rwsemtrace(sem,"Leaving __up_write"); }
/* * release a write lock on the semaphore */ void __up_write(struct rw_semaphore *sem) { unsigned long flags; raw_spin_lock_irqsave(&sem->wait_lock, flags); sem->activity = 0; #ifdef CONFIG_BRCM_DEBUG_RWSEM sem->wr_owner = NULL; #endif if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 1); raw_spin_unlock_irqrestore(&sem->wait_lock, flags); }
/* * downgrade a write lock into a read lock * - caller incremented waiting part of count and discovered it still negative * - just wake up any readers at the front of the queue */ struct rw_semaphore fastcall *rwsem_downgrade_wake(struct rw_semaphore *sem) { rwsemtrace(sem, "Entering rwsem_downgrade_wake"); spin_lock(&sem->wait_lock); /* do nothing if list empty */ if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 1); spin_unlock(&sem->wait_lock); rwsemtrace(sem, "Leaving rwsem_downgrade_wake"); return sem; }
/* * downgrade a write lock into a read lock * - just wake up any readers at the front of the queue */ void fastcall __downgrade_write(struct rw_semaphore *sem) { unsigned long flags; rwsemtrace(sem, "Entering __downgrade_write"); spin_lock_irqsave(&sem->wait_lock, flags); sem->activity = 1; if (!list_empty(&sem->wait_list)) sem = __rwsem_do_wake(sem, 0); spin_unlock_irqrestore(&sem->wait_lock, flags); rwsemtrace(sem, "Leaving __downgrade_write"); }
/* * wait for a lock to be granted */ static inline struct rw_semaphore *rwsem_down_failed_common(struct rw_semaphore *sem, struct rwsem_waiter *waiter, signed long adjustment) { struct task_struct *tsk = current; signed long count; set_task_state(tsk,TASK_UNINTERRUPTIBLE); /* set up my own style of waitqueue */ spin_lock(&sem->wait_lock); waiter->task = tsk; list_add_tail(&waiter->list,&sem->wait_list); /* note that we're now waiting on the lock, but no longer actively read-locking */ count = rwsem_atomic_update(adjustment,sem); /* if there are no longer active locks, wake the front queued process(es) up * - it might even be this process, since the waker takes a more active part */ if (!(count & RWSEM_ACTIVE_MASK)) sem = __rwsem_do_wake(sem,1); spin_unlock(&sem->wait_lock); /* wait to be given the lock */ for (;;) { if (!waiter->flags) break; schedule(); set_task_state(tsk, TASK_UNINTERRUPTIBLE); } tsk->state = TASK_RUNNING; return sem; }