|
|
1.1.1.2 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.2 root 5: *
1.1 root 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.
1.1.1.2 root 11: *
1.1 root 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.
1.1.1.2 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.2 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.2 root 22: *
1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * File: ipc/ipc_kmsg.h
28: * Author: Rich Draves
29: * Date: 1989
30: *
31: * Definitions for kernel messages.
32: */
33:
34: #ifndef _IPC_IPC_KMSG_H_
35: #define _IPC_IPC_KMSG_H_
36:
37: #include <mach/machine/vm_types.h>
38: #include <mach/message.h>
39: #include <kern/assert.h>
1.1.1.3 root 40: #include <kern/cpu_number.h>
1.1.1.5 ! root 41: #include <kern/macros.h>
1.1 root 42: #include <kern/kalloc.h>
43: #include <ipc/ipc_marequest.h>
1.1.1.3 root 44: #include <ipc/ipc_object.h>
45: #include <ipc/ipc_types.h>
1.1 root 46: #include <vm/vm_map.h>
47:
48: /*
49: * This structure is only the header for a kmsg buffer;
50: * the actual buffer is normally larger. The rest of the buffer
51: * holds the body of the message.
52: *
53: * In a kmsg, the port fields hold pointers to ports instead
54: * of port names. These pointers hold references.
55: *
56: * The ikm_header.msgh_remote_port field is the destination
57: * of the message.
58: */
59:
60: typedef struct ipc_kmsg {
61: struct ipc_kmsg *ikm_next, *ikm_prev;
62: vm_size_t ikm_size;
63: ipc_marequest_t ikm_marequest;
64: mach_msg_header_t ikm_header;
65: } *ipc_kmsg_t;
66:
67: #define IKM_NULL ((ipc_kmsg_t) 0)
68:
69: #define IKM_OVERHEAD \
70: (sizeof(struct ipc_kmsg) - sizeof(mach_msg_header_t))
71:
72: #define ikm_plus_overhead(size) ((vm_size_t)((size) + IKM_OVERHEAD))
73: #define ikm_less_overhead(size) ((mach_msg_size_t)((size) - IKM_OVERHEAD))
74:
1.1.1.4 root 75: #if MACH_IPC_TEST
1.1 root 76: /*
1.1.1.4 root 77: * For debugging.
1.1 root 78: */
79: #define IKM_BOGUS ((ipc_kmsg_t) 0xffffff10)
80:
1.1.1.4 root 81: #define ikm_mark_bogus(kmsg) \
82: MACRO_BEGIN \
83: (kmsg)->ikm_next = IKM_BOGUS; \
84: (kmsg)->ikm_prev = IKM_BOGUS; \
85: MACRO_END
86:
87: #else /* MACH_IPC_TEST */
88:
89: #define ikm_mark_bogus(kmsg) ;
90:
91: #endif /* MACH_IPC_TEST */
92:
1.1 root 93: /*
94: * We keep a per-processor cache of kernel message buffers.
95: * The cache saves the overhead/locking of using kalloc/kfree.
96: * The per-processor cache seems to miss less than a per-thread cache,
97: * and it also uses less memory. Access to the cache doesn't
98: * require locking.
99: */
100:
101: extern ipc_kmsg_t ipc_kmsg_cache[NCPUS];
102:
103: #define ikm_cache() ipc_kmsg_cache[cpu_number()]
104:
105: /*
106: * The size of the kernel message buffers that will be cached.
107: * IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
1.1.1.4 root 108: *
109: * We use the page size for IKM_SAVED_KMSG_SIZE to make sure the
110: * page is pinned to a single processor.
1.1 root 111: */
112:
1.1.1.4 root 113: #define IKM_SAVED_KMSG_SIZE PAGE_SIZE
1.1 root 114: #define IKM_SAVED_MSG_SIZE ikm_less_overhead(IKM_SAVED_KMSG_SIZE)
115:
116: #define ikm_alloc(size) \
117: ((ipc_kmsg_t) kalloc(ikm_plus_overhead(size)))
118:
119: #define ikm_init(kmsg, size) \
120: MACRO_BEGIN \
121: ikm_init_special((kmsg), ikm_plus_overhead(size)); \
122: MACRO_END
123:
124: #define ikm_init_special(kmsg, size) \
125: MACRO_BEGIN \
126: (kmsg)->ikm_size = (size); \
127: (kmsg)->ikm_marequest = IMAR_NULL; \
128: MACRO_END
129:
130: #define ikm_check_initialized(kmsg, size) \
131: MACRO_BEGIN \
132: assert((kmsg)->ikm_size == (size)); \
133: assert((kmsg)->ikm_marequest == IMAR_NULL); \
134: MACRO_END
135:
136: /*
137: * Non-positive message sizes are special. They indicate that
138: * the message buffer doesn't come from ikm_alloc and
139: * requires some special handling to free.
140: *
141: * ipc_kmsg_free is the non-macro form of ikm_free.
142: * It frees kmsgs of all varieties.
143: */
144:
145: #define IKM_SIZE_NORMA 0
146: #define IKM_SIZE_NETWORK -1
147:
148: #define ikm_free(kmsg) \
149: MACRO_BEGIN \
150: register vm_size_t _size = (kmsg)->ikm_size; \
151: \
152: if ((integer_t)_size > 0) \
153: kfree((vm_offset_t) (kmsg), _size); \
154: else \
155: ipc_kmsg_free(kmsg); \
156: MACRO_END
157:
158: /*
1.1.1.4 root 159: * struct ipc_kmsg_queue is defined in ipc/ipc_kmsg_queue.h
1.1 root 160: */
161:
162: #include <ipc/ipc_kmsg_queue.h>
163:
164: typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t;
165:
166: #define IKMQ_NULL ((ipc_kmsg_queue_t) 0)
167:
168:
169: #define ipc_kmsg_queue_init(queue) \
170: MACRO_BEGIN \
171: (queue)->ikmq_base = IKM_NULL; \
172: MACRO_END
173:
174: #define ipc_kmsg_queue_empty(queue) ((queue)->ikmq_base == IKM_NULL)
175:
176: /* Enqueue a kmsg */
177: extern void ipc_kmsg_enqueue(
178: ipc_kmsg_queue_t queue,
179: ipc_kmsg_t kmsg);
180:
181: /* Dequeue and return a kmsg */
182: extern ipc_kmsg_t ipc_kmsg_dequeue(
183: ipc_kmsg_queue_t queue);
184:
185: /* Pull a kmsg out of a queue */
186: extern void ipc_kmsg_rmqueue(
187: ipc_kmsg_queue_t queue,
188: ipc_kmsg_t kmsg);
189:
190: #define ipc_kmsg_queue_first(queue) ((queue)->ikmq_base)
191:
192: /* Return the kmsg following the given kmsg */
193: extern ipc_kmsg_t ipc_kmsg_queue_next(
194: ipc_kmsg_queue_t queue,
195: ipc_kmsg_t kmsg);
196:
197: #define ipc_kmsg_rmqueue_first_macro(queue, kmsg) \
198: MACRO_BEGIN \
199: register ipc_kmsg_t _next; \
200: \
201: assert((queue)->ikmq_base == (kmsg)); \
202: \
203: _next = (kmsg)->ikm_next; \
204: if (_next == (kmsg)) { \
205: assert((kmsg)->ikm_prev == (kmsg)); \
206: (queue)->ikmq_base = IKM_NULL; \
207: } else { \
208: register ipc_kmsg_t _prev = (kmsg)->ikm_prev; \
209: \
210: (queue)->ikmq_base = _next; \
211: _next->ikm_prev = _prev; \
212: _prev->ikm_next = _next; \
213: } \
1.1.1.4 root 214: ikm_mark_bogus (kmsg); \
1.1 root 215: MACRO_END
216:
217: #define ipc_kmsg_enqueue_macro(queue, kmsg) \
218: MACRO_BEGIN \
219: register ipc_kmsg_t _first = (queue)->ikmq_base; \
220: \
221: if (_first == IKM_NULL) { \
222: (queue)->ikmq_base = (kmsg); \
223: (kmsg)->ikm_next = (kmsg); \
224: (kmsg)->ikm_prev = (kmsg); \
225: } else { \
226: register ipc_kmsg_t _last = _first->ikm_prev; \
227: \
228: (kmsg)->ikm_next = _first; \
229: (kmsg)->ikm_prev = _last; \
230: _first->ikm_prev = (kmsg); \
231: _last->ikm_next = (kmsg); \
232: } \
233: MACRO_END
234:
235: extern void
1.1.1.3 root 236: ipc_kmsg_destroy(ipc_kmsg_t);
1.1 root 237:
238: extern void
1.1.1.3 root 239: ipc_kmsg_clean(ipc_kmsg_t);
1.1 root 240:
241: extern void
1.1.1.3 root 242: ipc_kmsg_free(ipc_kmsg_t);
1.1 root 243:
244: extern mach_msg_return_t
1.1.1.3 root 245: ipc_kmsg_get(mach_msg_header_t *, mach_msg_size_t, ipc_kmsg_t *);
1.1 root 246:
247: extern mach_msg_return_t
1.1.1.3 root 248: ipc_kmsg_get_from_kernel(mach_msg_header_t *, mach_msg_size_t, ipc_kmsg_t *);
1.1 root 249:
250: extern mach_msg_return_t
1.1.1.3 root 251: ipc_kmsg_put(mach_msg_header_t *, ipc_kmsg_t, mach_msg_size_t);
1.1 root 252:
253: extern void
1.1.1.3 root 254: ipc_kmsg_put_to_kernel(mach_msg_header_t *, ipc_kmsg_t, mach_msg_size_t);
1.1 root 255:
256: extern mach_msg_return_t
1.1.1.3 root 257: ipc_kmsg_copyin_header(mach_msg_header_t *, ipc_space_t, mach_port_t);
1.1 root 258:
259: extern mach_msg_return_t
1.1.1.3 root 260: ipc_kmsg_copyin(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_t);
1.1 root 261:
262: extern void
1.1.1.3 root 263: ipc_kmsg_copyin_from_kernel(ipc_kmsg_t);
1.1 root 264:
265: extern mach_msg_return_t
1.1.1.3 root 266: ipc_kmsg_copyout_header(mach_msg_header_t *, ipc_space_t, mach_port_t);
1.1 root 267:
268: extern mach_msg_return_t
1.1.1.3 root 269: ipc_kmsg_copyout_object(ipc_space_t, ipc_object_t,
270: mach_msg_type_name_t, mach_port_t *);
1.1 root 271:
272: extern mach_msg_return_t
1.1.1.3 root 273: ipc_kmsg_copyout_body(vm_offset_t, vm_offset_t, ipc_space_t, vm_map_t);
1.1 root 274:
275: extern mach_msg_return_t
1.1.1.3 root 276: ipc_kmsg_copyout(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_t);
1.1 root 277:
278: extern mach_msg_return_t
1.1.1.3 root 279: ipc_kmsg_copyout_pseudo(ipc_kmsg_t, ipc_space_t, vm_map_t);
1.1 root 280:
281: extern void
1.1.1.3 root 282: ipc_kmsg_copyout_dest(ipc_kmsg_t, ipc_space_t);
1.1 root 283:
1.1.1.2 root 284: #endif /* _IPC_IPC_KMSG_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.