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