include/asm-i386/semaphore.h
11579 #ifndef _I386_SEMAPHORE_H
11580 #define _I386_SEMAPHORE_H
11581
11582 #include <linux/linkage.h>
11583
11584 /*
11585 * SMP- and interrupt-safe semaphores..
11586 *
11587 * (C) Copyright 1996 Linus Torvalds
11588 *
11589 * Modified 1996-12-23 by Dave Grothe <dave@gcom.com> to
11590 * fix bugs in the original code and to make semaphore
11591 * waits interruptible so that processes waiting on
11592 * semaphores can be killed.
11593 * Modified 1999-02-14 by Andrea Arcangeli, split the
11594 * sched.c helper functions in asm/sempahore-helper.h
11595 * while fixing a potential and subtle race discovered by
11596 * Ulrich Schmid in down_interruptible(). Since I started
11597 * to play here I also implemented the `trylock'
11598 * semaphore operation.
11599 *
11600 * If you would like to see an analysis of this
11601 * implementation, please ftp to gcom.com and download
11602 * the file
11603 * /pub/linux/src/semaphore/semaphore-2.0.24.tar.gz. */
11604
11605 #include <asm/system.h>
11606 #include <asm/atomic.h>
11607 #include <asm/spinlock.h>
11608
11609 struct semaphore {
11610 atomic_t count;
11611 int waking;
11612 struct wait_queue * wait;
11613 };
11614
11615 #define MUTEX \
11616 ((struct semaphore) { ATOMIC_INIT(1), 0, NULL })
11617 #define MUTEX_LOCKED \
11618 ((struct semaphore) { ATOMIC_INIT(0), 0, NULL })
11619
11620 asmlinkage void
11621 __down_failed(void /* special reg calling convention */);
11622 asmlinkage int
11623 __down_failed_interruptible(void /* params in regs */);
11624 asmlinkage int
11625 __down_failed_trylock(void /* params in registers */);
11626 asmlinkage void
11627 __up_wakeup(void /* special reg calling convention */);
11628
11629 asmlinkage void __down(struct semaphore * sem);
11630 asmlinkage int __down_interruptible(
11631 struct semaphore * sem);
11632 asmlinkage int __down_trylock(struct semaphore * sem);
11633 asmlinkage void __up(struct semaphore * sem);
11634
11635 extern spinlock_t semaphore_wake_lock;
11636
11637 #define sema_init(sem, val) \
11638 atomic_set(&((sem)->count), (val))
11639
11640 /* This is ugly, but we want the default case to fall
11641 * through. "down_failed" is a special asm handler that
11642 * calls the C routine that actually waits. See
11643 * arch/i386/lib/semaphore.S */
11644 extern inline void down(struct semaphore * sem)
11645 {
11646 __asm__ __volatile__(
11647 "# atomic down operation\n\t"
11648 #ifdef __SMP__
11649 "lock ; "
11650 #endif
11651 "decl 0(%0)\n\t"
11652 "js 2f\n"
11653 "1:\n"
11654 ".section .text.lock,\"ax\"\n"
11655 "2:\tpushl $1b\n\t"
11656 "jmp __down_failed\n"
11657 ".previous"
11658 :/* no outputs */
11659 :"c" (sem)
11660 :"memory");
11661 }
11662
11663 extern inline int
11664 down_interruptible(struct semaphore * sem)
11665 {
11666 int result;
11667
11668 __asm__ __volatile__(
11669 "# atomic interruptible down operation\n\t"
11670 #ifdef __SMP__
11671 "lock ; "
11672 #endif
11673 "decl 0(%1)\n\t"
11674 "js 2f\n\t"
11675 "xorl %0,%0\n"
11676 "1:\n"
11677 ".section .text.lock,\"ax\"\n"
11678 "2:\tpushl $1b\n\t"
11679 "jmp __down_failed_interruptible\n"
11680 ".previous"
11681 :"=a" (result)
11682 :"c" (sem)
11683 :"memory");
11684 return result;
11685 }
11686
11687 extern inline int down_trylock(struct semaphore * sem)
11688 {
11689 int result;
11690
11691 __asm__ __volatile__(
11692 "# atomic interruptible down operation\n\t"
11693 #ifdef __SMP__
11694 "lock ; "
11695 #endif
11696 "decl 0(%1)\n\t"
11697 "js 2f\n\t"
11698 "xorl %0,%0\n"
11699 "1:\n"
11700 ".section .text.lock,\"ax\"\n"
11701 "2:\tpushl $1b\n\t"
11702 "jmp __down_failed_trylock\n"
11703 ".previous"
11704 :"=a" (result)
11705 :"c" (sem)
11706 :"memory");
11707 return result;
11708 }
11709
11710 /* Note! This is subtle. We jump to wake people up only
11711 * if the semaphore was negative (== somebody was waiting
11712 * on it). The default case (no contention) will result
11713 * in NO jumps for both down() and up(). */
11714 extern inline void up(struct semaphore * sem)
11715 {
11716 __asm__ __volatile__(
11717 "# atomic up operation\n\t"
11718 #ifdef __SMP__
11719 "lock ; "
11720 #endif
11721 "incl 0(%0)\n\t"
11722 "jle 2f\n"
11723 "1:\n"
11724 ".section .text.lock,\"ax\"\n"
11725 "2:\tpushl $1b\n\t"
11726 "jmp __up_wakeup\n"
11727 ".previous"
11728 :/* no outputs */
11729 :"c" (sem)
11730 :"memory");
11731 }
11732
11733 #endif
Сайт управляется системой
uCoz