|
|
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 <cpus.h> ! 38: #include <mach_ldebug.h> ! 39: ! 40: #include <mach/boolean.h> ! 41: #include <mach/machine/vm_types.h> ! 42: ! 43: #if NCPUS > 1 ! 44: #include <machine/lock.h>/*XXX*/ ! 45: #endif ! 46: ! 47: #define MACH_SLOCKS ((NCPUS > 1) || MACH_LDEBUG) ! 48: ! 49: /* ! 50: * A simple spin lock. ! 51: */ ! 52: ! 53: struct slock { ! 54: volatile natural_t lock_data; /* in general 1 bit is sufficient */ ! 55: }; ! 56: ! 57: typedef struct slock simple_lock_data_t; ! 58: typedef struct slock *simple_lock_t; ! 59: ! 60: #if MACH_SLOCKS ! 61: /* ! 62: * Use the locks. ! 63: */ ! 64: ! 65: #define decl_simple_lock_data(class,name) \ ! 66: class simple_lock_data_t name; ! 67: ! 68: #define simple_lock_addr(lock) (&(lock)) ! 69: ! 70: #if (NCPUS > 1) ! 71: ! 72: /* ! 73: * The single-CPU debugging routines are not valid ! 74: * on a multiprocessor. ! 75: */ ! 76: #define simple_lock_taken(lock) (1) /* always succeeds */ ! 77: #define check_simple_locks() ! 78: ! 79: #else /* NCPUS > 1 */ ! 80: /* ! 81: * Use our single-CPU locking test routines. ! 82: */ ! 83: ! 84: extern void simple_lock_init(simple_lock_t); ! 85: extern void simple_lock(simple_lock_t); ! 86: extern void simple_unlock(simple_lock_t); ! 87: extern boolean_t simple_lock_try(simple_lock_t); ! 88: ! 89: #define simple_lock_pause() ! 90: #define simple_lock_taken(lock) ((lock)->lock_data) ! 91: ! 92: extern void check_simple_locks(void); ! 93: ! 94: #endif /* NCPUS > 1 */ ! 95: ! 96: #else /* MACH_SLOCKS */ ! 97: /* ! 98: * Do not allocate storage for locks if not needed. ! 99: */ ! 100: #define decl_simple_lock_data(class,name) ! 101: #define simple_lock_addr(lock) ((simple_lock_t)0) ! 102: ! 103: /* ! 104: * No multiprocessor locking is necessary. ! 105: */ ! 106: #define simple_lock_init(l) ! 107: #define simple_lock(l) ! 108: #define simple_unlock(l) ! 109: #define simple_lock_try(l) (TRUE) /* always succeeds */ ! 110: #define simple_lock_taken(l) (1) /* always succeeds */ ! 111: #define check_simple_locks() ! 112: #define simple_lock_pause() ! 113: ! 114: #endif /* MACH_SLOCKS */ ! 115: ! 116: ! 117: #define decl_mutex_data(class,name) decl_simple_lock_data(class,name) ! 118: #define mutex_try(l) simple_lock_try(l) ! 119: #define mutex_lock(l) simple_lock(l) ! 120: #define mutex_unlock(l) simple_unlock(l) ! 121: #define mutex_init(l) simple_lock_init(l) ! 122: ! 123: ! 124: /* ! 125: * The general lock structure. Provides for multiple readers, ! 126: * upgrading from read to write, and sleeping until the lock ! 127: * can be gained. ! 128: * ! 129: * On some architectures, assembly language code in the 'inline' ! 130: * program fiddles the lock structures. It must be changed in ! 131: * concert with the structure layout. ! 132: * ! 133: * Only the "interlock" field is used for hardware exclusion; ! 134: * other fields are modified with normal instructions after ! 135: * acquiring the interlock bit. ! 136: */ ! 137: struct lock { ! 138: struct thread *thread; /* Thread that has lock, if ! 139: recursive locking allowed */ ! 140: unsigned int read_count:16, /* Number of accepted readers */ ! 141: /* boolean_t */ want_upgrade:1, /* Read-to-write upgrade waiting */ ! 142: /* boolean_t */ want_write:1, /* Writer is waiting, or ! 143: locked for write */ ! 144: /* boolean_t */ waiting:1, /* Someone is sleeping on lock */ ! 145: /* boolean_t */ can_sleep:1, /* Can attempts to lock go to sleep? */ ! 146: recursion_depth:12, /* Depth of recursion */ ! 147: :0; ! 148: decl_simple_lock_data(,interlock) ! 149: /* Hardware interlock field. ! 150: Last in the structure so that ! 151: field offsets are the same whether ! 152: or not it is present. */ ! 153: }; ! 154: ! 155: typedef struct lock lock_data_t; ! 156: typedef struct lock *lock_t; ! 157: ! 158: /* Sleep locks must work even if no multiprocessing */ ! 159: ! 160: extern void lock_init(lock_t, boolean_t); ! 161: extern void lock_sleepable(lock_t, boolean_t); ! 162: extern void lock_write(lock_t); ! 163: extern void lock_read(lock_t); ! 164: extern void lock_done(lock_t); ! 165: extern boolean_t lock_read_to_write(lock_t); ! 166: extern void lock_write_to_read(lock_t); ! 167: extern boolean_t lock_try_write(lock_t); ! 168: extern boolean_t lock_try_read(lock_t); ! 169: extern boolean_t lock_try_read_to_write(lock_t); ! 170: ! 171: #define lock_read_done(l) lock_done(l) ! 172: #define lock_write_done(l) lock_done(l) ! 173: ! 174: extern void lock_set_recursive(lock_t); ! 175: extern void lock_clear_recursive(lock_t); ! 176: ! 177: #endif /* _KERN_LOCK_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.