-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 88570 b: refs/heads/master c: 223ac2f h: refs/heads/master v: v3
- Loading branch information
Björn Steinbrink
authored and
Ingo Molnar
committed
Apr 17, 2008
1 parent
48b804a
commit 95dacbd
Showing
374 changed files
with
11,506 additions
and
15,052 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: d7bb545d86825e635cab33a1dd81ca0ad7b92887 | ||
refs/heads/master: 223ac2f42d49dd0324ca02ea15897ead1a2f5133 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
/* | ||
* Alpha semaphore implementation. | ||
* | ||
* (C) Copyright 1996 Linus Torvalds | ||
* (C) Copyright 1999, 2000 Richard Henderson | ||
*/ | ||
|
||
#include <linux/errno.h> | ||
#include <linux/sched.h> | ||
#include <linux/init.h> | ||
|
||
/* | ||
* This is basically the PPC semaphore scheme ported to use | ||
* the Alpha ll/sc sequences, so see the PPC code for | ||
* credits. | ||
*/ | ||
|
||
/* | ||
* Atomically update sem->count. | ||
* This does the equivalent of the following: | ||
* | ||
* old_count = sem->count; | ||
* tmp = MAX(old_count, 0) + incr; | ||
* sem->count = tmp; | ||
* return old_count; | ||
*/ | ||
static inline int __sem_update_count(struct semaphore *sem, int incr) | ||
{ | ||
long old_count, tmp = 0; | ||
|
||
__asm__ __volatile__( | ||
"1: ldl_l %0,%2\n" | ||
" cmovgt %0,%0,%1\n" | ||
" addl %1,%3,%1\n" | ||
" stl_c %1,%2\n" | ||
" beq %1,2f\n" | ||
" mb\n" | ||
".subsection 2\n" | ||
"2: br 1b\n" | ||
".previous" | ||
: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) | ||
: "Ir" (incr), "1" (tmp), "m" (sem->count)); | ||
|
||
return old_count; | ||
} | ||
|
||
/* | ||
* Perform the "down" function. Return zero for semaphore acquired, | ||
* return negative for signalled out of the function. | ||
* | ||
* If called from down, the return is ignored and the wait loop is | ||
* not interruptible. This means that a task waiting on a semaphore | ||
* using "down()" cannot be killed until someone does an "up()" on | ||
* the semaphore. | ||
* | ||
* If called from down_interruptible, the return value gets checked | ||
* upon return. If the return value is negative then the task continues | ||
* with the negative value in the return register (it can be tested by | ||
* the caller). | ||
* | ||
* Either form may be used in conjunction with "up()". | ||
*/ | ||
|
||
void __sched | ||
__down_failed(struct semaphore *sem) | ||
{ | ||
struct task_struct *tsk = current; | ||
DECLARE_WAITQUEUE(wait, tsk); | ||
|
||
#ifdef CONFIG_DEBUG_SEMAPHORE | ||
printk("%s(%d): down failed(%p)\n", | ||
tsk->comm, task_pid_nr(tsk), sem); | ||
#endif | ||
|
||
tsk->state = TASK_UNINTERRUPTIBLE; | ||
wmb(); | ||
add_wait_queue_exclusive(&sem->wait, &wait); | ||
|
||
/* | ||
* Try to get the semaphore. If the count is > 0, then we've | ||
* got the semaphore; we decrement count and exit the loop. | ||
* If the count is 0 or negative, we set it to -1, indicating | ||
* that we are asleep, and then sleep. | ||
*/ | ||
while (__sem_update_count(sem, -1) <= 0) { | ||
schedule(); | ||
set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
} | ||
remove_wait_queue(&sem->wait, &wait); | ||
tsk->state = TASK_RUNNING; | ||
|
||
/* | ||
* If there are any more sleepers, wake one of them up so | ||
* that it can either get the semaphore, or set count to -1 | ||
* indicating that there are still processes sleeping. | ||
*/ | ||
wake_up(&sem->wait); | ||
|
||
#ifdef CONFIG_DEBUG_SEMAPHORE | ||
printk("%s(%d): down acquired(%p)\n", | ||
tsk->comm, task_pid_nr(tsk), sem); | ||
#endif | ||
} | ||
|
||
int __sched | ||
__down_failed_interruptible(struct semaphore *sem) | ||
{ | ||
struct task_struct *tsk = current; | ||
DECLARE_WAITQUEUE(wait, tsk); | ||
long ret = 0; | ||
|
||
#ifdef CONFIG_DEBUG_SEMAPHORE | ||
printk("%s(%d): down failed(%p)\n", | ||
tsk->comm, task_pid_nr(tsk), sem); | ||
#endif | ||
|
||
tsk->state = TASK_INTERRUPTIBLE; | ||
wmb(); | ||
add_wait_queue_exclusive(&sem->wait, &wait); | ||
|
||
while (__sem_update_count(sem, -1) <= 0) { | ||
if (signal_pending(current)) { | ||
/* | ||
* A signal is pending - give up trying. | ||
* Set sem->count to 0 if it is negative, | ||
* since we are no longer sleeping. | ||
*/ | ||
__sem_update_count(sem, 0); | ||
ret = -EINTR; | ||
break; | ||
} | ||
schedule(); | ||
set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
} | ||
|
||
remove_wait_queue(&sem->wait, &wait); | ||
tsk->state = TASK_RUNNING; | ||
wake_up(&sem->wait); | ||
|
||
#ifdef CONFIG_DEBUG_SEMAPHORE | ||
printk("%s(%d): down %s(%p)\n", | ||
current->comm, task_pid_nr(current), | ||
(ret < 0 ? "interrupted" : "acquired"), sem); | ||
#endif | ||
return ret; | ||
} | ||
|
||
void | ||
__up_wakeup(struct semaphore *sem) | ||
{ | ||
/* | ||
* Note that we incremented count in up() before we came here, | ||
* but that was ineffective since the result was <= 0, and | ||
* any negative value of count is equivalent to 0. | ||
* This ends up setting count to 1, unless count is now > 0 | ||
* (i.e. because some other cpu has called up() in the meantime), | ||
* in which case we just increment count. | ||
*/ | ||
__sem_update_count(sem, 1); | ||
wake_up(&sem->wait); | ||
} | ||
|
||
void __sched | ||
down(struct semaphore *sem) | ||
{ | ||
#ifdef WAITQUEUE_DEBUG | ||
CHECK_MAGIC(sem->__magic); | ||
#endif | ||
#ifdef CONFIG_DEBUG_SEMAPHORE | ||
printk("%s(%d): down(%p) <count=%d> from %p\n", | ||
current->comm, task_pid_nr(current), sem, | ||
atomic_read(&sem->count), __builtin_return_address(0)); | ||
#endif | ||
__down(sem); | ||
} | ||
|
||
int __sched | ||
down_interruptible(struct semaphore *sem) | ||
{ | ||
#ifdef WAITQUEUE_DEBUG | ||
CHECK_MAGIC(sem->__magic); | ||
#endif | ||
#ifdef CONFIG_DEBUG_SEMAPHORE | ||
printk("%s(%d): down(%p) <count=%d> from %p\n", | ||
current->comm, task_pid_nr(current), sem, | ||
atomic_read(&sem->count), __builtin_return_address(0)); | ||
#endif | ||
return __down_interruptible(sem); | ||
} | ||
|
||
int | ||
down_trylock(struct semaphore *sem) | ||
{ | ||
int ret; | ||
|
||
#ifdef WAITQUEUE_DEBUG | ||
CHECK_MAGIC(sem->__magic); | ||
#endif | ||
|
||
ret = __down_trylock(sem); | ||
|
||
#ifdef CONFIG_DEBUG_SEMAPHORE | ||
printk("%s(%d): down_trylock %s from %p\n", | ||
current->comm, task_pid_nr(current), | ||
ret ? "failed" : "acquired", | ||
__builtin_return_address(0)); | ||
#endif | ||
|
||
return ret; | ||
} | ||
|
||
void | ||
up(struct semaphore *sem) | ||
{ | ||
#ifdef WAITQUEUE_DEBUG | ||
CHECK_MAGIC(sem->__magic); | ||
#endif | ||
#ifdef CONFIG_DEBUG_SEMAPHORE | ||
printk("%s(%d): up(%p) <count=%d> from %p\n", | ||
current->comm, task_pid_nr(current), sem, | ||
atomic_read(&sem->count), __builtin_return_address(0)); | ||
#endif | ||
__up(sem); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.