1d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca/**************************************************************************
2d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca *
3877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2007-2008 VMware, Inc.
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.
21877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * IN NO EVENT SHALL VMWARE 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 *
32877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * \author Jose Fonseca <jfonseca@vmware.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 Paul#include "util/u_math.h"
404f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
417a30668ad665f3315106e1a959c6186dea79a24aJason Ekstrand#include "util/list.h"
42d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#include "util/u_time.h"
431248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#include "util/u_debug_stack.h"
447e78b5ed38e289ddb6397a211361b6e3be4bf9abMarek Olšák#include <inttypes.h>
45d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
46d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#include "pb_buffer.h"
47d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#include "pb_bufmgr.h"
48d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
49d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
50d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#ifdef DEBUG
51d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
52d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
531248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#define PB_DEBUG_CREATE_BACKTRACE 8
541248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#define PB_DEBUG_MAP_BACKTRACE 8
551248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
561248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
57d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca/**
58d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * Convenience macro (type safe).
59d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca */
60d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#define SUPER(__derived) (&(__derived)->base)
61d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
62d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
63d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_debug_manager;
64d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
65d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
66d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca/**
67d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca * Wrapper around a pipe buffer which adds delayed destruction.
68d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca */
69d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_debug_buffer
70d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
71d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_buffer base;
72d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
73d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_buffer *buffer;
74d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_manager *mgr;
75d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
762af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size underflow_size;
772af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size overflow_size;
781248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
791248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct debug_stack_frame create_backtrace[PB_DEBUG_CREATE_BACKTRACE];
801248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
811248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex mutex;
821248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   unsigned map_count;
831248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct debug_stack_frame map_backtrace[PB_DEBUG_MAP_BACKTRACE];
841248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
851248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct list_head head;
86d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca};
87d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
88d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
89d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_debug_manager
90d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
91d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_manager base;
92d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
93d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_manager *provider;
94d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
952af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size underflow_size;
962af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size overflow_size;
971248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
981248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex mutex;
991248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct list_head list;
100d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca};
101d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
102d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
103a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline struct pb_debug_buffer *
104d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer(struct pb_buffer *buf)
105d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
106d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   assert(buf);
107d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return (struct pb_debug_buffer *)buf;
108d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
109d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
110d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
111a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline struct pb_debug_manager *
112d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_manager(struct pb_manager *mgr)
113d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
114d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   assert(mgr);
115d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return (struct pb_debug_manager *)mgr;
116d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
117d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
118d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
119d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic const uint8_t random_pattern[32] = {
120d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   0xaf, 0xcf, 0xa5, 0xa2, 0xc2, 0x63, 0x15, 0x1a,
121d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   0x7e, 0xe2, 0x7e, 0x84, 0x15, 0x49, 0xa2, 0x1e,
122d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   0x49, 0x63, 0xf5, 0x52, 0x74, 0x66, 0x9e, 0xc4,
123d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   0x6d, 0xcf, 0x2c, 0x4a, 0x74, 0xe6, 0xfd, 0x94
124d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca};
125d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
126d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
127a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
1282af0173e9e4eefe910c6011038e7346091a9b2a4José Fonsecafill_random_pattern(uint8_t *dst, pb_size size)
129d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
1302af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size i = 0;
131d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   while(size--) {
132d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      *dst++ = random_pattern[i++];
133d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      i &= sizeof(random_pattern) - 1;
134d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   }
135d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
136d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
137d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
138a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline boolean
1392af0173e9e4eefe910c6011038e7346091a9b2a4José Fonsecacheck_random_pattern(const uint8_t *dst, pb_size size,
1402af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                     pb_size *min_ofs, pb_size *max_ofs)
141d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
1422170ec9048eab751828700728c1cc8264c860229José Fonseca   boolean result = TRUE;
1432af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size i;
1442170ec9048eab751828700728c1cc8264c860229José Fonseca   *min_ofs = size;
1452170ec9048eab751828700728c1cc8264c860229José Fonseca   *max_ofs = 0;
1462170ec9048eab751828700728c1cc8264c860229José Fonseca   for(i = 0; i < size; ++i) {
1472170ec9048eab751828700728c1cc8264c860229José Fonseca      if(*dst++ != random_pattern[i % sizeof(random_pattern)]) {
1482170ec9048eab751828700728c1cc8264c860229José Fonseca         *min_ofs = MIN2(*min_ofs, i);
149c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca         *max_ofs = MAX2(*max_ofs, i);
1502170ec9048eab751828700728c1cc8264c860229José Fonseca	 result = FALSE;
1512170ec9048eab751828700728c1cc8264c860229José Fonseca      }
152d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   }
1532170ec9048eab751828700728c1cc8264c860229José Fonseca   return result;
154d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
155d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
156d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
157d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void
158c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecapb_debug_buffer_fill(struct pb_debug_buffer *buf)
159d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
160d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   uint8_t *map;
161d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
16267763488b1fea01d6eb1c7d9e05ecb175918c3afJosé Fonseca   map = pb_map(buf->buffer, PB_USAGE_CPU_WRITE, NULL);
163c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   assert(map);
164147fd00bb36917f8463aacd49a26e95ca0926255Edward O'Callaghan   if (map) {
165c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      fill_random_pattern(map, buf->underflow_size);
1664682e706012fe26627a2f827db01b5068cc62814Marek Olšák      fill_random_pattern(map + buf->underflow_size + buf->base.size,
167c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca                          buf->overflow_size);
168c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      pb_unmap(buf->buffer);
169c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   }
170c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca}
171c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
172c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
173c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca/**
174c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca * Check for under/over flows.
175c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca *
176c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca * Should be called with the buffer unmaped.
177c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca */
178c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecastatic void
179c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecapb_debug_buffer_check(struct pb_debug_buffer *buf)
180c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca{
181c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   uint8_t *map;
182d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
183935929595c31ded8827f081150d1024ff2909d6bJosé Fonseca   map = pb_map(buf->buffer,
184287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                PB_USAGE_CPU_READ |
185b5fcf0c8e07e666523b007fab1d0fc18c2c89241Dave Airlie                PB_USAGE_UNSYNCHRONIZED, NULL);
186d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   assert(map);
187147fd00bb36917f8463aacd49a26e95ca0926255Edward O'Callaghan   if (map) {
1882170ec9048eab751828700728c1cc8264c860229José Fonseca      boolean underflow, overflow;
1892af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca      pb_size min_ofs, max_ofs;
1902170ec9048eab751828700728c1cc8264c860229José Fonseca
1912170ec9048eab751828700728c1cc8264c860229José Fonseca      underflow = !check_random_pattern(map, buf->underflow_size,
1922170ec9048eab751828700728c1cc8264c860229José Fonseca                                        &min_ofs, &max_ofs);
1932170ec9048eab751828700728c1cc8264c860229José Fonseca      if(underflow) {
1947e78b5ed38e289ddb6397a211361b6e3be4bf9abMarek Olšák         debug_printf("buffer underflow (offset -%"PRIu64"%s to -%"PRIu64" bytes) detected\n",
195c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca                      buf->underflow_size - min_ofs,
196c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca                      min_ofs == 0 ? "+" : "",
197c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca                      buf->underflow_size - max_ofs);
198d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      }
1992170ec9048eab751828700728c1cc8264c860229José Fonseca
2004682e706012fe26627a2f827db01b5068cc62814Marek Olšák      overflow = !check_random_pattern(map + buf->underflow_size + buf->base.size,
2012170ec9048eab751828700728c1cc8264c860229José Fonseca                                       buf->overflow_size,
2022170ec9048eab751828700728c1cc8264c860229José Fonseca                                       &min_ofs, &max_ofs);
2032170ec9048eab751828700728c1cc8264c860229José Fonseca      if(overflow) {
2047e78b5ed38e289ddb6397a211361b6e3be4bf9abMarek Olšák         debug_printf("buffer overflow (size %"PRIu64" plus offset %"PRIu64" to %"PRIu64"%s bytes) detected\n",
2054682e706012fe26627a2f827db01b5068cc62814Marek Olšák                      buf->base.size,
206c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca                      min_ofs,
2072170ec9048eab751828700728c1cc8264c860229José Fonseca                      max_ofs,
208c46c07f6c60edb60514756bd6af7918f70931e53José Fonseca                      max_ofs == buf->overflow_size - 1 ? "+" : "");
209d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      }
2102170ec9048eab751828700728c1cc8264c860229José Fonseca
2111248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      if(underflow || overflow)
2121248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca         debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
2131248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
214168a3b8627861fbb2786839f7e276de82f883e42Brian Paul      debug_assert(!underflow);
215168a3b8627861fbb2786839f7e276de82f883e42Brian Paul      debug_assert(!overflow);
216c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
217c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      /* re-fill if not aborted */
218c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      if(underflow)
219c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca         fill_random_pattern(map, buf->underflow_size);
220c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca      if(overflow)
2214682e706012fe26627a2f827db01b5068cc62814Marek Olšák         fill_random_pattern(map + buf->underflow_size + buf->base.size,
222c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca                             buf->overflow_size);
223c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
224d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_unmap(buf->buffer);
225d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   }
226c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca}
227c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
228c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
229c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecastatic void
230c6739e8cea287e17b248120e1a76480f1a25c082José Fonsecapb_debug_buffer_destroy(struct pb_buffer *_buf)
231c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca{
2325e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
2331248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct pb_debug_manager *mgr = buf->mgr;
234c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
2354682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(!pipe_is_referenced(&buf->base.reference));
236c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
237c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   pb_debug_buffer_check(buf);
238d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
2391248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(mgr->mutex);
2401248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   LIST_DEL(&buf->head);
2411248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(mgr->mutex);
2421248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
2431248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_destroy(buf->mutex);
2441248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
245d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   pb_reference(&buf->buffer, NULL);
246d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   FREE(buf);
247d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
248d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
249d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
250d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void *
251d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer_map(struct pb_buffer *_buf,
252b5fcf0c8e07e666523b007fab1d0fc18c2c89241Dave Airlie                    unsigned flags, void *flush_ctx)
253d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
254d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
255c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   void *map;
256c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
257c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   pb_debug_buffer_check(buf);
258c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
259b5fcf0c8e07e666523b007fab1d0fc18c2c89241Dave Airlie   map = pb_map(buf->buffer, flags, flush_ctx);
260147fd00bb36917f8463aacd49a26e95ca0926255Edward O'Callaghan   if (!map)
261d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
262c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
263d108b69d2cd4c54cc5eaa9ef5d75604d57b5187fEdward O'Callaghan   pipe_mutex_lock(buf->mutex);
264d108b69d2cd4c54cc5eaa9ef5d75604d57b5187fEdward O'Callaghan   ++buf->map_count;
265d108b69d2cd4c54cc5eaa9ef5d75604d57b5187fEdward O'Callaghan   debug_backtrace_capture(buf->map_backtrace, 1, PB_DEBUG_MAP_BACKTRACE);
266d108b69d2cd4c54cc5eaa9ef5d75604d57b5187fEdward O'Callaghan   pipe_mutex_unlock(buf->mutex);
2671248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
268d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return (uint8_t *)map + buf->underflow_size;
269d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
270d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
271d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
272d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void
273d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer_unmap(struct pb_buffer *_buf)
274d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
275d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
2761248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
2771248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(buf->mutex);
2781248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   assert(buf->map_count);
2791248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   if(buf->map_count)
2801248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      --buf->map_count;
2811248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(buf->mutex);
2821248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
283d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   pb_unmap(buf->buffer);
284c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca
285c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   pb_debug_buffer_check(buf);
286d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
287d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
288d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
289d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void
290d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer_get_base_buffer(struct pb_buffer *_buf,
291d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca                                struct pb_buffer **base_buf,
2922af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                                pb_size *offset)
293d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
294d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
295d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   pb_get_base_buffer(buf->buffer, base_buf, offset);
296d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   *offset += buf->underflow_size;
297d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
298d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
299d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
300e06474dbae6979177629fb6187331291ff230c65José Fonsecastatic enum pipe_error
301e06474dbae6979177629fb6187331291ff230c65José Fonsecapb_debug_buffer_validate(struct pb_buffer *_buf,
302e06474dbae6979177629fb6187331291ff230c65José Fonseca                         struct pb_validate *vl,
303e06474dbae6979177629fb6187331291ff230c65José Fonseca                         unsigned flags)
304e06474dbae6979177629fb6187331291ff230c65José Fonseca{
305e06474dbae6979177629fb6187331291ff230c65José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
306e06474dbae6979177629fb6187331291ff230c65José Fonseca
3071248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(buf->mutex);
3081248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   if(buf->map_count) {
3091248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_printf("%s: attempting to validate a mapped buffer\n", __FUNCTION__);
3101248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_printf("last map backtrace is\n");
3111248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_backtrace_dump(buf->map_backtrace, PB_DEBUG_MAP_BACKTRACE);
3121248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   }
3131248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(buf->mutex);
3141248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
315e06474dbae6979177629fb6187331291ff230c65José Fonseca   pb_debug_buffer_check(buf);
316e06474dbae6979177629fb6187331291ff230c65José Fonseca
317e06474dbae6979177629fb6187331291ff230c65José Fonseca   return pb_validate(buf->buffer, vl, flags);
318e06474dbae6979177629fb6187331291ff230c65José Fonseca}
319e06474dbae6979177629fb6187331291ff230c65José Fonseca
320e06474dbae6979177629fb6187331291ff230c65José Fonseca
321e06474dbae6979177629fb6187331291ff230c65José Fonsecastatic void
322e06474dbae6979177629fb6187331291ff230c65José Fonsecapb_debug_buffer_fence(struct pb_buffer *_buf,
323e06474dbae6979177629fb6187331291ff230c65José Fonseca                      struct pipe_fence_handle *fence)
324e06474dbae6979177629fb6187331291ff230c65José Fonseca{
325e06474dbae6979177629fb6187331291ff230c65José Fonseca   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
326e06474dbae6979177629fb6187331291ff230c65José Fonseca   pb_fence(buf->buffer, fence);
327e06474dbae6979177629fb6187331291ff230c65José Fonseca}
328e06474dbae6979177629fb6187331291ff230c65José Fonseca
329e06474dbae6979177629fb6187331291ff230c65José Fonseca
330d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecaconst struct pb_vtbl
331d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_buffer_vtbl = {
332d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_debug_buffer_destroy,
333d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_debug_buffer_map,
334d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_debug_buffer_unmap,
335e06474dbae6979177629fb6187331291ff230c65José Fonseca      pb_debug_buffer_validate,
336e06474dbae6979177629fb6187331291ff230c65José Fonseca      pb_debug_buffer_fence,
337d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      pb_debug_buffer_get_base_buffer
338d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca};
339d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
340d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
3411248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonsecastatic void
342037e7a68f504f019b409ec8cb92f0075019a90f5Thomas Hellstrompb_debug_manager_dump_locked(struct pb_debug_manager *mgr)
3431248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca{
3441248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct list_head *curr, *next;
3451248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   struct pb_debug_buffer *buf;
3461248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3471248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   curr = mgr->list.next;
3481248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   next = curr->next;
3491248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   while(curr != &mgr->list) {
3501248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      buf = LIST_ENTRY(struct pb_debug_buffer, curr, head);
3511248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3524b1241bf76c7f7ed6d1088a266e9ac000b1f5a54Brian Paul      debug_printf("buffer = %p\n", (void *) buf);
3537e78b5ed38e289ddb6397a211361b6e3be4bf9abMarek Olšák      debug_printf("    .size = 0x%"PRIx64"\n", buf->base.size);
3541248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
3551248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3561248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      curr = next;
3571248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      next = curr->next;
3581248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   }
3591248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3601248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca}
3611248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
3621248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
363d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic struct pb_buffer *
364d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_manager_create_buffer(struct pb_manager *_mgr,
3652af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                               pb_size size,
366d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca                               const struct pb_desc *desc)
367d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
368d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
369d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_buffer *buf;
370d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_desc real_desc;
3712af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca   pb_size real_size;
372d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
373bcadde2068563b818a280e40e6189191e10fd371José Fonseca   assert(size);
374bcadde2068563b818a280e40e6189191e10fd371José Fonseca   assert(desc->alignment);
375bcadde2068563b818a280e40e6189191e10fd371José Fonseca
376d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   buf = CALLOC_STRUCT(pb_debug_buffer);
377147fd00bb36917f8463aacd49a26e95ca0926255Edward O'Callaghan   if (!buf)
378d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
379d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
3800be216c526c29726a73a26a37dcd5a00cfbefc86José Fonseca   real_size = mgr->underflow_size + size + mgr->overflow_size;
381d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   real_desc = *desc;
382287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   real_desc.usage |= PB_USAGE_CPU_WRITE;
383287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   real_desc.usage |= PB_USAGE_CPU_READ;
384d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
385d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   buf->buffer = mgr->provider->create_buffer(mgr->provider,
386d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca                                              real_size,
387d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca                                              &real_desc);
388d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   if(!buf->buffer) {
389d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      FREE(buf);
3901248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#if 0
3911248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      pipe_mutex_lock(mgr->mutex);
3921248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_printf("%s: failed to create buffer\n", __FUNCTION__);
3931248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      if(!LIST_IS_EMPTY(&mgr->list))
394037e7a68f504f019b409ec8cb92f0075019a90f5Thomas Hellstrom         pb_debug_manager_dump_locked(mgr);
3951248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      pipe_mutex_unlock(mgr->mutex);
3961248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca#endif
397d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
398d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   }
399d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4004682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(pipe_is_referenced(&buf->buffer->reference));
4014682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(pb_check_alignment(real_desc.alignment, buf->buffer->alignment));
4024682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(pb_check_usage(real_desc.usage, buf->buffer->usage));
4034682e706012fe26627a2f827db01b5068cc62814Marek Olšák   assert(buf->buffer->size >= real_size);
404d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4054682e706012fe26627a2f827db01b5068cc62814Marek Olšák   pipe_reference_init(&buf->base.reference, 1);
4064682e706012fe26627a2f827db01b5068cc62814Marek Olšák   buf->base.alignment = desc->alignment;
4074682e706012fe26627a2f827db01b5068cc62814Marek Olšák   buf->base.usage = desc->usage;
4084682e706012fe26627a2f827db01b5068cc62814Marek Olšák   buf->base.size = size;
409d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
410d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   buf->base.vtbl = &pb_debug_buffer_vtbl;
411d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   buf->mgr = mgr;
412d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4130be216c526c29726a73a26a37dcd5a00cfbefc86José Fonseca   buf->underflow_size = mgr->underflow_size;
4144682e706012fe26627a2f827db01b5068cc62814Marek Olšák   buf->overflow_size = buf->buffer->size - buf->underflow_size - size;
415d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4161248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   debug_backtrace_capture(buf->create_backtrace, 1, PB_DEBUG_CREATE_BACKTRACE);
4171248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
418c6739e8cea287e17b248120e1a76480f1a25c082José Fonseca   pb_debug_buffer_fill(buf);
419d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
4201248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_init(buf->mutex);
4211248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
4221248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(mgr->mutex);
4231248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   LIST_ADDTAIL(&buf->head, &mgr->list);
4241248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(mgr->mutex);
4251248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
426d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return &buf->base;
427d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
428d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
429d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
430d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastatic void
4311672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonsecapb_debug_manager_flush(struct pb_manager *_mgr)
4321672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca{
4331672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
4341672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca   assert(mgr->provider->flush);
4351672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca   if(mgr->provider->flush)
4361672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca      mgr->provider->flush(mgr->provider);
4371672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca}
4381672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca
4391672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca
4401672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonsecastatic void
441d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecapb_debug_manager_destroy(struct pb_manager *_mgr)
442d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
443d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
4441248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
4451248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_lock(mgr->mutex);
4461248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   if(!LIST_IS_EMPTY(&mgr->list)) {
4471248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca      debug_printf("%s: unfreed buffers\n", __FUNCTION__);
448037e7a68f504f019b409ec8cb92f0075019a90f5Thomas Hellstrom      pb_debug_manager_dump_locked(mgr);
4491248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   }
4501248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_unlock(mgr->mutex);
4511248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
4521248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_destroy(mgr->mutex);
453d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr->provider->destroy(mgr->provider);
454d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   FREE(mgr);
455d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
456d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
457d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
458d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_manager *
4590be216c526c29726a73a26a37dcd5a00cfbefc86José Fonsecapb_debug_manager_create(struct pb_manager *provider,
4602af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                        pb_size underflow_size, pb_size overflow_size)
461d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
462d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   struct pb_debug_manager *mgr;
463d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
464147fd00bb36917f8463aacd49a26e95ca0926255Edward O'Callaghan   if (!provider)
465d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
466d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
467d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr = CALLOC_STRUCT(pb_debug_manager);
468d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   if (!mgr)
469d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca      return NULL;
470d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
471d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr->base.destroy = pb_debug_manager_destroy;
472d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr->base.create_buffer = pb_debug_manager_create_buffer;
4731672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca   mgr->base.flush = pb_debug_manager_flush;
474d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   mgr->provider = provider;
4750be216c526c29726a73a26a37dcd5a00cfbefc86José Fonseca   mgr->underflow_size = underflow_size;
4760be216c526c29726a73a26a37dcd5a00cfbefc86José Fonseca   mgr->overflow_size = overflow_size;
4771248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
4781248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   pipe_mutex_init(mgr->mutex);
4791248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca   LIST_INITHEAD(&mgr->list);
4801248ff7d45ce4b78af8c7a091cb64f1f992f88ddJosé Fonseca
481d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return &mgr->base;
482d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
483d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
484d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
485d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#else /* !DEBUG */
486d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
487d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
488d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonsecastruct pb_manager *
4890be216c526c29726a73a26a37dcd5a00cfbefc86José Fonsecapb_debug_manager_create(struct pb_manager *provider,
4902af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca                        pb_size underflow_size, pb_size overflow_size)
491d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca{
492d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca   return provider;
493d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca}
494d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
495d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca
496d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422José Fonseca#endif /* !DEBUG */
497