netlib.narod.ru< Назад | Оглавление | Далее >

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

netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz