1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Debug buffer manager to detect buffer under- and overflows.
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \author Jose Fonseca <jrfonseca@tungstengraphics.com>
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_compiler.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "os/os_thread.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_double_list.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_time.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug_stack.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pb_buffer.h"
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pb_bufmgr.h"
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define PB_DEBUG_CREATE_BACKTRACE 8
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define PB_DEBUG_MAP_BACKTRACE 8
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convenience macro (type safe).
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SUPER(__derived) (&(__derived)->base)
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_debug_manager;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Wrapper around a pipe buffer which adds delayed destruction.
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_debug_buffer
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_buffer base;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_buffer *buffer;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_manager *mgr;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_size underflow_size;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_size overflow_size;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct debug_stack_frame create_backtrace[PB_DEBUG_CREATE_BACKTRACE];
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex mutex;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned map_count;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct debug_stack_frame map_backtrace[PB_DEBUG_MAP_BACKTRACE];
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct list_head head;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_debug_manager
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_manager base;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_manager *provider;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_size underflow_size;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_size overflow_size;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex mutex;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct list_head list;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct pb_debug_buffer *
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer(struct pb_buffer *buf)
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(buf);
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (struct pb_debug_buffer *)buf;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct pb_debug_manager *
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_manager(struct pb_manager *mgr)
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(mgr);
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (struct pb_debug_manager *)mgr;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const uint8_t random_pattern[32] = {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   0xaf, 0xcf, 0xa5, 0xa2, 0xc2, 0x63, 0x15, 0x1a,
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   0x7e, 0xe2, 0x7e, 0x84, 0x15, 0x49, 0xa2, 0x1e,
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   0x49, 0x63, 0xf5, 0x52, 0x74, 0x66, 0x9e, 0xc4,
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   0x6d, 0xcf, 0x2c, 0x4a, 0x74, 0xe6, 0xfd, 0x94
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfill_random_pattern(uint8_t *dst, pb_size size)
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_size i = 0;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while(size--) {
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *dst++ = random_pattern[i++];
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i &= sizeof(random_pattern) - 1;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcheck_random_pattern(const uint8_t *dst, pb_size size,
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     pb_size *min_ofs, pb_size *max_ofs)
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean result = TRUE;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_size i;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *min_ofs = size;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *max_ofs = 0;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for(i = 0; i < size; ++i) {
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(*dst++ != random_pattern[i % sizeof(random_pattern)]) {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *min_ofs = MIN2(*min_ofs, i);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *max_ofs = MAX2(*max_ofs, i);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = FALSE;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_fill(struct pb_debug_buffer *buf)
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint8_t *map;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   map = pb_map(buf->buffer, PB_USAGE_CPU_WRITE, NULL);
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(map);
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(map) {
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fill_random_pattern(map, buf->underflow_size);
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fill_random_pattern(map + buf->underflow_size + buf->base.size,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          buf->overflow_size);
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_unmap(buf->buffer);
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Check for under/over flows.
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Should be called with the buffer unmaped.
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_check(struct pb_debug_buffer *buf)
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint8_t *map;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   map = pb_map(buf->buffer,
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                PB_USAGE_CPU_READ |
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                PB_USAGE_UNSYNCHRONIZED, NULL);
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(map);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(map) {
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      boolean underflow, overflow;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_size min_ofs, max_ofs;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      underflow = !check_random_pattern(map, buf->underflow_size,
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        &min_ofs, &max_ofs);
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(underflow) {
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("buffer underflow (offset -%u%s to -%u bytes) detected\n",
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      buf->underflow_size - min_ofs,
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      min_ofs == 0 ? "+" : "",
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      buf->underflow_size - max_ofs);
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      overflow = !check_random_pattern(map + buf->underflow_size + buf->base.size,
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       buf->overflow_size,
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       &min_ofs, &max_ofs);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(overflow) {
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("buffer overflow (size %u plus offset %u to %u%s bytes) detected\n",
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      buf->base.size,
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      min_ofs,
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      max_ofs,
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      max_ofs == buf->overflow_size - 1 ? "+" : "");
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(underflow || overflow)
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_assert(!underflow);
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_assert(!overflow);
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* re-fill if not aborted */
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(underflow)
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fill_random_pattern(map, buf->underflow_size);
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(overflow)
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fill_random_pattern(map + buf->underflow_size + buf->base.size,
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             buf->overflow_size);
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_unmap(buf->buffer);
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_destroy(struct pb_buffer *_buf)
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_manager *mgr = buf->mgr;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!pipe_is_referenced(&buf->base.reference));
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_debug_buffer_check(buf);
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_lock(mgr->mutex);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LIST_DEL(&buf->head);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_unlock(mgr->mutex);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_destroy(buf->mutex);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_reference(&buf->buffer, NULL);
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(buf);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_map(struct pb_buffer *_buf,
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    unsigned flags, void *flush_ctx)
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *map;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_debug_buffer_check(buf);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   map = pb_map(buf->buffer, flags, flush_ctx);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(!map)
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(map) {
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_mutex_lock(buf->mutex);
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ++buf->map_count;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_backtrace_capture(buf->map_backtrace, 1, PB_DEBUG_MAP_BACKTRACE);
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_mutex_unlock(buf->mutex);
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (uint8_t *)map + buf->underflow_size;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_unmap(struct pb_buffer *_buf)
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_lock(buf->mutex);
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(buf->map_count);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(buf->map_count)
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      --buf->map_count;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_unlock(buf->mutex);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_unmap(buf->buffer);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_debug_buffer_check(buf);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_get_base_buffer(struct pb_buffer *_buf,
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                struct pb_buffer **base_buf,
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                pb_size *offset)
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_get_base_buffer(buf->buffer, base_buf, offset);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *offset += buf->underflow_size;
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum pipe_error
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_validate(struct pb_buffer *_buf,
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         struct pb_validate *vl,
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         unsigned flags)
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_lock(buf->mutex);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(buf->map_count) {
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("%s: attempting to validate a mapped buffer\n", __FUNCTION__);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("last map backtrace is\n");
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_backtrace_dump(buf->map_backtrace, PB_DEBUG_MAP_BACKTRACE);
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_unlock(buf->mutex);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_debug_buffer_check(buf);
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pb_validate(buf->buffer, vl, flags);
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_fence(struct pb_buffer *_buf,
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct pipe_fence_handle *fence)
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_fence(buf->buffer, fence);
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst struct pb_vtbl
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_buffer_vtbl = {
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_debug_buffer_destroy,
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_debug_buffer_map,
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_debug_buffer_unmap,
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_debug_buffer_validate,
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_debug_buffer_fence,
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_debug_buffer_get_base_buffer
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_manager_dump_locked(struct pb_debug_manager *mgr)
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct list_head *curr, *next;
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_buffer *buf;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   curr = mgr->list.next;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   next = curr->next;
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while(curr != &mgr->list) {
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      buf = LIST_ENTRY(struct pb_debug_buffer, curr, head);
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("buffer = %p\n", (void *) buf);
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("    .size = 0x%x\n", buf->base.size);
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      curr = next;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      next = curr->next;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pb_buffer *
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_manager_create_buffer(struct pb_manager *_mgr,
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               pb_size size,
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               const struct pb_desc *desc)
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_buffer *buf;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_desc real_desc;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_size real_size;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(size);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(desc->alignment);
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf = CALLOC_STRUCT(pb_debug_buffer);
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(!buf)
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   real_size = mgr->underflow_size + size + mgr->overflow_size;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   real_desc = *desc;
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   real_desc.usage |= PB_USAGE_CPU_WRITE;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   real_desc.usage |= PB_USAGE_CPU_READ;
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf->buffer = mgr->provider->create_buffer(mgr->provider,
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              real_size,
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              &real_desc);
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(!buf->buffer) {
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(buf);
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_mutex_lock(mgr->mutex);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("%s: failed to create buffer\n", __FUNCTION__);
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(!LIST_IS_EMPTY(&mgr->list))
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pb_debug_manager_dump_locked(mgr);
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_mutex_unlock(mgr->mutex);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(pipe_is_referenced(&buf->buffer->reference));
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(pb_check_alignment(real_desc.alignment, buf->buffer->alignment));
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(pb_check_usage(real_desc.usage, buf->buffer->usage));
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(buf->buffer->size >= real_size);
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_reference_init(&buf->base.reference, 1);
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf->base.alignment = desc->alignment;
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf->base.usage = desc->usage;
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf->base.size = size;
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf->base.vtbl = &pb_debug_buffer_vtbl;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf->mgr = mgr;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf->underflow_size = mgr->underflow_size;
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf->overflow_size = buf->buffer->size - buf->underflow_size - size;
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   debug_backtrace_capture(buf->create_backtrace, 1, PB_DEBUG_CREATE_BACKTRACE);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pb_debug_buffer_fill(buf);
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_init(buf->mutex);
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_lock(mgr->mutex);
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LIST_ADDTAIL(&buf->head, &mgr->list);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_unlock(mgr->mutex);
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &buf->base;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_manager_flush(struct pb_manager *_mgr)
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(mgr->provider->flush);
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(mgr->provider->flush)
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mgr->provider->flush(mgr->provider);
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_manager_destroy(struct pb_manager *_mgr)
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_lock(mgr->mutex);
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(!LIST_IS_EMPTY(&mgr->list)) {
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("%s: unfreed buffers\n", __FUNCTION__);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pb_debug_manager_dump_locked(mgr);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_unlock(mgr->mutex);
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_destroy(mgr->mutex);
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mgr->provider->destroy(mgr->provider);
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(mgr);
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_manager *
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_manager_create(struct pb_manager *provider,
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        pb_size underflow_size, pb_size overflow_size)
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pb_debug_manager *mgr;
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(!provider)
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mgr = CALLOC_STRUCT(pb_debug_manager);
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!mgr)
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mgr->base.destroy = pb_debug_manager_destroy;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mgr->base.create_buffer = pb_debug_manager_create_buffer;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mgr->base.flush = pb_debug_manager_flush;
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mgr->provider = provider;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mgr->underflow_size = underflow_size;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mgr->overflow_size = overflow_size;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex_init(mgr->mutex);
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LIST_INITHEAD(&mgr->list);
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &mgr->base;
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else /* !DEBUG */
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_manager *
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_debug_manager_create(struct pb_manager *provider,
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        pb_size underflow_size, pb_size overflow_size)
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return provider;
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* !DEBUG */
498