|
|
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 root 41: #include <kern/macro_help.h>
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:
75: /*
76: * XXX For debugging.
77: */
78: #define IKM_BOGUS ((ipc_kmsg_t) 0xffffff10)
79:
80: /*
81: * We keep a per-processor cache of kernel message buffers.
82: * The cache saves the overhead/locking of using kalloc/kfree.
83: * The per-processor cache seems to miss less than a per-thread cache,
84: * and it also uses less memory. Access to the cache doesn't
85: * require locking.
86: */
87:
88: extern ipc_kmsg_t ipc_kmsg_cache[NCPUS];
89:
90: #define ikm_cache() ipc_kmsg_cache[cpu_number()]
91:
92: /*
93: * The size of the kernel message buffers that will be cached.
94: * IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
95: */
96:
97: #define IKM_SAVED_KMSG_SIZE ((vm_size_t) 256)
98: #define IKM_SAVED_MSG_SIZE ikm_less_overhead(IKM_SAVED_KMSG_SIZE)
99:
100: #define ikm_alloc(size) \
101: ((ipc_kmsg_t) kalloc(ikm_plus_overhead(size)))
102:
103: #define ikm_init(kmsg, size) \
104: MACRO_BEGIN \
105: ikm_init_special((kmsg), ikm_plus_overhead(size)); \
106: MACRO_END
107:
108: #define ikm_init_special(kmsg, size) \
109: MACRO_BEGIN \
110: (kmsg)->ikm_size = (size); \
111: (kmsg)->ikm_marequest = IMAR_NULL; \
112: MACRO_END
113:
114: #define ikm_check_initialized(kmsg, size) \
115: MACRO_BEGIN \
116: assert((kmsg)->ikm_size == (size)); \
117: assert((kmsg)->ikm_marequest == IMAR_NULL); \
118: MACRO_END
119:
120: /*
121: * Non-positive message sizes are special. They indicate that
122: * the message buffer doesn't come from ikm_alloc and
123: * requires some special handling to free.
124: *
125: * ipc_kmsg_free is the non-macro form of ikm_free.
126: * It frees kmsgs of all varieties.
127: */
128:
129: #define IKM_SIZE_NORMA 0
130: #define IKM_SIZE_NETWORK -1
131:
132: #define ikm_free(kmsg) \
133: MACRO_BEGIN \
134: register vm_size_t _size = (kmsg)->ikm_size; \
135: \
136: if ((integer_t)_size > 0) \
137: kfree((vm_offset_t) (kmsg), _size); \
138: else \
139: ipc_kmsg_free(kmsg); \
140: MACRO_END
141:
142: /*
143: * struct ipc_kmsg_queue is defined in kern/thread.h instead of here,
144: * so that kern/thread.h doesn't have to include ipc/ipc_kmsg.h.
145: */
146:
147: #include <ipc/ipc_kmsg_queue.h>
148:
149: typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t;
150:
151: #define IKMQ_NULL ((ipc_kmsg_queue_t) 0)
152:
153:
154: #define ipc_kmsg_queue_init(queue) \
155: MACRO_BEGIN \
156: (queue)->ikmq_base = IKM_NULL; \
157: MACRO_END
158:
159: #define ipc_kmsg_queue_empty(queue) ((queue)->ikmq_base == IKM_NULL)
160:
161: /* Enqueue a kmsg */
162: extern void ipc_kmsg_enqueue(
163: ipc_kmsg_queue_t queue,
164: ipc_kmsg_t kmsg);
165:
166: /* Dequeue and return a kmsg */
167: extern ipc_kmsg_t ipc_kmsg_dequeue(
168: ipc_kmsg_queue_t queue);
169:
170: /* Pull a kmsg out of a queue */
171: extern void ipc_kmsg_rmqueue(
172: ipc_kmsg_queue_t queue,
173: ipc_kmsg_t kmsg);
174:
175: #define ipc_kmsg_queue_first(queue) ((queue)->ikmq_base)
176:
177: /* Return the kmsg following the given kmsg */
178: extern ipc_kmsg_t ipc_kmsg_queue_next(
179: ipc_kmsg_queue_t queue,
180: ipc_kmsg_t kmsg);
181:
182: #define ipc_kmsg_rmqueue_first_macro(queue, kmsg) \
183: MACRO_BEGIN \
184: register ipc_kmsg_t _next; \
185: \
186: assert((queue)->ikmq_base == (kmsg)); \
187: \
188: _next = (kmsg)->ikm_next; \
189: if (_next == (kmsg)) { \
190: assert((kmsg)->ikm_prev == (kmsg)); \
191: (queue)->ikmq_base = IKM_NULL; \
192: } else { \
193: register ipc_kmsg_t _prev = (kmsg)->ikm_prev; \
194: \
195: (queue)->ikmq_base = _next; \
196: _next->ikm_prev = _prev; \
197: _prev->ikm_next = _next; \
198: } \
199: /* XXX Debug paranoia */ \
200: kmsg->ikm_next = IKM_BOGUS; \
201: kmsg->ikm_prev = IKM_BOGUS; \
202: MACRO_END
203:
204: #define ipc_kmsg_enqueue_macro(queue, kmsg) \
205: MACRO_BEGIN \
206: register ipc_kmsg_t _first = (queue)->ikmq_base; \
207: \
208: if (_first == IKM_NULL) { \
209: (queue)->ikmq_base = (kmsg); \
210: (kmsg)->ikm_next = (kmsg); \
211: (kmsg)->ikm_prev = (kmsg); \
212: } else { \
213: register ipc_kmsg_t _last = _first->ikm_prev; \
214: \
215: (kmsg)->ikm_next = _first; \
216: (kmsg)->ikm_prev = _last; \
217: _first->ikm_prev = (kmsg); \
218: _last->ikm_next = (kmsg); \
219: } \
220: MACRO_END
221:
222: extern void
1.1.1.3 ! root 223: ipc_kmsg_destroy(ipc_kmsg_t);
1.1 root 224:
225: extern void
1.1.1.3 ! root 226: ipc_kmsg_clean(ipc_kmsg_t);
1.1 root 227:
228: extern void
1.1.1.3 ! root 229: ipc_kmsg_free(ipc_kmsg_t);
1.1 root 230:
231: extern mach_msg_return_t
1.1.1.3 ! root 232: ipc_kmsg_get(mach_msg_header_t *, mach_msg_size_t, ipc_kmsg_t *);
1.1 root 233:
234: extern mach_msg_return_t
1.1.1.3 ! root 235: ipc_kmsg_get_from_kernel(mach_msg_header_t *, mach_msg_size_t, ipc_kmsg_t *);
1.1 root 236:
237: extern mach_msg_return_t
1.1.1.3 ! root 238: ipc_kmsg_put(mach_msg_header_t *, ipc_kmsg_t, mach_msg_size_t);
1.1 root 239:
240: extern void
1.1.1.3 ! root 241: ipc_kmsg_put_to_kernel(mach_msg_header_t *, ipc_kmsg_t, mach_msg_size_t);
1.1 root 242:
243: extern mach_msg_return_t
1.1.1.3 ! root 244: ipc_kmsg_copyin_header(mach_msg_header_t *, ipc_space_t, mach_port_t);
1.1 root 245:
246: extern mach_msg_return_t
1.1.1.3 ! root 247: ipc_kmsg_copyin(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_t);
1.1 root 248:
249: extern void
1.1.1.3 ! root 250: ipc_kmsg_copyin_from_kernel(ipc_kmsg_t);
1.1 root 251:
252: extern mach_msg_return_t
1.1.1.3 ! root 253: ipc_kmsg_copyout_header(mach_msg_header_t *, ipc_space_t, mach_port_t);
1.1 root 254:
255: extern mach_msg_return_t
1.1.1.3 ! root 256: ipc_kmsg_copyout_object(ipc_space_t, ipc_object_t,
! 257: mach_msg_type_name_t, mach_port_t *);
1.1 root 258:
259: extern mach_msg_return_t
1.1.1.3 ! root 260: ipc_kmsg_copyout_body(vm_offset_t, vm_offset_t, ipc_space_t, vm_map_t);
1.1 root 261:
262: extern mach_msg_return_t
1.1.1.3 ! root 263: ipc_kmsg_copyout(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_t);
1.1 root 264:
265: extern mach_msg_return_t
1.1.1.3 ! root 266: ipc_kmsg_copyout_pseudo(ipc_kmsg_t, ipc_space_t, vm_map_t);
1.1 root 267:
268: extern void
1.1.1.3 ! root 269: ipc_kmsg_copyout_dest(ipc_kmsg_t, ipc_space_t);
1.1 root 270:
1.1.1.2 root 271: #endif /* _IPC_IPC_KMSG_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.