Annotation of Gnu-Mach/kern/lock.h, revision 1.1.1.4

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1993-1987 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     File:   kern/lock.h
                     28:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     29:  *     Date:   1985
                     30:  *
                     31:  *     Locking primitives definitions
                     32:  */
                     33: 
                     34: #ifndef        _KERN_LOCK_H_
                     35: #define        _KERN_LOCK_H_
                     36: 
                     37: #include <mach/boolean.h>
                     38: #include <mach/machine/vm_types.h>
                     39: 
                     40: #if NCPUS > 1
                     41: #include <machine/lock.h>/*XXX*/
                     42: #endif
                     43: 
                     44: #define MACH_SLOCKS    ((NCPUS > 1) || MACH_LDEBUG)
                     45: 
                     46: /*
                     47:  *     A simple spin lock.
                     48:  */
                     49: 
                     50: struct slock {
                     51:        volatile natural_t lock_data;   /* in general 1 bit is sufficient */
1.1.1.4 ! root       52:        struct {} is_a_simple_lock;
1.1       root       53: };
                     54: 
1.1.1.4 ! root       55: /*
        !            56:  *     Used by macros to assert that the given argument is a simple
        !            57:  *     lock.
        !            58:  */
        !            59: #define simple_lock_assert(l)  (void) &(l)->is_a_simple_lock
        !            60: 
1.1       root       61: typedef struct slock   simple_lock_data_t;
                     62: typedef struct slock   *simple_lock_t;
                     63: 
                     64: #if    MACH_SLOCKS
                     65: /*
                     66:  *     Use the locks.
                     67:  */
                     68: 
                     69: #define        decl_simple_lock_data(class,name) \
                     70: class  simple_lock_data_t      name;
                     71: 
1.1.1.4 ! root       72: #define        simple_lock_addr(lock)  (simple_lock_assert(&(lock)),   \
        !            73:                                 &(lock))
1.1       root       74: 
                     75: #if    (NCPUS > 1)
                     76: 
                     77: /*
                     78:  *     The single-CPU debugging routines are not valid
                     79:  *     on a multiprocessor.
                     80:  */
1.1.1.4 ! root       81: #define        simple_lock_taken(lock)         (simple_lock_assert(lock),      \
        !            82:                                         1)     /* always succeeds */
1.1       root       83: #define check_simple_locks()
1.1.1.4 ! root       84: #define check_simple_locks_enable()
        !            85: #define check_simple_locks_disable()
1.1       root       86: 
                     87: #else  /* NCPUS > 1 */
                     88: /*
                     89:  *     Use our single-CPU locking test routines.
                     90:  */
                     91: 
                     92: extern void            simple_lock_init(simple_lock_t);
1.1.1.4 ! root       93: extern void            _simple_lock(simple_lock_t,
        !            94:                                     const char *, const char *);
1.1       root       95: extern void            simple_unlock(simple_lock_t);
1.1.1.4 ! root       96: extern boolean_t       _simple_lock_try(simple_lock_t,
        !            97:                                         const char *, const char *);
        !            98: 
        !            99: /* We provide simple_lock and simple_lock_try so that we can save the
        !           100:    location.  */
        !           101: #define XSTR(x)                #x
        !           102: #define STR(x)         XSTR(x)
        !           103: #define LOCATION       __FILE__ ":" STR(__LINE__)
        !           104: 
        !           105: #define simple_lock(lock)      _simple_lock((lock), #lock, LOCATION)
        !           106: #define simple_lock_try(lock)  _simple_lock_try((lock), #lock, LOCATION)
1.1       root      107: 
                    108: #define simple_lock_pause()
1.1.1.4 ! root      109: #define simple_lock_taken(lock)                (simple_lock_assert(lock),      \
        !           110:                                         (lock)->lock_data)
1.1       root      111: 
                    112: extern void            check_simple_locks(void);
1.1.1.4 ! root      113: extern void            check_simple_locks_enable(void);
        !           114: extern void            check_simple_locks_disable(void);
1.1       root      115: 
                    116: #endif /* NCPUS > 1 */
                    117: 
                    118: #else  /* MACH_SLOCKS */
                    119: /*
                    120:  * Do not allocate storage for locks if not needed.
                    121:  */
1.1.1.4 ! root      122: struct simple_lock_data_empty { struct {} is_a_simple_lock; };
        !           123: #define        decl_simple_lock_data(class,name)       \
1.1.1.3   root      124: class struct simple_lock_data_empty name;
1.1.1.4 ! root      125: #define        simple_lock_addr(lock)          (simple_lock_assert(&(lock)),   \
        !           126:                                         (simple_lock_t)0)
1.1       root      127: 
                    128: /*
                    129:  *     No multiprocessor locking is necessary.
                    130:  */
