1d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca/**************************************************************************
2d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca *
3d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * All Rights Reserved.
5d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca *
6d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
7d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * copy of this software and associated documentation files (the
8d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * "Software"), to deal in the Software without restriction, including
9d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * without limitation the rights to use, copy, modify, merge, publish,
10d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * distribute, sub license, and/or sell copies of the Software, and to
11d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * permit persons to whom the Software is furnished to do so, subject to
12d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * the following conditions:
13d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca *
14d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * The above copyright notice and this permission notice (including the
15d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * next paragraph) shall be included in all copies or substantial portions
16d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * of the Software.
17d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca *
18d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca *
26d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca **************************************************************************/
27d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
28d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca/**
29d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * \file
30d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * Debug buffer manager to detect buffer under- and overflows.
31d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca *
32e06474dbae6979177629fb6187331291ff230c65José Fonseca * \author Jose Fonseca <jrfonseca@tungstengraphics.com>
33d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca */
34d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
35d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
36d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#include "pipe/p_compiler.h"
37ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h"
382aaca1df9df6980ec88180c8866c8987b31db91aJosé Fonseca#include "os/os_thread.h"
396fd2feaad7029a2f6d02bcf7039cbe72f53c615cBrian#include "util/u_math.h"
404f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
41d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#include "util/u_double_list.h"
42d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#include "util/u_time.h"
431248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#include "util/u_debug_stack.h"
44d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
45d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#include "pb_buffer.h"
46d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#include "pb_bufmgr.h"
47d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
48d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
49d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#ifdef DEBUG
50d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
51d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
521248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#define PB_DEBUG_CREATE_BACKTRACE 8
531248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#define PB_DEBUG_MAP_BACKTRACE 8
541248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
551248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
56d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca/**
57d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * Convenience macro (type safe).
58d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca */
59d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#define SUPER(__derived) (&(__derived)->base)
60d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
61d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
62d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_debug_manager;
63d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
64d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
65d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca/**
66d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * Wrapper around a pipe buffer which adds delayed destruction.
67d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca */
68d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_debug_buffer
69d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
70d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_buffer base;
71d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
72d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_buffer *buffer;
73d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_manager *mgr;
74d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
752af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size underflow_size;
762af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size overflow_size;
771248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
781248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct debug_stack_frame create_backtrace[PB_DEBUG_CREATE_BACKTRACE];
791248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
801248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex mutex;
811248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   unsigned map_count;
821248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct debug_stack_frame map_backtrace[PB_DEBUG_MAP_BACKTRACE];
831248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
841248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct list_head head;
85d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca};
86d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
87d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
88d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_debug_manager
89d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
90d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_manager base;
91d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
92d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_manager *provider;
93d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
942af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size underflow_size;
952af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size overflow_size;
961248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
971248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex mutex;
981248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct list_head list;
99d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca};
100d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
101d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
102d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic INLINE struct pb_debug_buffer *
103d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer(struct pb_buffer *buf)
104d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
105d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   assert(buf);
106d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return (struct pb_debug_buffer *)buf;
107d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
108d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
109d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
110d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic INLINE struct pb_debug_manager *
111d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_manager(struct pb_manager *mgr)
112d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
113d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   assert(mgr);
114d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return (struct pb_debug_manager *)mgr;
115d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
116d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
117d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
118d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic const uint8_t random_pattern[32] = {
119d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   0xaf, 0xcf, 0xa5, 0xa2, 0xc2, 0x63, 0x15, 0x1a,
120d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   0x7e, 0xe2, 0x7e, 0x84, 0x15, 0x49, 0xa2, 0x1e,
121d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   0x49, 0x63, 0xf5, 0x52, 0x74, 0x66, 0x9e, 0xc4,
122d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   0x6d, 0xcf, 0x2c, 0x4a, 0x74, 0xe6, 0xfd, 0x94
123d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca};
124d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
125d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
126d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic INLINE void
1272af0173e9e4eefe910c6011038e7346091a9b2a4José Fonsecafill_random_pattern(uint8_t *dst, pb_size size)
128d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
1292af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size i = 0;
130d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   while(size--) {
131d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      *dst++ = random_pattern[i++];
132d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      i &= sizeof(random_pattern) - 1;
133d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   }
134d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
135d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
136d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
137d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic INLINE boolean
1382af0173e9e4eefe910c6011038e7346091a9b2a4José Fonsecacheck_random_pattern(const uint8_t *dst, pb_size size,
1392af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                     pb_size *min_ofs, pb_size *max_ofs)
140d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
1412170ec9048eab751828700728c1cc8264c860229José Fonseca   boolean result = TRUE;
1422af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size i;
1432170ec9048eab751828700728c1cc8264c860229José Fonseca   *min_ofs = size;
1442170ec9048eab751828700728c1cc8264c860229José Fonseca   *max_ofs = 0;
1452170ec9048eab751828700728c1cc8264c860229José Fonseca   for(i = 0; i < size; ++i) {
1462170ec9048eab751828700728c1cc8264c860229José Fonseca      if(*dst++ != random_pattern[i % sizeof(random_pattern)]) {
1472170ec9048eab751828700728c1cc8264c860229José Fonseca         *min_ofs = MIN2(*min_ofs, i);
148c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca         *max_ofs = MAX2(*max_ofs, i);
1492170ec9048eab751828700728c1cc8264c860229José Fonseca	 result = FALSE;
1502170ec9048eab751828700728c1cc8264c860229José Fonseca      }
151d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   }
1522170ec9048eab751828700728c1cc8264c860229José Fonseca   return result;
153d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
154d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
155d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
156d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void
157c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecapb_debug_buffer_fill(struct pb_debug_buffer *buf)
158d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
159d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   uint8_t *map;
160d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
16167763488b1fea01d6eb1c7d9e05ecb175918c3afJosé Fonseca   map = pb_map(buf->buffer, PB_USAGE_CPU_WRITE, NULL);
162c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   assert(map);
163c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   if(map) {
164c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      fill_random_pattern(map, buf->underflow_size);
1654682e706012fe26627a2f827db01b5068cc62814Marek Olšák      fill_random_pattern(map + buf->underflow_size + buf->base.size,
166c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca                          buf->overflow_size);
167c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      pb_unmap(buf->buffer);
168c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   }
169c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca}
170c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
171c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
172c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca/**
173c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca * Check for under/over flows.
174c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca *
175c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca * Should be called with the buffer unmaped.
176c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca */
177c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecastatic void
178c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecapb_debug_buffer_check(struct pb_debug_buffer *buf)
179c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca{
180c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   uint8_t *map;
181d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
182935929595c31ded8827f081150d1024ff2909d6bJosé Fonseca   map = pb_map(buf->buffer,
183287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                PB_USAGE_CPU_READ |
184b5fcf0c8e07e666523b007fab1d0fc18c2c89241Dave Airlie                PB_USAGE_UNSYNCHRONIZED, NULL);
185d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   assert(map);
186d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   if(map) {
1872170ec9048eab751828700728c1cc8264c860229José Fonseca      boolean underflow, overflow;
1882af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca      pb_size min_ofs, max_ofs;
1892170ec9048eab751828700728c1cc8264c860229José Fonseca
1902170ec9048eab751828700728c1cc8264c860229José Fonseca      underflow = !check_random_pattern(map, buf->underflow_size,
1912170ec9048eab751828700728c1cc8264c860229José Fonseca                                        &min_ofs, &max_ofs);
1922170ec9048eab751828700728c1cc8264c860229José Fonseca      if(underflow) {
193c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca         debug_printf("buffer underflow (offset -%u%s to -%u bytes) detected\n",
194c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca                      buf->underflow_size - min_ofs,
195c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca                      min_ofs == 0 ? "+" : "",
196c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca                      buf->underflow_size - max_ofs);
197d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      }
1982170ec9048eab751828700728c1cc8264c860229José Fonseca
1994682e706012fe26627a2f827db01b5068cc62814Marek Olšák      overflow = !check_random_pattern(map + buf->underflow_size + buf->base.size,
2002170ec9048eab751828700728c1cc8264c860229José Fonseca                                       buf->overflow_size,
2012170ec9048eab751828700728c1cc8264c860229José Fonseca                                       &min_ofs, &max_ofs);
2022170ec9048eab751828700728c1cc8264c860229José Fonseca      if(overflow) {
203c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca         debug_printf("buffer overflow (size %u plus offset %u to %u%s bytes) detected\n",
2044682e706012fe26627a2f827db01b5068cc62814Marek Olšák                      buf->base.size,
205c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca                      min_ofs,
2062170ec9048eab751828700728c1cc8264c860229José Fonseca                      max_ofs,
207c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca                      max_ofs == buf->overflow_size - 1 ? "+" : "");
208d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      }
2092170ec9048eab751828700728c1cc8264c860229José Fonseca
2101248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      if(underflow || overflow)
2111248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca         debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
2121248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
213168a3b8627861fbb2786839f7e276de82f883e42Brian Paul      debug_assert(!underflow);
214168a3b8627861fbb2786839f7e276de82f883e42Brian Paul      debug_assert(!overflow);
215c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
216c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      /* re-fill if not aborted */
217c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      if(underflow)
218c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca         fill_random_pattern(map, buf->underflow_size);
219c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      if(overflow)
2204682e706012fe26627a2f827db01b5068cc62814Marek Olšák         fill_random_pattern(map + buf->underflow_size + buf->base.size,
221c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca                             buf->overflow_size);
222c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
223d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_unmap(buf->buffer);
224d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   }
225c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca}
226c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
227c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
228c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecastatic void
229c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecapb_debug_buffer_destroy(struct pb_buffer *_buf)
230c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca{
2315e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
2321248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct pb_debug_manager *mgr = buf->mgr;
233c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
2344682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(!pipe_is_referenced(&buf->base.reference));
235c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
236c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   pb_debug_buffer_check(buf);
237d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
2381248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(mgr->mutex);
2391248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   LIST_DEL(&buf->head);
2401248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(mgr->mutex);
2411248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
2421248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_destroy(buf->mutex);
2431248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
244d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   pb_reference(&buf->buffer, NULL);
245d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   FREE(buf);
246d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
247d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
248d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
249d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void *
250d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer_map(struct pb_buffer *_buf,
251b5fcf0c8e07e666523b007fab1d0fc18c2c89241Dave Airlie                    unsigned flags, void *flush_ctx)
252d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
253d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
254c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   void *map;
255c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
256c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   pb_debug_buffer_check(buf);
257c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
258b5fcf0c8e07e666523b007fab1d0fc18c2c89241Dave Airlie   map = pb_map(buf->buffer, flags, flush_ctx);
259d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   if(!map)
260d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
261c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
2621248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   if(map) {
2631248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      pipe_mutex_lock(buf->mutex);
2641248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      ++buf->map_count;
2651248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_backtrace_capture(buf->map_backtrace, 1, PB_DEBUG_MAP_BACKTRACE);
2661248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      pipe_mutex_unlock(buf->mutex);
2671248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   }
2681248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
269d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return (uint8_t *)map + buf->underflow_size;
270d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
271d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
272d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
273d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void
274d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer_unmap(struct pb_buffer *_buf)
275d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
276d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
2771248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
2781248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(buf->mutex);
2791248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   assert(buf->map_count);
2801248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   if(buf->map_count)
2811248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      --buf->map_count;
2821248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(buf->mutex);
2831248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
284d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   pb_unmap(buf->buffer);
285c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
286c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   pb_debug_buffer_check(buf);
287d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
288d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
289d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
290d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void
291d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer_get_base_buffer(struct pb_buffer *_buf,
292d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca                                struct pb_buffer **base_buf,
2932af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                                pb_size *offset)
294d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
295d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
296d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   pb_get_base_buffer(buf->buffer, base_buf, offset);
297d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   *offset += buf->underflow_size;
298d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
299d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
300d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
301e06474dbae6979177629fb6187331291ff230c65José Fonsecastatic enum pipe_error
302e06474dbae6979177629fb6187331291ff230c65José Fonsecapb_debug_buffer_validate(struct pb_buffer *_buf,
303e06474dbae6979177629fb6187331291ff230c65José Fonseca                         struct pb_validate *vl,
304e06474dbae6979177629fb6187331291ff230c65José Fonseca                         unsigned flags)
305e06474dbae6979177629fb6187331291ff230c65José Fonseca{
306e06474dbae6979177629fb6187331291ff230c65José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
307e06474dbae6979177629fb6187331291ff230c65José Fonseca
3081248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(buf->mutex);
3091248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   if(buf->map_count) {
3101248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_printf("%s: attempting to validate a mapped buffer\n", __FUNCTION__);
3111248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_printf("last map backtrace is\n");
3121248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_backtrace_dump(buf->map_backtrace, PB_DEBUG_MAP_BACKTRACE);
3131248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   }
3141248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(buf->mutex);
3151248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
316e06474dbae6979177629fb6187331291ff230c65José Fonseca   pb_debug_buffer_check(buf);
317e06474dbae6979177629fb6187331291ff230c65José Fonseca
318e06474dbae6979177629fb6187331291ff230c65José Fonseca   return pb_validate(buf->buffer, vl, flags);
319e06474dbae6979177629fb6187331291ff230c65José Fonseca}
320e06474dbae6979177629fb6187331291ff230c65José Fonseca
321e06474dbae6979177629fb6187331291ff230c65José Fonseca
322e06474dbae6979177629fb6187331291ff230c65José Fonsecastatic void
323e06474dbae6979177629fb6187331291ff230c65José Fonsecapb_debug_buffer_fence(struct pb_buffer *_buf,
324e06474dbae6979177629fb6187331291ff230c65José Fonseca                      struct pipe_fence_handle *fence)
325e06474dbae6979177629fb6187331291ff230c65José Fonseca{
326e06474dbae6979177629fb6187331291ff230c65José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
327e06474dbae6979177629fb6187331291ff230c65José Fonseca   pb_fence(buf->buffer, fence);
328e06474dbae6979177629fb6187331291ff230c65José Fonseca}
329e06474dbae6979177629fb6187331291ff230c65José Fonseca
330e06474dbae6979177629fb6187331291ff230c65José Fonseca
331d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecaconst struct pb_vtbl
332d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer_vtbl = {
333d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_debug_buffer_destroy,
334d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_debug_buffer_map,
335d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_debug_buffer_unmap,
336e06474dbae6979177629fb6187331291ff230c65José Fonseca      pb_debug_buffer_validate,
337e06474dbae6979177629fb6187331291ff230c65José Fonseca      pb_debug_buffer_fence,
338d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_debug_buffer_get_base_buffer
339d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca};
340d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
341d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
3421248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonsecastatic void
343037e7a68f504f019b409ec8cb92f0075019a90f5Thomas Hellstrompb_debug_manager_dump_locked(struct pb_debug_manager *mgr)
3441248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca{
3451248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct list_head *curr, *next;
3461248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct pb_debug_buffer *buf;
3471248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3481248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   curr = mgr->list.next;
3491248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   next = curr->next;
3501248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   while(curr != &mgr->list) {
3511248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      buf = LIST_ENTRY(struct pb_debug_buffer, curr, head);
3521248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3534b1241bf76c7f7ed6d1088a266e9ac000b1f5a54Brian Paul      debug_printf("buffer = %p\n", (void *) buf);
3544682e706012fe26627a2f827db01b5068cc62814Marek Olšák      debug_printf("    .size = 0x%x\n", buf->base.size);
3551248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
3561248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3571248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      curr = next;
3581248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      next = curr->next;
3591248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   }
3601248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3611248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca}
3621248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3631248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
364d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic struct pb_buffer *
365d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_manager_create_buffer(struct pb_manager *_mgr,
3662af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                               pb_size size,
367d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca                               const struct pb_desc *desc)
368d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
369d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
370d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_buffer *buf;
371d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_desc real_desc;
3722af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size real_size;
373d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
374bcadde2068563b818a280e40e6189191e10fd371José Fonseca   assert(size);
375bcadde2068563b818a280e40e6189191e10fd371José Fonseca   assert(desc->alignment);
376bcadde2068563b818a280e40e6189191e10fd371José Fonseca
377d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   buf = CALLOC_STRUCT(pb_debug_buffer);
378d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   if(!buf)
379d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
380d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
3810be216c526c29726a73a26a37dcd5a00cfbefc86José Fonseca   real_size = mgr->underflow_size + size + mgr->overflow_size;
382d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   real_desc = *desc;
383287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   real_desc.usage |= PB_USAGE_CPU_WRITE;
384287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   real_desc.usage |= PB_USAGE_CPU_READ;
385d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
386d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   buf->buffer = mgr->provider->create_buffer(mgr->provider,
387d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca                                              real_size,
388d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca                                              &real_desc);
389d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   if(!buf->buffer) {
390d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      FREE(buf);
3911248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#if 0
3921248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      pipe_mutex_lock(mgr->mutex);
3931248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_printf("%s: failed to create buffer\n", __FUNCTION__);
3941248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      if(!LIST_IS_EMPTY(&mgr->list))
395037e7a68f504f019b409ec8cb92f0075019a90f5Thomas Hellstrom         pb_debug_manager_dump_locked(mgr);
3961248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      pipe_mutex_unlock(mgr->mutex);
3971248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#endif
398d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
399d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   }
400d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4014682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(pipe_is_referenced(&buf->buffer->reference));
4024682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(pb_check_alignment(real_desc.alignment, buf->buffer->alignment));
4034682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(pb_check_usage(real_desc.usage, buf->buffer->usage));
4044682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(buf->buffer->size >= real_size);
405d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4064682e706012fe26627a2f827db01b5068cc62814Marek Olšák   pipe_reference_init(&buf->base.reference, 1);
4074682e706012fe26627a2f827db01b5068cc62814Marek Olšák   buf->base.alignment = desc->alignment;
4084682e706012fe26627a2f827db01b5068cc62814Marek Olšák   buf->base.usage = desc->usage;
4094682e706012fe26627a2f827db01b5068cc62814Marek Olšák   buf->base.size = size;
410d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
411d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   buf->base.vtbl = &pb_debug_buffer_vtbl;
412d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   buf->mgr = mgr;
413d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4140be216c526c29726a73a26a37dcd5a00cfbefc86José Fonseca   buf->underflow_size = mgr->underflow_size;
4154682e706012fe26627a2f827db01b5068cc62814Marek Olšák   buf->overflow_size = buf->buffer->size - buf->underflow_size - size;
416d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4171248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   debug_backtrace_capture(buf->create_backtrace, 1, PB_DEBUG_CREATE_BACKTRACE);
4181248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
419c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   pb_debug_buffer_fill(buf);
420d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4211248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_init(buf->mutex);
4221248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
4231248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(mgr->mutex);
4241248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   LIST_ADDTAIL(&buf->head, &mgr->list);
4251248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(mgr->mutex);
4261248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
427d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return &buf->base;
428d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
429d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
430d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
431d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void
4321672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonsecapb_debug_manager_flush(struct pb_manager *_mgr)
4331672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca{
4341672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
4351672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca   assert(mgr->provider->flush);
4361672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca   if(mgr->provider->flush)
4371672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca      mgr->provider->flush(mgr->provider);
4381672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca}
4391672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca
4401672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca
4411672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonsecastatic void
442d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_manager_destroy(struct pb_manager *_mgr)
443d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
444d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
4451248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
4461248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(mgr->mutex);
4471248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   if(!LIST_IS_EMPTY(&mgr->list)) {
4481248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_printf("%s: unfreed buffers\n", __FUNCTION__);
449037e7a68f504f019b409ec8cb92f0075019a90f5Thomas Hellstrom      pb_debug_manager_dump_locked(mgr);
4501248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   }
4511248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(mgr->mutex);
4521248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
4531248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_destroy(mgr->mutex);
454d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr->provider->destroy(mgr->provider);
455d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   FREE(mgr);
456d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
457d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
458d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
459d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_manager *
4600be216c526c29726a73a26a37dcd5a00cfbefc86José Fonsecapb_debug_manager_create(struct pb_manager *provider,
4612af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                        pb_size underflow_size, pb_size overflow_size)
462d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
463d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_manager *mgr;
464d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
465d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   if(!provider)
466d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
467d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
468d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr = CALLOC_STRUCT(pb_debug_manager);
469d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   if (!mgr)
470d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
471d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
472d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr->base.destroy = pb_debug_manager_destroy;
473d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr->base.create_buffer = pb_debug_manager_create_buffer;
4741672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca   mgr->base.flush = pb_debug_manager_flush;
475d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr->provider = provider;
4760be216c526c29726a73a26a37dcd5a00cfbefc86José Fonseca   mgr->underflow_size = underflow_size;
4770be216c526c29726a73a26a37dcd5a00cfbefc86José Fonseca   mgr->overflow_size = overflow_size;
4781248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
4791248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_init(mgr->mutex);
4801248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   LIST_INITHEAD(&mgr->list);
4811248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
482d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return &mgr->base;
483d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
484d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
485d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
486d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#else /* !DEBUG */
487d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
488d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
489d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_manager *
4900be216c526c29726a73a26a37dcd5a00cfbefc86José Fonsecapb_debug_manager_create(struct pb_manager *provider,
4912af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                        pb_size underflow_size, pb_size overflow_size)
492d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
493d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return provider;
494d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
495d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
496d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
497d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#endif /* !DEBUG */
498