- Visual C++源码
- Visual Basic源码
- C++ Builder源码
- Java源码
- Delphi源码
- C/C++源码
- PHP源码
- Perl源码
- Python源码
- Asm源码
- Pascal源码
- Borland C++源码
- Others源码
- SQL源码
- VBScript源码
- JavaScript源码
- ASP/ASPX源码
- C#源码
- Flash/ActionScript源码
- matlab源码
- PowerBuilder源码
- LabView源码
- Flex源码
- MathCAD源码
- VBA源码
- IDL源码
- Lisp/Scheme源码
- VHDL源码
- Objective-C源码
- Fortran源码
- tcl/tk源码
- QT源码
semaphore-helper.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:
Linux/Unix编程
开发平台:
Unix_Linux
- /*
- * SMP- and interrupt-safe semaphores helper functions.
- *
- * (C) Copyright 1996 Linus Torvalds
- * (C) Copyright 1999 Andrea Arcangeli
- * (C) Copyright 1999, 2001 Ralf Baechle
- * (C) Copyright 1999, 2001 Silicon Graphics, Inc.
- */
- #ifndef _ASM_SEMAPHORE_HELPER_H
- #define _ASM_SEMAPHORE_HELPER_H
- /*
- * These two _must_ execute atomically wrt each other.
- */
- static inline void wake_one_more(struct semaphore * sem)
- {
- atomic_inc(&sem->waking);
- }
- static inline int waking_non_zero(struct semaphore *sem)
- {
- int ret, tmp;
- __asm__ __volatile__(
- "1:tllt%1, %2ttt# waking_non_zeront"
- "blezt%1, 2fnt"
- "subut%0, %1, 1nt"
- "sct%0, %2nt"
- "beqzt%0, 1bn"
- "2:"
- : "=r" (ret), "=r" (tmp), "+m" (sem->waking)
- : "0" (0));
- return ret;
- }
- /*
- * waking_non_zero_interruptible:
- * 1 got the lock
- * 0 go to sleep
- * -EINTR interrupted
- *
- * We must undo the sem->count down_interruptible decrement
- * simultaneously and atomically with the sem->waking adjustment,
- * otherwise we can race with wake_one_more.
- *
- * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words.
- *
- * Pseudocode:
- *
- * If(sem->waking > 0) {
- * Decrement(sem->waking)
- * Return(SUCCESS)
- * } else If(signal_pending(tsk)) {
- * Increment(sem->count)
- * Return(-EINTR)
- * } else {
- * Return(SLEEP)
- * }
- */
- static inline int
- waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk)
- {
- long ret, tmp;
- #ifdef __MIPSEB__
- __asm__ __volatile__(
- ".settpushttt# waking_non_zero_interruptiblent"
- ".settnoatnt"
- "0:tlldt%1, %2nt"
- "lit%0, 0nt"
- "sllt$1, %1, 0nt"
- "blezt$1, 1fnt"
- "daddiut%1, %1, -1nt"
- "lit%0, 1nt"
- "bt2fnt"
- "1:tbeqzt%3, 2fnt"
- "lit%0, %4nt"
- "dlit$1, 0x0000000100000000nt"
- "daddut%1, %1, $1nt"
- "2:tscdt%1, %2nt"
- "beqzt%1, 0bnt"
- ".settpop"
- : "=&r" (ret), "=&r" (tmp), "=m" (*sem)
- : "r" (signal_pending(tsk)), "i" (-EINTR));
- #elif defined(__MIPSEL__)
- __asm__ __volatile__(
- ".settpushttt# waking_non_zero_interruptiblent"
- ".sett noatn"
- "0:tlldt%1, %2nt"
- "lit%0, 0nt"
- "blezt%1, 1fnt"
- "dlit$1, 0x0000000100000000nt"
- "dsubut%1, %1, $1nt"
- "lit%0, 1nt"
- "bt2fn"
- "1:tbeqzt%3, 2fnt"
- "lit%0, %4nt"
- /*
- * It would be nice to assume that sem->count
- * is != -1, but we will guard against that case
- */
- "daddiut$1, %1, 1nt"
- "dsll32t$1, $1, 0nt"
- "dsrl32t$1, $1, 0nt"
- "dsrl32t%1, %1, 0nt"
- "dsll32t%1, %1, 0nt"
- "ort%1, %1, $1n"
- "2:tscdt%1, %2nt"
- "beqzt %1, 0bnt"
- ".settpop"
- : "=&r" (ret), "=&r" (tmp), "=m" (*sem)
- : "r" (signal_pending(tsk)), "i" (-EINTR));
- #endif
- return ret;
- }
- /*
- * waking_non_zero_trylock is unused. we do everything in
- * down_trylock and let non-ll/sc hosts bounce around.
- */
- static inline int waking_non_zero_trylock(struct semaphore *sem)
- {
- #if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
- #endif
- return 0;
- }
- #endif /* _ASM_SEMAPHORE_HELPER_H */