|
|
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.