|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * @OSF_COPYRIGHT@
24: *
25: */
26:
27: /*
28: * Really a C file, but I'd like to have this code available in both
29: * the kernel and the application, so I'll put it in a .h file. This
30: * file needs to be included only once in the AIL or ME, into a .c file
31: * where it will be compiled.
32: */
33:
34: /*
35: * Since these are debug functions, it doesn't matter which processor macro
36: * version I use; I don't mind spoiling cache while I'm debugging.
37: */
38:
39: #include <mach/flipc_cb.h>
40: /*
41: * Print (using printf) all buffers in the communications buffer that
42: * are not on any endpoint or on the buffer freelist. Only active
43: * endpoints are checked.
44: *
45: * Note that no locking is done; this function implicitly assumes the
46: * communications buffer is in a quiescent state. It is expected that
47: * this function will normally be called from a debugger.
48: *
49: * As long as it is at it, this function prints buffers that are
50: * doubly owned (valid pointers to them from two places).
51: */
52:
53: /*
54: * Given that these functions will normally be called from the debugger,
55: * there isn't any need to globally visible prototypes for them. To
56: * eliminate compilation warnings, we include prototypes for the functions
57: * here in the file.
58: */
59: static void flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t,
60: flipc_data_buffer_t);
61: void flipcdbg_print_unowned_buffers(void);
62: void flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr);
63:
64: #ifdef __GNUC__
65: __inline__
66: #endif
67: static void
68: flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t cb_ctl,
69: flipc_data_buffer_t buffer)
70: {
71: unsigned char *buffer_base = flipc_cb_base + cb_ctl->data_buffer.start;
72: int bitpos = ((((unsigned char *) buffer) - buffer_base)
73: / cb_ctl->data_buffer_size);
74: int element = bitpos / (sizeof(unsigned long) * 8);
75: int subbitpos = bitpos - element * sizeof(unsigned long) * 8;
76:
77: /* Is that position set already? */
78: if (flipc_debug_buffer_bitvec[element] & (1 << subbitpos))
79: printf("Buffer 0x%x (idx: %d, cbptr: 0x%x) is multiply referenced.\n",
80: buffer, bitpos, FLIPC_CBPTR(buffer));
81:
82: /* Set it. */
83: flipc_debug_buffer_bitvec[element] |= (1 << subbitpos);
84: }
85:
86: void
87: flipcdbg_print_unowned_buffers(void)
88: {
89: flipc_comm_buffer_ctl_t cb_ctl =
90: (flipc_comm_buffer_ctl_t) flipc_cb_base;
91: int i;
92: unsigned long bitvec_length = ((cb_ctl->data_buffer.number + sizeof(unsigned long) * 8)
93: / (sizeof(unsigned int) * 8));
94: flipc_data_buffer_t current_buffer;
95: flipc_endpoint_t current_endpoint;
96: flipc_cb_ptr current_cbptr;
97: int header_printed = 0;
98:
99: /* Clean out the bitvec. */
100: for (i = 0; i < bitvec_length; i++)
101: flipc_debug_buffer_bitvec[i] = 0;
102:
103: /* Go through the freelist, setting bits for each buffer. */
104: for (current_cbptr = cb_ctl->data_buffer.free;
105: current_cbptr != FLIPC_CBPTR_NULL;
106: current_cbptr = current_buffer->u.free) {
107: int bitpos;
108: int element, subbitpos;
109:
110: current_buffer = FLIPC_DATA_BUFFER_PTR(current_cbptr);
111: flipcdbg_update_bufferset_bitvec(cb_ctl, current_buffer);
112: }
113:
114: /* Go through all the endpoints, again setting bits for each buffer. */
115: for (current_endpoint = FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start);
116: (current_endpoint
117: < (FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)
118: + cb_ctl->endpoint.number));
119: current_endpoint++) {
120: if (EXTRACT_ENABLED(current_endpoint->saildm_dpb_or_enabled)) {
121: flipc_cb_ptr current_ptr =
122: (EXTRACT_DPB(current_endpoint->saildm_dpb_or_enabled)
123: ? current_endpoint->sme_process_ptr
124: : current_endpoint->shrd_acquire_ptr);
125: flipc_cb_ptr limit_ptr = current_endpoint->sail_release_ptr;
126:
127: while (current_ptr != limit_ptr) {
128: flipc_cb_ptr current_buffer_cbptr =
129: *FLIPC_BUFFERLIST_PTR(current_ptr);
130: flipc_data_buffer_t current_buffer =
131: FLIPC_DATA_BUFFER_PTR(current_buffer_cbptr);
132:
133: /* Mark this as set. */
134: flipcdbg_update_bufferset_bitvec(cb_ctl, current_buffer);
135:
136: /* Increment the current pointer. */
137: current_ptr = NEXT_BUFFERLIST_PTR_ME(current_ptr,
138: current_endpoint);
139: }
140: }
141: }
142:
143: /* Ok, we should have marked every buffer that has a reference.
144: Print out all the ones that done have references. */
145: for (i = 0; i < bitvec_length; i++) {
146: int this_limit =
147: ((i == bitvec_length - 1)
148: ? cb_ctl->data_buffer.number % (sizeof(unsigned long)*8)
149: : sizeof(unsigned long)*8);
150: if (flipc_debug_buffer_bitvec[i] != (unsigned long) -1) {
151: int j;
152: for (j = 0; j < this_limit; j++) {
153: if (!(flipc_debug_buffer_bitvec[i] & (1 << j))) {
154: int buffer_bitpos = i * sizeof(unsigned long) * 8 + j;
155: flipc_cb_ptr buffer_cbptr =
156: (buffer_bitpos * cb_ctl->data_buffer_size
157: + cb_ctl->data_buffer.start);
158: flipc_data_buffer_t buffer_ptr =
159: FLIPC_DATA_BUFFER_PTR(buffer_cbptr);
160:
161: /* Print header if necessary. */
162: if (!header_printed) {
163: header_printed = 1;
164: printf("Unreferenced buffers (ptr,idx,cbptr):");
165: }
166:
167: /* Print buffer. */
168: printf(" (0x%x,%d,0x%x)", buffer_ptr, buffer_bitpos,
169: buffer_cbptr);
170: }
171: }
172: }
173: }
174: if (header_printed)
175: printf("\n");
176: }
177:
178: void
179: flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr)
180: {
181: flipc_comm_buffer_ctl_t cb_ctl =
182: (flipc_comm_buffer_ctl_t) flipc_cb_base;
183: int found_on_freelist = 0;
184: int found_on_endpoints = 0;
185: int i;
186: flipc_endpoint_t current_endpoint;
187:
188: flipc_cb_ptr current_cbptr;
189: flipc_data_buffer_t current_buffer;
190:
191: /* Go through the freelist, looking for buffer. */
192: for (i = 0, current_cbptr = cb_ctl->data_buffer.free;
193: current_cbptr != FLIPC_CBPTR_NULL;
194: i++, current_cbptr = current_buffer->u.free) {
195: if (current_cbptr == buffer_cbptr) {
196: printf("Buffer found on freelist in position %d\n", i);
197: found_on_freelist = 1;
198: }
199: current_buffer = FLIPC_DATA_BUFFER_PTR(current_cbptr);
200: if (i > cb_ctl->data_buffer.number) {
201: printf ("**Some form of corruption following freelist.**");
202: return;
203: }
204: }
205: if (found_on_freelist)
206: printf("(Total buffers on freelist: %d/%d)\n", i,
207: cb_ctl->data_buffer.number);
208:
209: /* Go through all the endpoints, again looking for the buffer. */
210: for (current_endpoint = FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start);
211: (current_endpoint
212: < (FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)
213: + cb_ctl->endpoint.number));
214: current_endpoint++) {
215: if (EXTRACT_ENABLED(current_endpoint->saildm_dpb_or_enabled)) {
216: flipc_cb_ptr current_ptr =
217: (EXTRACT_DPB(current_endpoint->saildm_dpb_or_enabled)
218: ? current_endpoint->sme_process_ptr
219: : current_endpoint->shrd_acquire_ptr);
220: flipc_cb_ptr limit_ptr = current_endpoint->sail_release_ptr;
221:
222: while (current_ptr != limit_ptr) {
223: current_cbptr = *FLIPC_BUFFERLIST_PTR(current_ptr);
224:
225: if (current_cbptr == buffer_cbptr) {
226: printf("Buffer found on endpoint 0x%x (idx: %d)\n",
227: current_endpoint,
228: (current_endpoint
229: - FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)));
230: found_on_endpoints = 1;
231: }
232:
233: /* Increment the current pointer. */
234: current_ptr = NEXT_BUFFERLIST_PTR_ME(current_ptr,
235: current_endpoint);
236: }
237: }
238: }
239: }
240:
241:
242:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.