Annotation of XNU/osfmk/i386/lock.h, revision 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.