|
|
1.1 ! root 1: #ifndef __SYS_KSYNCH_H__ ! 2: #define __SYS_KSYNCH_H__ ! 3: ! 4: /* ! 5: * Support for basic locks. ! 6: */ ! 7: ! 8: /* ! 9: *-IMPORTS: ! 10: * <common/ccompat.h> ! 11: * __EXTERN_C_BEGIN__ ! 12: * __EXTERN_C_END__ ! 13: * __VOID__ ! 14: * __PROTO () ! 15: * <kernel/_lock.h> ! 16: * __lock_t ! 17: * <kernel/x86lock.h> ! 18: * atomic_uchar_t ! 19: * <sys/types.h> ! 20: * bool_t ! 21: * pl_t ! 22: */ ! 23: ! 24: #if _DDI_DKI ! 25: ! 26: #include <common/ccompat.h> ! 27: #include <kernel/_lock.h> ! 28: #include <kernel/x86lock.h> ! 29: #include <sys/types.h> ! 30: ! 31: /* ! 32: * We can provide a greater level of error checking/reporting if we know we ! 33: * are running on a uniprocessor. Use this feature-test macro to control ! 34: * compilation of code for uniprocessors. ! 35: * ! 36: * Note that many of the traditional simplifying assumptions about ! 37: * uniprocessor systems may not apply if basic-lock acquisition can schedule ! 38: * interrupt contexts (ie, if the system is designed such that interrupts ! 39: * need not be turned off). Such as system would behave effectively like a ! 40: * multiprocessor, although most of the extra checking could still be valid ! 41: * with information gained from the interrupt-handler scheduling system. ! 42: */ ! 43: ! 44: #define __UNIPROCESSOR__ ! 45: ! 46: ! 47: /* ! 48: * For greater scalability, a "ticket lock" should be preferred over a basic ! 49: * test-and-set or test-and-test-and-set spin lock, since it guarantees ! 50: * FIFO ordering and reduces the level of memory contention (important for ! 51: * multiprocessor shared-memory cache performance). See the paper cited at the ! 52: * top of this file for more details. ! 53: * ! 54: * However, ticket locks take slightly more memory and are slightly slower ! 55: * that basic test-and-set spin locks, so we only use them in situations ! 56: * where we expect them to be needed. ! 57: */ ! 58: ! 59: #ifdef __UNIPROCESSOR__ ! 60: #define __TICKET_LOCK__ ! 61: #endif ! 62: ! 63: ! 64: /* ! 65: * Even if ticket locks are used, in the absence of a fetch-and-increment ! 66: * atomic operation a basic test-and-set style lock must be used to control ! 67: * the "ticket gate", so the style of test-and-set lock used will always have ! 68: * consequences. A simple test-and-set spin lock reduces delay, while a ! 69: * test-and-test-and-set spin reduces contention. ! 70: */ ! 71: ! 72: #define __TEST_AND_TEST__ ! 73: ! 74: ! 75: /* ! 76: * Information structure used for holding debugging information about ! 77: * lock structures. ! 78: */ ! 79: ! 80: struct lock_info { ! 81: __CONST__ char * lk_name; /* name for statistics gathering */ ! 82: int lk_flags; /* must be zero */ ! 83: int lk_pad; ! 84: }; ! 85: ! 86: typedef struct lock_info lkinfo_t; ! 87: ! 88: ! 89: /* ! 90: * No lock statistics structure is currently defined, but we reserve the name. ! 91: * ! 92: * For the other lock structures, we publish only their names, and leave the ! 93: * types incomplete. ! 94: */ ! 95: ! 96: typedef __VOID__ lkstat_t; ! 97: typedef __lock_t lock_t; ! 98: typedef struct synch_var sv_t; ! 99: typedef struct sleep_lock sleep_t; ! 100: typedef struct readwrite_lock rwlock_t; ! 101: ! 102: ! 103: __EXTERN_C_BEGIN__ ! 104: ! 105: /* Basic lock functions */ ! 106: ! 107: pl_t LOCK __PROTO ((lock_t * _lockp, pl_t _pl)); ! 108: lock_t * LOCK_ALLOC __PROTO ((__lkhier_t _hierarchy, ! 109: pl_t _min_pl, lkinfo_t * _lkinfop, ! 110: int _flag)); ! 111: void LOCK_DEALLOC __PROTO ((lock_t * _lockp)); ! 112: pl_t TRYLOCK __PROTO ((lock_t * _lockp, pl_t _pl)); ! 113: void UNLOCK __PROTO ((lock_t * _lockp, pl_t _pl)); ! 114: ! 115: ! 116: /* Synchronisation variable functions */ ! 117: ! 118: sv_t * SV_ALLOC __PROTO ((int _flag)); ! 119: void SV_BROADCAST __PROTO ((sv_t * _svp, int _flags)); ! 120: void SV_DEALLOC __PROTO ((sv_t * _svp)); ! 121: void SV_SIGNAL __PROTO ((sv_t * _svp, int _flags)); ! 122: void SV_WAIT __PROTO ((sv_t * _svp, int _priority, ! 123: lock_t * _lkp)); ! 124: bool_t SV_WAIT_SIG __PROTO ((sv_t * _svp, int _priority, ! 125: lock_t * _lkp)); ! 126: ! 127: ! 128: /* Sleep locks */ ! 129: ! 130: sleep_t * SLEEP_ALLOC __PROTO ((int _arg, lkinfo_t * _lkinfop, ! 131: int _flag)); ! 132: void SLEEP_DEALLOC __PROTO ((sleep_t * _lockp)); ! 133: void SLEEP_LOCK __PROTO ((sleep_t * _lockp, int _priority)); ! 134: bool_t SLEEP_LOCKAVAIL __PROTO ((sleep_t * _lockp)); ! 135: bool_t SLEEP_LOCKOWNED __PROTO ((sleep_t * _lockp)); ! 136: bool_t SLEEP_LOCK_SIG __PROTO ((sleep_t * _lockp, int _priority)); ! 137: bool_t SLEEP_TRYLOCK __PROTO ((sleep_t * _lockp)); ! 138: void SLEEP_UNLOCK __PROTO ((sleep_t * _lockp)); ! 139: ! 140: ! 141: /* Read/write locks */ ! 142: ! 143: rwlock_t * RW_ALLOC __PROTO ((__lkhier_t _hierarchy, ! 144: pl_t _min_pl, lkinfo_t * _lkinfop, ! 145: int _flag)); ! 146: void RW_DEALLOC __PROTO ((rwlock_t * _lockp)); ! 147: pl_t RW_RDLOCK __PROTO ((rwlock_t * _lockp, pl_t _pl)); ! 148: pl_t RW_TRYRDLOCK __PROTO ((rwlock_t * _lockp, pl_t _pl)); ! 149: pl_t RW_TRYWRLOCK __PROTO ((rwlock_t * _lockp, pl_t _pl)); ! 150: void RW_UNLOCK __PROTO ((rwlock_t * _lockp, pl_t _pl)); ! 151: pl_t RW_WRLOCK __PROTO ((rwlock_t * _lockp, pl_t _pl)); ! 152: ! 153: __EXTERN_C_END__ ! 154: ! 155: #endif /* _DDI_DKI */ ! 156: ! 157: /* ! 158: * This type is used in the old Coherent source as a primitive form of sleep ! 159: * lock. It should go ASAP, but there's a limit to how much people will let ! 160: * me get away with changing... this type is used in a structure which cannot ! 161: * alter because the "configuration" mechanism for Coherent kernels is to ! 162: * stuff values into the linked object file, in particular the device switch ! 163: * table! ! 164: */ ! 165: ! 166: #if ! _I386 ! 167: ! 168: typedef unsigned char GATE [2]; ! 169: ! 170: #else /* if _I386 */ ! 171: ! 172: typedef struct { ! 173: unsigned char _lock [2]; ! 174: unsigned _count; ! 175: char * _name; ! 176: } GATE [1]; ! 177: ! 178: #define __GATE_INIT(g, name) ((g)->_lock [1] = (g)->_lock [0] = 0, \ ! 179: (g)->_name = (name), (g)->_count = 0) ! 180: #define __GATE_LOCK_COUNT(g) ((g)->_count ++) ! 181: #define __GATE_LOCKED(gate) ((gate)->_lock [0]) ! 182: ! 183: #endif /* ! _I386 */ ! 184: ! 185: #endif /* ! defined (__SYS_KSYNCH_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.