pb_bufmgr_cache.c revision e9d156e9e4f92ae1ce70bd563c251b34d238c4bc
1988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul/************************************************************************** 2988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * 3a99114a69f2b7963ca1f855a320aea8aa56755acBrian * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * All Rights Reserved. 50bf5dbe002a64e198f55724cc1542602c012490fBrian * 6988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 7988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * copy of this software and associated documentation files (the 8988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * "Software"), to deal in the Software without restriction, including 9988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * without limitation the rights to use, copy, modify, merge, publish, 10988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * distribute, sub license, and/or sell copies of the Software, and to 11988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * permit persons to whom the Software is furnished to do so, subject to 12988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * the following conditions: 13988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * 14988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * The above copyright notice and this permission notice (including the 15988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * next paragraph) shall be included in all copies or substantial portions 16988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * of the Software. 17988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * 18988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * 26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul **************************************************************************/ 27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul 28122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul/** 29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul * \file 30bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul * Buffer cache. 31bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul * 32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul * \author Jose Fonseca <jrfonseca-at-tungstengraphics-dot-com> 33bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com> 34bd5ba36bf73fb63e62f779138d5e1ef6fcec6f26Brian Paul */ 35bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul 36a37b2219d6e3f299379c6434d65f300660d12c3eBrian Paul 37bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "pipe/p_compiler.h" 38bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "util/u_debug.h" 39a4bec69e7271eda0137874973aa8c7d44175fedfBrian Paul#include "pipe/p_thread.h" 40bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "util/u_memory.h" 41bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "util/u_double_list.h" 42bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "util/u_time.h" 43bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul 44bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "pb_buffer.h" 451f32c665c8af0622e2bbf451edb999ffbcd7d0feEric Anholt#include "pb_bufmgr.h" 46f37070bab6af350caec905ea7658e9241042b6ccIan Romanick 47867f9b07d42c2b49ddb9e5bb17f0ac5c4a80d8acMarek Olšák 48fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 49988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * Convenience macro (type safe). 50ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul */ 51b5ee368baf6472a79d250f0be418200760f4b43dBrian Paul#define SUPER(__derived) (&(__derived)->base) 52988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 53d0dc75c000d5af92648c7de901756400672b8447Brian Paul 54988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulstruct pb_cache_manager; 55bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul 566f9dbe773953b024075910b3bec11ebc96c2e8e0Brian Paul 57bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul/** 58988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * Wrapper around a pipe buffer which adds delayed destruction. 59988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul */ 60988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulstruct pb_cache_buffer 61988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul{ 62988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct pb_buffer base; 63988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 64988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct pb_buffer *buffer; 65988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct pb_cache_manager *mgr; 66988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 67988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul /** Caching time interval */ 68988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct util_time start, end; 69988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 70988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct list_head head; 71988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul}; 726bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul 73988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 74988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulstruct pb_cache_manager 75988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul{ 76988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct pb_manager base; 77e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 78988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct pb_manager *provider; 79988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul unsigned usecs; 80988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 81988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul pipe_mutex mutex; 82988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 83988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct list_head delayed; 84988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul size_t numDelayed; 85122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul}; 866b146214dc16b441376d8dcaba21bcc4256a2402Keith Whitwell 87988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 88bd5ba36bf73fb63e62f779138d5e1ef6fcec6f26Brian Paulstatic INLINE struct pb_cache_buffer * 89988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulpb_cache_buffer(struct pb_buffer *buf) 90988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul{ 91988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul assert(buf); 92988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul return (struct pb_cache_buffer *)buf; 93988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul} 948f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul 95e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul 96e3dc78e57a7effbd30dc9539b3ea05ad85ac34e5Brian Paulstatic INLINE struct pb_cache_manager * 97cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paulpb_cache_manager(struct pb_manager *mgr) 98e885cb48a0b9292b3df9204f1c2783bf1fe29a28Eric Anholt{ 99988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul assert(mgr); 100e8fdd0e0d5286f4a9c763ffde44decec51124ebcBrian Paul return (struct pb_cache_manager *)mgr; 101ec19bdd16c3d4070af69fd865042babe0a627595Brian Paul} 10268d293b03535ca50daf70650b32db780f1718a3bBrian Paul 103988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 104988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul/** 105988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul * Actually destroy the buffer. 10620177a620ef123ae7cdbc7252fd41a48f5b76accBrian Paul */ 10720177a620ef123ae7cdbc7252fd41a48f5b76accBrian Paulstatic INLINE void 108e6cf338d015e994012535fce5e06c7dc59482b02Brian Paul_pb_cache_buffer_destroy(struct pb_cache_buffer *buf) 109e6cf338d015e994012535fce5e06c7dc59482b02Brian Paul{ 110e10337da21d45ab7cccfa98b4112d1b33f3a5604Brian Paul struct pb_cache_manager *mgr = buf->mgr; 111e10337da21d45ab7cccfa98b4112d1b33f3a5604Brian Paul 112b4dc35d9bc879c104faac043b640ae2673763b93Chia-I Wu LIST_DEL(&buf->head); 113988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul assert(mgr->numDelayed); 1144d859f73fce9918381c65da55f046a7c605c9e65Brian Paul --mgr->numDelayed; 1154d859f73fce9918381c65da55f046a7c605c9e65Brian Paul assert(!pipe_is_referenced(&buf->base.base.reference)); 1164d859f73fce9918381c65da55f046a7c605c9e65Brian Paul pb_reference(&buf->buffer, NULL); 1174d859f73fce9918381c65da55f046a7c605c9e65Brian Paul FREE(buf); 1184d859f73fce9918381c65da55f046a7c605c9e65Brian Paul} 119988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 120988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 121988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul/** 122c93105eb9e2499efb237fd89dba0cebd48f18375Ian Romanick * Free as many cache buffers from the list head as possible. 123988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul */ 124988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulstatic void 125988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul_pb_cache_buffer_list_check_free(struct pb_cache_manager *mgr) 126988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul{ 127988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct list_head *curr, *next; 128acafeeb6dce74382fb3a48b83ab72bf67b7581eaBrian Paul struct pb_cache_buffer *buf; 129acafeeb6dce74382fb3a48b83ab72bf67b7581eaBrian Paul struct util_time now; 130988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 131988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul util_time_get(&now); 132988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 133988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul curr = mgr->delayed.next; 134988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul next = curr->next; 135988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul while(curr != &mgr->delayed) { 136988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 137988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 138988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul if(!util_time_timeout(&buf->start, &buf->end, &now)) 139988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul break; 140988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 141988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul _pb_cache_buffer_destroy(buf); 142988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 143988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul curr = next; 144988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul next = curr->next; 145988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul } 146988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul} 147988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 148988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 149988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulstatic void 150988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulpb_cache_buffer_destroy(struct pb_buffer *_buf) 151878c371e6cf6eb28afacc482d8aeaa0119f00d5bBrian Paul{ 1525179f671e7f9366e278dbff519c283956ba0c2feBrian Paul struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 153878c371e6cf6eb28afacc482d8aeaa0119f00d5bBrian Paul struct pb_cache_manager *mgr = buf->mgr; 154988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 155988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul pipe_mutex_lock(mgr->mutex); 156988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul assert(!pipe_is_referenced(&buf->base.base.reference)); 157988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 158988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul _pb_cache_buffer_list_check_free(mgr); 159a8da1feb231115205f3a19b0bb0a9317157ba167Brian Paul 160331eb58f68db26b54f706a908a3e1424a461b709Brian Paul util_time_get(&buf->start); 161e75b283b45add351dbe5a09289fe85546df8a79aBrian Paul util_time_add(&buf->start, mgr->usecs, &buf->end); 162a8da1feb231115205f3a19b0bb0a9317157ba167Brian Paul LIST_ADDTAIL(&buf->head, &mgr->delayed); 163a8da1feb231115205f3a19b0bb0a9317157ba167Brian Paul ++mgr->numDelayed; 164a8da1feb231115205f3a19b0bb0a9317157ba167Brian Paul pipe_mutex_unlock(mgr->mutex); 165f37070bab6af350caec905ea7658e9241042b6ccIan Romanick} 166f37070bab6af350caec905ea7658e9241042b6ccIan Romanick 1672c6f911e10761c0946261d494bf149b19072821dBrian Paul 168d0dc75c000d5af92648c7de901756400672b8447Brian Paulstatic void * 169d0dc75c000d5af92648c7de901756400672b8447Brian Paulpb_cache_buffer_map(struct pb_buffer *_buf, 170d0dc75c000d5af92648c7de901756400672b8447Brian Paul unsigned flags) 171755f2e2ae597df9208523b0996bbdabf3db463b0Brian Paul{ 172755f2e2ae597df9208523b0996bbdabf3db463b0Brian Paul struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 173e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul return pb_map(buf->buffer, flags); 17462c66b34303303e6786652efa611a100ae64439aBrian Paul} 1752c6f911e10761c0946261d494bf149b19072821dBrian Paul 176afa1df58714c37b056fe9aee77500e900ee9dbf0Brian Paul 177afa1df58714c37b056fe9aee77500e900ee9dbf0Brian Paulstatic void 178867f9b07d42c2b49ddb9e5bb17f0ac5c4a80d8acMarek Olšákpb_cache_buffer_unmap(struct pb_buffer *_buf) 179867f9b07d42c2b49ddb9e5bb17f0ac5c4a80d8acMarek Olšák{ 180ee34e6ef716bb630440299ac1efbc2055ef09ffdIan Romanick struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 181ee34e6ef716bb630440299ac1efbc2055ef09ffdIan Romanick pb_unmap(buf->buffer); 182ee34e6ef716bb630440299ac1efbc2055ef09ffdIan Romanick} 183ee34e6ef716bb630440299ac1efbc2055ef09ffdIan Romanick 184ee34e6ef716bb630440299ac1efbc2055ef09ffdIan Romanick 185a37b2219d6e3f299379c6434d65f300660d12c3eBrian Paulstatic enum pipe_error 186a37b2219d6e3f299379c6434d65f300660d12c3eBrian Paulpb_cache_buffer_validate(struct pb_buffer *_buf, 187fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct pb_validate *vl, 188fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul unsigned flags) 1891f32c665c8af0622e2bbf451edb999ffbcd7d0feEric Anholt{ 1901f32c665c8af0622e2bbf451edb999ffbcd7d0feEric Anholt struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 191988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul return pb_validate(buf->buffer, vl, flags); 192988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul} 193988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 194988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 195988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulstatic void 196988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulpb_cache_buffer_fence(struct pb_buffer *_buf, 197b5ee368baf6472a79d250f0be418200760f4b43dBrian Paul struct pipe_fence_handle *fence) 198988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul{ 199988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 200fd7c46f53f3a7ae5c67f3c44ba283eeb4f72b366Chad Versace pb_fence(buf->buffer, fence); 201988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul} 202988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 203988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul 204988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulstatic void 205988a8862c8379c0312d40353ee4b35537dff59a1Brian Paulpb_cache_buffer_get_base_buffer(struct pb_buffer *_buf, 206988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul struct pb_buffer **base_buf, 207988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul unsigned *offset) 208988a8862c8379c0312d40353ee4b35537dff59a1Brian Paul{ 20912d69fca096facf0ddb4642faaed4d5f02d76848Brian Paul struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 21012d69fca096facf0ddb4642faaed4d5f02d76848Brian Paul pb_get_base_buffer(buf->buffer, base_buf, offset); 21112d69fca096facf0ddb4642faaed4d5f02d76848Brian Paul} 2120bf5dbe002a64e198f55724cc1542602c012490fBrian 2130bf5dbe002a64e198f55724cc1542602c012490fBrian 2140bf5dbe002a64e198f55724cc1542602c012490fBrianconst struct pb_vtbl 2150bf5dbe002a64e198f55724cc1542602c012490fBrianpb_cache_buffer_vtbl = { 216a99114a69f2b7963ca1f855a320aea8aa56755acBrian pb_cache_buffer_destroy, 217a99114a69f2b7963ca1f855a320aea8aa56755acBrian pb_cache_buffer_map, 218a99114a69f2b7963ca1f855a320aea8aa56755acBrian pb_cache_buffer_unmap, 219a99114a69f2b7963ca1f855a320aea8aa56755acBrian pb_cache_buffer_validate, 220a99114a69f2b7963ca1f855a320aea8aa56755acBrian pb_cache_buffer_fence, 221f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg pb_cache_buffer_get_base_buffer 222a99114a69f2b7963ca1f855a320aea8aa56755acBrian}; 223a99114a69f2b7963ca1f855a320aea8aa56755acBrian 224a99114a69f2b7963ca1f855a320aea8aa56755acBrian 225a99114a69f2b7963ca1f855a320aea8aa56755acBrianstatic INLINE boolean 226a99114a69f2b7963ca1f855a320aea8aa56755acBrianpb_cache_is_buffer_compat(struct pb_cache_buffer *buf, 227a99114a69f2b7963ca1f855a320aea8aa56755acBrian size_t size, 22874713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul const struct pb_desc *desc) 22974713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul{ 230a99114a69f2b7963ca1f855a320aea8aa56755acBrian if(buf->base.base.size < size) 231a99114a69f2b7963ca1f855a320aea8aa56755acBrian return FALSE; 23274713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul 23374713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul /* be lenient with size */ 23474713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul if(buf->base.base.size >= 2*size) 23574713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul return FALSE; 236a99114a69f2b7963ca1f855a320aea8aa56755acBrian 237fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul if(!pb_check_alignment(desc->alignment, buf->base.base.alignment)) 238fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul return FALSE; 239fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul 240fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul if(!pb_check_usage(desc->usage, buf->base.base.usage)) 2419b8287f8f5398647ced3a52885233d58e548c2b7Brian Paul return FALSE; 2429b8287f8f5398647ced3a52885233d58e548c2b7Brian Paul 2439b8287f8f5398647ced3a52885233d58e548c2b7Brian Paul return TRUE; 2449b8287f8f5398647ced3a52885233d58e548c2b7Brian Paul} 245fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul 246fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul 247fd5511d27fc44096117c47ab503fb5b47f993061Brian Paulstatic struct pb_buffer * 248fd5511d27fc44096117c47ab503fb5b47f993061Brian Paulpb_cache_manager_create_buffer(struct pb_manager *_mgr, 249fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul size_t size, 250fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul const struct pb_desc *desc) 251fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul{ 252fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul struct pb_cache_manager *mgr = pb_cache_manager(_mgr); 253fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul struct pb_cache_buffer *buf; 254a99114a69f2b7963ca1f855a320aea8aa56755acBrian struct pb_cache_buffer *curr_buf; 255a99114a69f2b7963ca1f855a320aea8aa56755acBrian struct list_head *curr, *next; 256a99114a69f2b7963ca1f855a320aea8aa56755acBrian struct util_time now; 257a99114a69f2b7963ca1f855a320aea8aa56755acBrian 258a99114a69f2b7963ca1f855a320aea8aa56755acBrian pipe_mutex_lock(mgr->mutex); 259a99114a69f2b7963ca1f855a320aea8aa56755acBrian 260a99114a69f2b7963ca1f855a320aea8aa56755acBrian buf = NULL; 261a99114a69f2b7963ca1f855a320aea8aa56755acBrian curr = mgr->delayed.next; 262a99114a69f2b7963ca1f855a320aea8aa56755acBrian next = curr->next; 263a99114a69f2b7963ca1f855a320aea8aa56755acBrian 264a99114a69f2b7963ca1f855a320aea8aa56755acBrian /* search in the expired buffers, freeing them in the process */ 265a99114a69f2b7963ca1f855a320aea8aa56755acBrian util_time_get(&now); 266a99114a69f2b7963ca1f855a320aea8aa56755acBrian while(curr != &mgr->delayed) { 267a99114a69f2b7963ca1f855a320aea8aa56755acBrian curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 268a99114a69f2b7963ca1f855a320aea8aa56755acBrian if(!buf && pb_cache_is_buffer_compat(curr_buf, size, desc)) 269a99114a69f2b7963ca1f855a320aea8aa56755acBrian buf = curr_buf; 270a99114a69f2b7963ca1f855a320aea8aa56755acBrian else if(util_time_timeout(&curr_buf->start, &curr_buf->end, &now)) 27191e61f435a71436c209934a0ece165b540aba3e0Brian Paul _pb_cache_buffer_destroy(curr_buf); 272a99114a69f2b7963ca1f855a320aea8aa56755acBrian else 273a99114a69f2b7963ca1f855a320aea8aa56755acBrian /* This buffer (and all hereafter) are still hot in cache */ 274a99114a69f2b7963ca1f855a320aea8aa56755acBrian break; 275a99114a69f2b7963ca1f855a320aea8aa56755acBrian curr = next; 276a99114a69f2b7963ca1f855a320aea8aa56755acBrian next = curr->next; 277a99114a69f2b7963ca1f855a320aea8aa56755acBrian } 278a99114a69f2b7963ca1f855a320aea8aa56755acBrian 279099aad2fb0dba8baff61dc7a6803c6c976c08069Brian Paul /* keep searching in the hot buffers */ 280099aad2fb0dba8baff61dc7a6803c6c976c08069Brian Paul if(!buf) { 281099aad2fb0dba8baff61dc7a6803c6c976c08069Brian Paul while(curr != &mgr->delayed) { 282099aad2fb0dba8baff61dc7a6803c6c976c08069Brian Paul curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 283a99114a69f2b7963ca1f855a320aea8aa56755acBrian if(pb_cache_is_buffer_compat(curr_buf, size, desc)) { 284a99114a69f2b7963ca1f855a320aea8aa56755acBrian buf = curr_buf; 285a99114a69f2b7963ca1f855a320aea8aa56755acBrian break; 286a99114a69f2b7963ca1f855a320aea8aa56755acBrian } 287a99114a69f2b7963ca1f855a320aea8aa56755acBrian /* no need to check the timeout here */ 288a99114a69f2b7963ca1f855a320aea8aa56755acBrian curr = next; 289a99114a69f2b7963ca1f855a320aea8aa56755acBrian next = curr->next; 290a99114a69f2b7963ca1f855a320aea8aa56755acBrian } 291a99114a69f2b7963ca1f855a320aea8aa56755acBrian } 292a99114a69f2b7963ca1f855a320aea8aa56755acBrian 293a99114a69f2b7963ca1f855a320aea8aa56755acBrian if(buf) { 294a99114a69f2b7963ca1f855a320aea8aa56755acBrian LIST_DEL(&buf->head); 295a99114a69f2b7963ca1f855a320aea8aa56755acBrian pipe_mutex_unlock(mgr->mutex); 296a99114a69f2b7963ca1f855a320aea8aa56755acBrian /* Increase refcount */ 297a99114a69f2b7963ca1f855a320aea8aa56755acBrian pb_reference((struct pb_buffer**)&buf, &buf->base); 298a99114a69f2b7963ca1f855a320aea8aa56755acBrian return &buf->base; 299a99114a69f2b7963ca1f855a320aea8aa56755acBrian } 300a99114a69f2b7963ca1f855a320aea8aa56755acBrian 301a99114a69f2b7963ca1f855a320aea8aa56755acBrian pipe_mutex_unlock(mgr->mutex); 302a99114a69f2b7963ca1f855a320aea8aa56755acBrian 303a99114a69f2b7963ca1f855a320aea8aa56755acBrian buf = CALLOC_STRUCT(pb_cache_buffer); 304a99114a69f2b7963ca1f855a320aea8aa56755acBrian if(!buf) 305a99114a69f2b7963ca1f855a320aea8aa56755acBrian return NULL; 306a99114a69f2b7963ca1f855a320aea8aa56755acBrian 307a99114a69f2b7963ca1f855a320aea8aa56755acBrian buf->buffer = mgr->provider->create_buffer(mgr->provider, size, desc); 308a99114a69f2b7963ca1f855a320aea8aa56755acBrian if(!buf->buffer) { 309a99114a69f2b7963ca1f855a320aea8aa56755acBrian FREE(buf); 310a99114a69f2b7963ca1f855a320aea8aa56755acBrian return NULL; 311a99114a69f2b7963ca1f855a320aea8aa56755acBrian } 312a99114a69f2b7963ca1f855a320aea8aa56755acBrian 313a99114a69f2b7963ca1f855a320aea8aa56755acBrian assert(pipe_is_referenced(&buf->buffer->base.reference)); 314a99114a69f2b7963ca1f855a320aea8aa56755acBrian assert(pb_check_alignment(desc->alignment, buf->buffer->base.alignment)); 315a99114a69f2b7963ca1f855a320aea8aa56755acBrian assert(pb_check_usage(desc->usage, buf->buffer->base.usage)); 316a99114a69f2b7963ca1f855a320aea8aa56755acBrian assert(buf->buffer->base.size >= size); 317a99114a69f2b7963ca1f855a320aea8aa56755acBrian 318a99114a69f2b7963ca1f855a320aea8aa56755acBrian pipe_reference_init(&buf->base.base.reference, 1); 319a99114a69f2b7963ca1f855a320aea8aa56755acBrian buf->base.base.alignment = buf->buffer->base.alignment; 320a99114a69f2b7963ca1f855a320aea8aa56755acBrian buf->base.base.usage = buf->buffer->base.usage; 321a99114a69f2b7963ca1f855a320aea8aa56755acBrian buf->base.base.size = buf->buffer->base.size; 322a99114a69f2b7963ca1f855a320aea8aa56755acBrian 323 buf->base.vtbl = &pb_cache_buffer_vtbl; 324 buf->mgr = mgr; 325 326 return &buf->base; 327} 328 329 330static void 331pb_cache_manager_flush(struct pb_manager *_mgr) 332{ 333 struct pb_cache_manager *mgr = pb_cache_manager(_mgr); 334 struct list_head *curr, *next; 335 struct pb_cache_buffer *buf; 336 337 pipe_mutex_lock(mgr->mutex); 338 curr = mgr->delayed.next; 339 next = curr->next; 340 while(curr != &mgr->delayed) { 341 buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 342 _pb_cache_buffer_destroy(buf); 343 curr = next; 344 next = curr->next; 345 } 346 pipe_mutex_unlock(mgr->mutex); 347 348 assert(mgr->provider->flush); 349 if(mgr->provider->flush) 350 mgr->provider->flush(mgr->provider); 351} 352 353 354static void 355pb_cache_manager_destroy(struct pb_manager *mgr) 356{ 357 pb_cache_manager_flush(mgr); 358 FREE(mgr); 359} 360 361 362struct pb_manager * 363pb_cache_manager_create(struct pb_manager *provider, 364 unsigned usecs) 365{ 366 struct pb_cache_manager *mgr; 367 368 if(!provider) 369 return NULL; 370 371 mgr = CALLOC_STRUCT(pb_cache_manager); 372 if (!mgr) 373 return NULL; 374 375 mgr->base.destroy = pb_cache_manager_destroy; 376 mgr->base.create_buffer = pb_cache_manager_create_buffer; 377 mgr->base.flush = pb_cache_manager_flush; 378 mgr->provider = provider; 379 mgr->usecs = usecs; 380 LIST_INITHEAD(&mgr->delayed); 381 mgr->numDelayed = 0; 382 pipe_mutex_init(mgr->mutex); 383 384 return &mgr->base; 385} 386