Annotation of Gnu-Mach/linux/src/include/asm-i386/semaphore.h, revision 1.1.1.2

1.1       root        1: #ifndef _I386_SEMAPHORE_H
                      2: #define _I386_SEMAPHORE_H
                      3: 
                      4: #include <linux/linkage.h>
                      5: #include <asm/system.h>
                      6: 
                      7: /*
                      8:  * SMP- and interrupt-safe semaphores..
                      9:  *
                     10:  * (C) Copyright 1996 Linus Torvalds
                     11:  *
                     12:  * Modified 1996-12-23 by Dave Grothe <[email protected]> to fix bugs in
                     13:  *                     the original code and to make semaphore waits
                     14:  *                     interruptible so that processes waiting on
                     15:  *                     semaphores can be killed.
                     16:  *
                     17:  * If you would like to see an analysis of this implementation, please
                     18:  * ftp to gcom.com and download the file
                     19:  * /pub/linux/src/semaphore/semaphore-2.0.24.tar.gz.
                     20:  *
                     21:  */
                     22: 
                     23: struct semaphore {
                     24:        int count;
                     25:        int waking;
                     26:        int lock ;                      /* to make waking testing atomic */
                     27:        struct wait_queue * wait;
                     28: };
                     29: 
                     30: #define MUTEX ((struct semaphore) { 1, 0, 0, NULL })
                     31: #define MUTEX_LOCKED ((struct semaphore) { 0, 0, 0, NULL })
                     32: 
1.1.1.2 ! root       33: /* Special register calling convention:
        !            34:  * eax contains return address
        !            35:  * ecx contains semaphore address
        !            36:  */
1.1       root       37: asmlinkage void down_failed(void /* special register calling convention */);
                     38: asmlinkage void up_wakeup(void /* special register calling convention */);
                     39: 
                     40: extern void __down(struct semaphore * sem);
                     41: extern void __up(struct semaphore * sem);
                     42: 
                     43: /*
                     44:  * This is ugly, but we want the default case to fall through.
                     45:  * "down_failed" is a special asm handler that calls the C
                     46:  * routine that actually waits. See arch/i386/lib/semaphore.S
                     47:  */
1.1.1.2 ! root       48: static inline void down(struct semaphore * sem)
1.1       root       49: {
1.1.1.2 ! root       50:        int d0;
1.1       root       51:        __asm__ __volatile__(
                     52:                "# atomic down operation\n\t"
                     53:                "movl $1f,%%eax\n\t"
                     54: #ifdef __SMP__
                     55:                "lock ; "
                     56: #endif
1.1.1.2 ! root       57:                "decl %1\n\t"
1.1       root       58:                "js " SYMBOL_NAME_STR(down_failed) "\n"
                     59:                "1:\n"
1.1.1.2 ! root       60:                :"=&a" (d0), "=m" (sem->count)
1.1       root       61:                :"c" (sem)
1.1.1.2 ! root       62:                :"memory");
1.1       root       63: }
                     64: 
                     65: /*
                     66:  * Primitives to spin on a lock.  Needed only for SMP version.
                     67:  */
                     68: extern inline void get_buzz_lock(int *lock_ptr)
                     69: {
                     70: #ifdef __SMP__
                     71:         while (xchg(lock_ptr,1) != 0) ;
                     72: #endif
                     73: } /* get_buzz_lock */
                     74: 
                     75: extern inline void give_buzz_lock(int *lock_ptr)
                     76: {
                     77: #ifdef __SMP__
                     78:         *lock_ptr = 0 ;
                     79: #endif
                     80: } /* give_buzz_lock */
                     81: 
                     82: asmlinkage int down_failed_interruptible(void);  /* params in registers */
                     83: 
                     84: /*
                     85:  * This version waits in interruptible state so that the waiting
                     86:  * process can be killed.  The down_failed_interruptible routine
                     87:  * returns negative for signalled and zero for semaphore acquired.
                     88:  */
1.1.1.2 ! root       89: static inline int down_interruptible(struct semaphore * sem)
1.1       root       90: {
                     91:        int     ret ;
                     92: 
                     93:         __asm__ __volatile__(
                     94:                 "# atomic interruptible down operation\n\t"
                     95:                 "movl $2f,%%eax\n\t"
                     96: #ifdef __SMP__
                     97:                 "lock ; "
                     98: #endif
1.1.1.2 ! root       99:                 "decl %1\n\t"
1.1       root      100:                 "js " SYMBOL_NAME_STR(down_failed_interruptible) "\n\t"
                    101:                 "xorl %%eax,%%eax\n"
                    102:                 "2:\n"
1.1.1.2 ! root      103:                 :"=&a" (ret), "=m" (sem->count)
1.1       root      104:                 :"c" (sem)
1.1.1.2 ! root      105:                 :"memory");
1.1       root      106: 
                    107:        return(ret) ;
                    108: }
                    109: 
                    110: /*
                    111:  * Note! This is subtle. We jump to wake people up only if
                    112:  * the semaphore was negative (== somebody was waiting on it).
                    113:  * The default case (no contention) will result in NO
                    114:  * jumps for both down() and up().
                    115:  */
1.1.1.2 ! root      116: static inline void up(struct semaphore * sem)
1.1       root      117: {
1.1.1.2 ! root      118:        int d0;
1.1       root      119:        __asm__ __volatile__(
                    120:                "# atomic up operation\n\t"
                    121:                "movl $1f,%%eax\n\t"
                    122: #ifdef __SMP__
                    123:                "lock ; "
                    124: #endif
1.1.1.2 ! root      125:                "incl %1\n\t"
1.1       root      126:                "jle " SYMBOL_NAME_STR(up_wakeup)
                    127:                "\n1:"
1.1.1.2 ! root      128:                :"=&a" (d0), "=m" (sem->count)
1.1       root      129:                :"c" (sem)
1.1.1.2 ! root      130:                :"memory");
1.1       root      131: }
                    132: 
                    133: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.