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