Annotation of XNU/osfmk/i386/lock.h, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (C) 1998 Apple Computer
                     24:  * All Rights Reserved
                     25:  */
                     26: /*
                     27:  * @OSF_COPYRIGHT@
                     28:  */
                     29: /* 
                     30:  * Mach Operating System
                     31:  * Copyright (c) 1991,1990 Carnegie Mellon University
                     32:  * All Rights Reserved.
                     33:  * 
                     34:  * Permission to use, copy, modify and distribute this software and its
                     35:  * documentation is hereby granted, provided that both the copyright
                     36:  * notice and this permission notice appear in all copies of the
                     37:  * software, derivative works or modified versions, and any portions
                     38:  * thereof, and that both notices appear in supporting documentation.
                     39:  * 
                     40:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     41:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     42:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     43:  * 
                     44:  * Carnegie Mellon requests users of this software to return to
                     45:  * 
                     46:  *  Software Distribution Coordinator  or  [email protected]
                     47:  *  School of Computer Science
                     48:  *  Carnegie Mellon University
                     49:  *  Pittsburgh PA 15213-3890
                     50:  * 
                     51:  * any improvements or extensions that they make and grant Carnegie Mellon
                     52:  * the rights to redistribute these changes.
                     53:  */
                     54: 
                     55: /*
                     56:  */
                     57: 
                     58: /*
                     59:  * Machine-dependent simple locks for the i386.
                     60:  */
                     61: 
                     62: #ifndef        _I386_LOCK_H_
                     63: #define        _I386_LOCK_H_
                     64: 
                     65: #include <kern/macro_help.h>
                     66: #include <kern/assert.h>
                     67: #include <i386/hw_lock_types.h>
                     68: 
                     69: #ifdef MACH_KERNEL_PRIVATE
                     70: 
                     71: #include <mach_rt.h>
                     72: #include <mach_ldebug.h>
                     73: #include <cpus.h>
                     74: 
                     75: 
                     76: #if defined(__GNUC__)
                     77: 
                     78: /*
                     79:  *     General bit-lock routines.
                     80:  */
                     81: 
                     82: #define        bit_lock(bit,l)                                                 \
                     83:        __asm__ volatile("      jmp     1f      \n                      \
                     84:                        0:      btl     %0, %1  \n                      \
                     85:                                jb      0b      \n                      \
                     86:                        1:      lock            \n                      \
                     87:                                btsl    %0,%1   \n                      \
                     88:                                jb      0b"                     :       \
                     89:                                                                :       \
                     90:                        "r" (bit), "m" (*(volatile int *)(l))   :       \
                     91:                        "memory");
                     92: 
                     93: #define        bit_unlock(bit,l)                                               \
                     94:        __asm__ volatile("      lock            \n                      \
                     95:                                btrl    %0,%1"                  :       \
                     96:                                                                :       \
                     97:                        "r" (bit), "m" (*(volatile int *)(l)));
                     98: 
                     99: /*
                    100:  *      Set or clear individual bits in a long word.
                    101:  *      The locked access is needed only to lock access
                    102:  *      to the word, not to individual bits.
                    103:  */
                    104: 
                    105: #define        i_bit_set(bit,l)                                                \
                    106:        __asm__ volatile("      lock            \n                      \
                    107:                                btsl    %0,%1"                  :       \
                    108:                                                                :       \
                    109:                        "r" (bit), "m" (*(volatile int *)(l)));
                    110: 
                    111: #define        i_bit_clear(bit,l)                                              \
                    112:        __asm__ volatile("      lock            \n                      \
                    113:                                btrl    %0,%1"                  :       \
                    114:                                                                :       \
                    115:                        "r" (bit), "m" (*(volatile int *)(l)));
                    116: 
                    117: extern __inline__ unsigned long i_bit_isset(unsigned int testbit, volatile unsigned long *word)
                    118: {
                    119:        int     bit;
                    120: 
                    121:        __asm__ volatile("btl %2,%1\n\tsbbl %0,%0" : "=r" (bit)
                    122:                : "m" (word), "ir" (testbit));
                    123:        return bit;
                    124: }
                    125: 
                    126: extern __inline__ char xchgb(volatile char * cp, char new);
                    127: 
                    128: extern __inline__ void atomic_incl(long * p, long delta);
                    129: extern __inline__ void atomic_incs(short * p, short delta);
                    130: extern __inline__ void atomic_incb(char * p, char delta);
                    131: 
                    132: extern __inline__ void atomic_decl(long * p, long delta);
                    133: extern __inline__ void atomic_decs(short * p, short delta);
                    134: extern __inline__ void atomic_decb(char * p, char delta);
                    135: 
                    136: extern __inline__ long atomic_getl(long * p);
                    137: extern __inline__ short        atomic_gets(short * p);
                    138: extern __inline__ char atomic_getb(char * p);
                    139: 
                    140: extern __inline__ void atomic_setl(long * p, long value);
                    141: extern __inline__ void atomic_sets(short * p, short value);
                    142: extern __inline__ void atomic_setb(char * p, char value);
                    143: 
                    144: extern __inline__ char xchgb(volatile char * cp, char new)
                    145: {
                    146:        register char   old = new;
                    147: 
                    148:        __asm__ volatile ("     xchgb   %0,%2"                  :
                    149:                        "=q" (old)                              :
                    150:                        "0" (new), "m" (*(volatile char *)cp) : "memory");
                    151:        return (old);
                    152: }
                    153: 
                    154: extern __inline__ void atomic_incl(long * p, long delta)
                    155: {
                    156: #if NEED_ATOMIC
                    157:        __asm__ volatile ("     lock            \n              \
                    158:                                addl    %0,%1"          :       \
                    159:                                                        :       \
                    160:                                "r" (delta), "m" (*(volatile long *)p));
                    161: #else /* NEED_ATOMIC */
                    162:        *p += delta;
                    163: #endif /* NEED_ATOMIC */
                    164: }
                    165: 
                    166: extern __inline__ void atomic_incs(short * p, short delta)
                    167: {
                    168: #if NEED_ATOMIC
                    169:        __asm__ volatile ("     lock            \n              \
                    170:                                addw    %0,%1"          :       \
                    171:                                                        :       \
                    172:                                "q" (delta), "m" (*(volatile short *)p));
                    173: #else /* NEED_ATOMIC */
                    174:        *p += delta;
                    175: #endif /* NEED_ATOMIC */
                    176: }
                    177: 
                    178: extern __inline__ void atomic_incb(char * p, char delta)
                    179: {
                    180: #if NEED_ATOMIC
                    181:        __asm__ volatile ("     lock            \n              \
                    182:                                addb    %0,%1"          :       \
                    183:                                                        :       \
                    184:                                "q" (delta), "m" (*(volatile char *)p));
                    185: #else /* NEED_ATOMIC */
                    186:        *p += delta;
                    187: #endif /* NEED_ATOMIC */
                    188: }
                    189: 
                    190: extern __inline__ void atomic_decl(long * p, long delta)
                    191: {
                    192: #if NCPUS > 1
                    193:        __asm__ volatile ("     lock            \n              \
                    194:                                subl    %0,%1"          :       \
                    195:                                                        :       \
                    196:                                "r" (delta), "m" (*(volatile long *)p));
                    197: #else /* NCPUS > 1 */
                    198:        *p -= delta;
                    199: #endif /* NCPUS > 1 */
                    200: }
                    201: 
                    202: extern __inline__ void atomic_decs(short * p, short delta)
                    203: {
                    204: #if NEED_ATOMIC
                    205:        __asm__ volatile ("     lock            \n              \
                    206:                                subw    %0,%1"          :       \
                    207:                                                        :       \
                    208:                                "q" (delta), "m" (*(volatile short *)p));
                    209: #else /* NEED_ATOMIC */
                    210:        *p -= delta;
                    211: #endif /* NEED_ATOMIC */
                    212: }
                    213: 
                    214: extern __inline__ void atomic_decb(char * p, char delta)
                    215: {
                    216: #if NEED_ATOMIC
                    217:        __asm__ volatile ("     lock            \n              \
                    218:                                subb    %0,%1"          :       \
                    219:                                                        :       \
                    220:                                "q" (delta), "m" (*(volatile char *)p));
                    221: #else /* NEED_ATOMIC */
                    222:        *p -= delta;
                    223: #endif /* NEED_ATOMIC */
                    224: }
                    225: 
                    226: extern __inline__ long atomic_getl(long * p)
                    227: {
                    228:        return (*p);
                    229: }
                    230: 
                    231: extern __inline__ short        atomic_gets(short * p)
                    232: {
                    233:        return (*p);
                    234: }
                    235: 
                    236: extern __inline__ char atomic_getb(char * p)
                    237: {
                    238:        return (*p);
                    239: }
                    240: 
                    241: extern __inline__ void atomic_setl(long * p, long value)
                    242: {
                    243:        *p = value;
                    244: }
                    245: 
                    246: extern __inline__ void atomic_sets(short * p, short value)
                    247: {
                    248:        *p = value;
                    249: }
                    250: 
                    251: extern __inline__ void atomic_setb(char * p, char value)
                    252: {
                    253:        *p = value;
                    254: }
                    255: 
                    256: 
                    257: #else  /* !defined(__GNUC__) */
                    258: 
                    259: extern void    i_bit_set(
                    260:        int index,
                    261:        void *addr);
                    262: 
                    263: extern void    i_bit_clear(
                    264:        int index,
                    265:        void *addr);
                    266: 
                    267: extern void bit_lock(
                    268:        int index,
                    269:        void *addr);
                    270: 
                    271: extern void bit_unlock(
                    272:        int index,
                    273:        void *addr);
                    274: 
                    275: /*
                    276:  * All other routines defined in __GNUC__ case lack
                    277:  * definitions otherwise. - XXX
                    278:  */
                    279: 
                    280: #endif /* !defined(__GNUC__) */
                    281: 
                    282: 
                    283: #if    !(USLOCK_DEBUG || USLOCK_STATS)
                    284: /*
                    285:  *     Take responsibility for production-quality usimple_locks.
                    286:  *     Let the portable lock package build simple_locks in terms
                    287:  *     of usimple_locks, which is done efficiently with macros.
                    288:  *     Currently, these aren't inlined although they probably
                    289:  *     should be.  The portable lock package is used for the
                    290:  *     usimple_lock prototypes and data declarations.
                    291:  *
                    292:  *     For non-production configurations, punt entirely to the
                    293:  *     portable lock package.
                    294:  *
                    295:  *     N.B.  I've left in the hooks for ETAP, so we can
                    296:  *     compare the performance of stats-gathering on top
                    297:  *     of "production" locks v. stats-gathering on top
                    298:  *     of portable, C-based locks.
                    299:  */
                    300: #define        USIMPLE_LOCK_CALLS
                    301: #endif /* !(USLOCK_DEBUG || USLOCK_STATS) */
                    302: 
                    303: 
                    304: #if    MACH_RT || (NCPUS > 1) || MACH_LDEBUG
                    305: #if    MACH_LDEBUG || !MACH_RT
                    306: #define        mutex_try(m)    (!(m)->interlock && _mutex_try(m))
                    307: #define        mutex_lock(m)                                           \
                    308: MACRO_BEGIN                                                    \
                    309:        assert(assert_wait_possible());                         \
                    310:        _mutex_lock((m));                                       \
                    311: MACRO_END
                    312: 
                    313: #else  /* MACH_LDEBUG || !MACH_RT */
                    314: #define        mutex_try(m)    (!(m)->interlock && \
                    315:                !xchgb ((volatile char *)&((m)->locked), 1))
                    316: #define        mutex_lock(m)                                           \
                    317: MACRO_BEGIN                                                    \
                    318:        assert(assert_wait_possible());                         \
                    319:        _mutex_lock (m);                                        \
                    320: MACRO_END
                    321: 
                    322: #endif /* MACH_LDEBUG || !MACH_RT */
                    323: #else  /* MACH_RT || (NCPUS > 1) || MACH_LDEBUG */
                    324: #define        mutex_try       _mutex_try
                    325: #define        mutex_lock      _mutex_lock
                    326: #endif /* MACH_RT || (NCPUS > 1) || MACH_LDEBUG */
                    327: 
                    328: #else /* !MACH_KERNEL_PRIVATE */
                    329: 
                    330: #define mutex_try      _mutex_try
                    331: #define mutex_lock(m)                          \
                    332: MACRO_BEGIN                                    \
                    333:        assert(assert_wait_possible());         \
                    334:        _mutex_lock((m));                       \
                    335: MACRO_END
                    336: 
                    337: #endif /* !MACH_KERNEL_PRIVATE */
                    338: 
                    339: extern void            kernel_preempt_check (void);
                    340: 
                    341: #endif /* _I386_LOCK_H_ */
                    342: 

unix.superglobalmegacorp.com

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