1.1.1.4 ! root      131: #define simple_lock_init(l)    simple_lock_assert(l)
        !           132: #define simple_lock(l)         simple_lock_assert(l)
        !           133: #define simple_unlock(l)       simple_lock_assert(l)
        !           134: #define simple_lock_try(l)     (simple_lock_assert(l),         \
        !           135:                                 TRUE)  /* always succeeds */
        !           136: #define simple_lock_taken(l)   (simple_lock_assert(l),         \
        !           137:                                 1)     /* always succeeds */
1.1       root      138: #define check_simple_locks()
1.1.1.4 ! root      139: #define check_simple_locks_enable()
        !           140: #define check_simple_locks_disable()
1.1       root      141: #define simple_lock_pause()
                    142: 
                    143: #endif /* MACH_SLOCKS */
                    144: 
                    145: 
                    146: #define decl_mutex_data(class,name)    decl_simple_lock_data(class,name)
                    147: #define        mutex_try(l)                    simple_lock_try(l)
                    148: #define        mutex_lock(l)                   simple_lock(l)
                    149: #define        mutex_unlock(l)                 simple_unlock(l)
                    150: #define        mutex_init(l)                   simple_lock_init(l)
                    151: 
                    152: 
                    153: /*
                    154:  *     The general lock structure.  Provides for multiple readers,
                    155:  *     upgrading from read to write, and sleeping until the lock
                    156:  *     can be gained.
                    157:  *
                    158:  *     On some architectures, assembly language code in the 'inline'
                    159:  *     program fiddles the lock structures.  It must be changed in
                    160:  *     concert with the structure layout.
                    161:  *
                    162:  *     Only the "interlock" field is used for hardware exclusion;
                    163:  *     other fields are modified with normal instructions after
                    164:  *     acquiring the interlock bit.
                    165:  */
                    166: struct lock {
                    167:        struct thread   *thread;        /* Thread that has lock, if
                    168:                                           recursive locking allowed */
                    169:        unsigned int    read_count:16,  /* Number of accepted readers */
                    170:        /* boolean_t */ want_upgrade:1, /* Read-to-write upgrade waiting */
                    171:        /* boolean_t */ want_write:1,   /* Writer is waiting, or
                    172:                                           locked for write */
                    173:        /* boolean_t */ waiting:1,      /* Someone is sleeping on lock */
                    174:        /* boolean_t */ can_sleep:1,    /* Can attempts to lock go to sleep? */
                    175:                        recursion_depth:12, /* Depth of recursion */
                    176:                        :0; 
1.1.1.4 ! root      177: #if MACH_LDEBUG
        !           178:        struct thread   *writer;
        !           179: #endif /* MACH_LDEBUG */
1.1       root      180:        decl_simple_lock_data(,interlock)
                    181:                                        /* Hardware interlock field.
                    182:                                           Last in the structure so that
                    183:                                           field offsets are the same whether
                    184:                                           or not it is present. */
                    185: };
                    186: 
                    187: typedef struct lock    lock_data_t;
                    188: typedef struct lock    *lock_t;
                    189: 
                    190: /* Sleep locks must work even if no multiprocessing */
                    191: 
                    192: extern void            lock_init(lock_t, boolean_t);
                    193: extern void            lock_sleepable(lock_t, boolean_t);
                    194: extern void            lock_write(lock_t);
                    195: extern void            lock_read(lock_t);
                    196: extern void            lock_done(lock_t);
                    197: extern boolean_t       lock_read_to_write(lock_t);
                    198: extern void            lock_write_to_read(lock_t);
                    199: extern boolean_t       lock_try_write(lock_t);
                    200: extern boolean_t       lock_try_read(lock_t);
                    201: extern boolean_t       lock_try_read_to_write(lock_t);
                    202: 
                    203: #define        lock_read_done(l)       lock_done(l)
                    204: #define        lock_write_done(l)      lock_done(l)
                    205: 
                    206: extern void            lock_set_recursive(lock_t);
                    207: extern void            lock_clear_recursive(lock_t);
                    208: 
1.1.1.4 ! root      209: /* Lock debugging support.  */
        !           210: #if    ! MACH_LDEBUG
        !           211: #define have_read_lock(l)      1
        !           212: #define have_write_lock(l)     1
        !           213: #else  /* MACH_LDEBUG */
        !           214: /* XXX: We don't keep track of readers, so this is an approximation.  */
        !           215: #define have_read_lock(l)      ((l)->read_count > 0)
        !           216: #define have_write_lock(l)     ((l)->writer == current_thread())
        !           217: #endif /* MACH_LDEBUG */
        !           218: #define have_lock(l)           (have_read_lock(l) || have_write_lock(l))
        !           219: 
1.1.1.2   root      220: void db_show_all_slocks(void);
                    221: 
1.1       root      222: #endif /* _KERN_LOCK_H_ */

unix.superglobalmegacorp.com

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