1fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca/************************************************************************** 2fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * 3fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * All Rights Reserved. 5fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * 6fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 7fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * copy of this software and associated documentation files (the 8fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * "Software"), to deal in the Software without restriction, including 9fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * without limitation the rights to use, copy, modify, merge, publish, 10fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * distribute, sub license, and/or sell copies of the Software, and to 11fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * permit persons to whom the Software is furnished to do so, subject to 12fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * the following conditions: 13fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * 14fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * The above copyright notice and this permission notice (including the 15fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * next paragraph) shall be included in all copies or substantial portions 16fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * of the Software. 17fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * 18fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * 26fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca **************************************************************************/ 27fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 28fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca/** 29fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * \file 30fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * Buffer cache. 31fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * 32e06474dbae6979177629fb6187331291ff230c65José Fonseca * \author Jose Fonseca <jrfonseca-at-tungstengraphics-dot-com> 33fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com> 34fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca */ 35fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 36fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 37fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca#include "pipe/p_compiler.h" 38ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h" 392aaca1df9df6980ec88180c8866c8987b31db91aJosé Fonseca#include "os/os_thread.h" 404f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 41fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca#include "util/u_double_list.h" 42fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca#include "util/u_time.h" 43fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 44fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca#include "pb_buffer.h" 45fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca#include "pb_bufmgr.h" 46fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 47fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 48fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca/** 49fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * Convenience macro (type safe). 50fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca */ 51fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca#define SUPER(__derived) (&(__derived)->base) 52fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 53fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 54fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastruct pb_cache_manager; 55fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 56fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 57fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca/** 58fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * Wrapper around a pipe buffer which adds delayed destruction. 59fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca */ 60fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastruct pb_cache_buffer 61fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 62fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_buffer base; 63fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 64fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_buffer *buffer; 65fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_manager *mgr; 66fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 67fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca /** Caching time interval */ 68bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul int64_t start, end; 69fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 70fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct list_head head; 71fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca}; 72fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 73fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 74fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastruct pb_cache_manager 75fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 76fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_manager base; 77fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 78fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_manager *provider; 79fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca unsigned usecs; 80fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 810bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex mutex; 82fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 83fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct list_head delayed; 842af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca pb_size numDelayed; 85fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca}; 86fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 87fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 88fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic INLINE struct pb_cache_buffer * 89fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_buffer(struct pb_buffer *buf) 90fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 91fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca assert(buf); 92fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca return (struct pb_cache_buffer *)buf; 93fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 94fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 95fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 96fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic INLINE struct pb_cache_manager * 97fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_manager(struct pb_manager *mgr) 98fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 99fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca assert(mgr); 100fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca return (struct pb_cache_manager *)mgr; 101fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 102fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 103fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 104fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca/** 105fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * Actually destroy the buffer. 106fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca */ 107fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic INLINE void 108fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca_pb_cache_buffer_destroy(struct pb_cache_buffer *buf) 109fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 110fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_manager *mgr = buf->mgr; 111fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 112fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca LIST_DEL(&buf->head); 113fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca assert(mgr->numDelayed); 114fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca --mgr->numDelayed; 1154682e706012fe26627a2f827db01b5068cc62814Marek Olšák assert(!pipe_is_referenced(&buf->base.reference)); 116fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca pb_reference(&buf->buffer, NULL); 117fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca FREE(buf); 118fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 119fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 120fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 121fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca/** 122fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca * Free as many cache buffers from the list head as possible. 123fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca */ 124fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic void 125fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca_pb_cache_buffer_list_check_free(struct pb_cache_manager *mgr) 126fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 127fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct list_head *curr, *next; 128fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_buffer *buf; 129bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul int64_t now; 130fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 131bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul now = os_time_get(); 132fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 133fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca curr = mgr->delayed.next; 134fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca next = curr->next; 135fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca while(curr != &mgr->delayed) { 136fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 137fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 138bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul if(!os_time_timeout(buf->start, buf->end, now)) 139fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca break; 140fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 141fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca _pb_cache_buffer_destroy(buf); 142fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 143fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca curr = next; 144fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca next = curr->next; 145fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca } 146fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 147fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 148fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 149fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic void 150fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_buffer_destroy(struct pb_buffer *_buf) 151fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 152fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 153fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_manager *mgr = buf->mgr; 154fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 1550bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex_lock(mgr->mutex); 1564682e706012fe26627a2f827db01b5068cc62814Marek Olšák assert(!pipe_is_referenced(&buf->base.reference)); 157fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 158fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca _pb_cache_buffer_list_check_free(mgr); 159fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 160bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul buf->start = os_time_get(); 161bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul buf->end = buf->start + mgr->usecs; 162fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca LIST_ADDTAIL(&buf->head, &mgr->delayed); 163fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca ++mgr->numDelayed; 1640bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex_unlock(mgr->mutex); 165fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 166fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 167fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 168fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic void * 169fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_buffer_map(struct pb_buffer *_buf, 170b5fcf0c8e07e666523b007fab1d0fc18c2c89241Dave Airlie unsigned flags, void *flush_ctx) 171fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 172fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 173b5fcf0c8e07e666523b007fab1d0fc18c2c89241Dave Airlie return pb_map(buf->buffer, flags, flush_ctx); 174fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 175fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 176fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 177fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic void 178fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_buffer_unmap(struct pb_buffer *_buf) 179fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 180fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 181fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca pb_unmap(buf->buffer); 182fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 183fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 184fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 185e06474dbae6979177629fb6187331291ff230c65José Fonsecastatic enum pipe_error 186e06474dbae6979177629fb6187331291ff230c65José Fonsecapb_cache_buffer_validate(struct pb_buffer *_buf, 187e06474dbae6979177629fb6187331291ff230c65José Fonseca struct pb_validate *vl, 188e06474dbae6979177629fb6187331291ff230c65José Fonseca unsigned flags) 189e06474dbae6979177629fb6187331291ff230c65José Fonseca{ 190e06474dbae6979177629fb6187331291ff230c65José Fonseca struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 191e06474dbae6979177629fb6187331291ff230c65José Fonseca return pb_validate(buf->buffer, vl, flags); 192e06474dbae6979177629fb6187331291ff230c65José Fonseca} 193e06474dbae6979177629fb6187331291ff230c65José Fonseca 194e06474dbae6979177629fb6187331291ff230c65José Fonseca 195e06474dbae6979177629fb6187331291ff230c65José Fonsecastatic void 196e06474dbae6979177629fb6187331291ff230c65José Fonsecapb_cache_buffer_fence(struct pb_buffer *_buf, 197e06474dbae6979177629fb6187331291ff230c65José Fonseca struct pipe_fence_handle *fence) 198e06474dbae6979177629fb6187331291ff230c65José Fonseca{ 199e06474dbae6979177629fb6187331291ff230c65José Fonseca struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 200e06474dbae6979177629fb6187331291ff230c65José Fonseca pb_fence(buf->buffer, fence); 201e06474dbae6979177629fb6187331291ff230c65José Fonseca} 202e06474dbae6979177629fb6187331291ff230c65José Fonseca 203e06474dbae6979177629fb6187331291ff230c65José Fonseca 204fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic void 205fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_buffer_get_base_buffer(struct pb_buffer *_buf, 206fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_buffer **base_buf, 2072af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca pb_size *offset) 208fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 209fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 210fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca pb_get_base_buffer(buf->buffer, base_buf, offset); 211fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 212fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 213fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 214fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecaconst struct pb_vtbl 215fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_buffer_vtbl = { 216fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca pb_cache_buffer_destroy, 217fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca pb_cache_buffer_map, 218fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca pb_cache_buffer_unmap, 219e06474dbae6979177629fb6187331291ff230c65José Fonseca pb_cache_buffer_validate, 220e06474dbae6979177629fb6187331291ff230c65José Fonseca pb_cache_buffer_fence, 221fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca pb_cache_buffer_get_base_buffer 222fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca}; 223fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 224fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 22549866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airliestatic INLINE int 22695aeeb6d746e57473116ef4d72c05330902f68a5José Fonsecapb_cache_is_buffer_compat(struct pb_cache_buffer *buf, 2272af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca pb_size size, 22895aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca const struct pb_desc *desc) 22995aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca{ 2304682e706012fe26627a2f827db01b5068cc62814Marek Olšák if(buf->base.size < size) 23149866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie return 0; 2324b52f4df1b37918a363d05e0b3db22125e801367José Fonseca 2334b52f4df1b37918a363d05e0b3db22125e801367José Fonseca /* be lenient with size */ 2344682e706012fe26627a2f827db01b5068cc62814Marek Olšák if(buf->base.size >= 2*size) 23549866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie return 0; 23695aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 2374682e706012fe26627a2f827db01b5068cc62814Marek Olšák if(!pb_check_alignment(desc->alignment, buf->base.alignment)) 23849866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie return 0; 23995aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 2404682e706012fe26627a2f827db01b5068cc62814Marek Olšák if(!pb_check_usage(desc->usage, buf->base.usage)) 24149866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie return 0; 2420dab3189e1d100a9a2487f7aff45589b423c386cDave Airlie 24349579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák if (buf->mgr->provider->is_buffer_busy) { 24449579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák if (buf->mgr->provider->is_buffer_busy(buf->mgr->provider, buf->buffer)) 24549579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák return -1; 24649579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák } else { 24749579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák void *ptr = pb_map(buf->buffer, PB_USAGE_DONTBLOCK, NULL); 24849579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák 24949579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák if (!ptr) 25049579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák return -1; 25149579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák 25249579a4df8f9f85139a02c95ae59ea0a5dec663cMarek Olšák pb_unmap(buf->buffer); 2530dab3189e1d100a9a2487f7aff45589b423c386cDave Airlie } 2540dab3189e1d100a9a2487f7aff45589b423c386cDave Airlie 25549866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie return 1; 25695aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca} 25795aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 25895aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 259fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastatic struct pb_buffer * 260fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_manager_create_buffer(struct pb_manager *_mgr, 2612af0173e9e4eefe910c6011038e7346091a9b2a4José Fonseca pb_size size, 262fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca const struct pb_desc *desc) 263fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 264fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_manager *mgr = pb_cache_manager(_mgr); 265fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_buffer *buf; 26695aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca struct pb_cache_buffer *curr_buf; 267fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct list_head *curr, *next; 268bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul int64_t now; 26949866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie int ret = 0; 27049866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie 2710bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex_lock(mgr->mutex); 27295aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 27395aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca buf = NULL; 274fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca curr = mgr->delayed.next; 275fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca next = curr->next; 27695aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 27795aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca /* search in the expired buffers, freeing them in the process */ 278bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul now = os_time_get(); 279fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca while(curr != &mgr->delayed) { 28095aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 28149866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie if(!buf && (ret = pb_cache_is_buffer_compat(curr_buf, size, desc) > 0)) 28249866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie buf = curr_buf; 283bcace317c7ff2c774784b24b51b2de5d9cc871a0Brian Paul else if(os_time_timeout(curr_buf->start, curr_buf->end, now)) 28449866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie _pb_cache_buffer_destroy(curr_buf); 285038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca else 286038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca /* This buffer (and all hereafter) are still hot in cache */ 287038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca break; 28849866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie if (ret == -1) 28949866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie break; 29095aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca curr = next; 29195aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca next = curr->next; 29295aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca } 293fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 29495aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca /* keep searching in the hot buffers */ 29549866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie if(!buf && ret != -1) { 296038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca while(curr != &mgr->delayed) { 297038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 29849866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie ret = pb_cache_is_buffer_compat(curr_buf, size, desc); 29949866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie if (ret > 0) { 300038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca buf = curr_buf; 301038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca break; 302038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca } 30349866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie if (ret == -1) 30449866c8f34579420a30c33f76cfb2d77bafcdf0aDave Airlie break; 305038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca /* no need to check the timeout here */ 306038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca curr = next; 307038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca next = curr->next; 308038d53cbdb9e504388141c25859bce12f7e8f87eJosé Fonseca } 309fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca } 31095aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 31195aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca if(buf) { 31295aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca LIST_DEL(&buf->head); 313bf21b7006c63c3dc47045c22d4f372dfe6c7ce67Dave Airlie --mgr->numDelayed; 3140bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex_unlock(mgr->mutex); 3155e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer /* Increase refcount */ 3164682e706012fe26627a2f827db01b5068cc62814Marek Olšák pipe_reference_init(&buf->base.reference, 1); 31795aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca return &buf->base; 31895aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca } 31995aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 3200bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex_unlock(mgr->mutex); 321fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 322fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca buf = CALLOC_STRUCT(pb_cache_buffer); 323fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca if(!buf) 324fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca return NULL; 325fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 326fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca buf->buffer = mgr->provider->create_buffer(mgr->provider, size, desc); 32739d7de69b1e3317ba813b4475f2b6132d70f8eefMarek Olšák 32839d7de69b1e3317ba813b4475f2b6132d70f8eefMarek Olšák /* Empty the cache and try again. */ 32939d7de69b1e3317ba813b4475f2b6132d70f8eefMarek Olšák if (!buf->buffer) { 33039d7de69b1e3317ba813b4475f2b6132d70f8eefMarek Olšák mgr->base.flush(&mgr->base); 33139d7de69b1e3317ba813b4475f2b6132d70f8eefMarek Olšák buf->buffer = mgr->provider->create_buffer(mgr->provider, size, desc); 33239d7de69b1e3317ba813b4475f2b6132d70f8eefMarek Olšák } 33339d7de69b1e3317ba813b4475f2b6132d70f8eefMarek Olšák 334fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca if(!buf->buffer) { 335fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca FREE(buf); 336fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca return NULL; 337fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca } 338fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 3394682e706012fe26627a2f827db01b5068cc62814Marek Olšák assert(pipe_is_referenced(&buf->buffer->reference)); 3404682e706012fe26627a2f827db01b5068cc62814Marek Olšák assert(pb_check_alignment(desc->alignment, buf->buffer->alignment)); 3414682e706012fe26627a2f827db01b5068cc62814Marek Olšák assert(pb_check_usage(desc->usage, buf->buffer->usage)); 3424682e706012fe26627a2f827db01b5068cc62814Marek Olšák assert(buf->buffer->size >= size); 34395aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca 3444682e706012fe26627a2f827db01b5068cc62814Marek Olšák pipe_reference_init(&buf->base.reference, 1); 3454682e706012fe26627a2f827db01b5068cc62814Marek Olšák buf->base.alignment = buf->buffer->alignment; 3464682e706012fe26627a2f827db01b5068cc62814Marek Olšák buf->base.usage = buf->buffer->usage; 3474682e706012fe26627a2f827db01b5068cc62814Marek Olšák buf->base.size = buf->buffer->size; 348fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 349fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca buf->base.vtbl = &pb_cache_buffer_vtbl; 350fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca buf->mgr = mgr; 351fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 352fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca return &buf->base; 353fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 354fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 355fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 3561672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonsecastatic void 3571672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonsecapb_cache_manager_flush(struct pb_manager *_mgr) 358fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 359fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_manager *mgr = pb_cache_manager(_mgr); 360fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct list_head *curr, *next; 361fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_buffer *buf; 362fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 3630bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex_lock(mgr->mutex); 364fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca curr = mgr->delayed.next; 365fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca next = curr->next; 366fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca while(curr != &mgr->delayed) { 367fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 368fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca _pb_cache_buffer_destroy(buf); 369fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca curr = next; 370fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca next = curr->next; 371fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca } 3720bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex_unlock(mgr->mutex); 3731672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca 3741672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca assert(mgr->provider->flush); 3751672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca if(mgr->provider->flush) 3761672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca mgr->provider->flush(mgr->provider); 377a75a3df851339c782e045e01c2b21ffadb1e09f5José Fonseca} 378a75a3df851339c782e045e01c2b21ffadb1e09f5José Fonseca 379a75a3df851339c782e045e01c2b21ffadb1e09f5José Fonseca 380a75a3df851339c782e045e01c2b21ffadb1e09f5José Fonsecastatic void 381a75a3df851339c782e045e01c2b21ffadb1e09f5José Fonsecapb_cache_manager_destroy(struct pb_manager *mgr) 382a75a3df851339c782e045e01c2b21ffadb1e09f5José Fonseca{ 3831672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca pb_cache_manager_flush(mgr); 384fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca FREE(mgr); 385fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 386fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 387fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 388fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecastruct pb_manager * 389fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonsecapb_cache_manager_create(struct pb_manager *provider, 390fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca unsigned usecs) 391fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca{ 392fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca struct pb_cache_manager *mgr; 393fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 394ea4ca10b1bec67c8a60db0e4e5581318ce9f62f9José Fonseca if(!provider) 395ea4ca10b1bec67c8a60db0e4e5581318ce9f62f9José Fonseca return NULL; 396ea4ca10b1bec67c8a60db0e4e5581318ce9f62f9José Fonseca 397ea4ca10b1bec67c8a60db0e4e5581318ce9f62f9José Fonseca mgr = CALLOC_STRUCT(pb_cache_manager); 398fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca if (!mgr) 399fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca return NULL; 400fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 401fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca mgr->base.destroy = pb_cache_manager_destroy; 402fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca mgr->base.create_buffer = pb_cache_manager_create_buffer; 4031672e8e05996d48e51a1998bd7e9b08b78e012f5José Fonseca mgr->base.flush = pb_cache_manager_flush; 404fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca mgr->provider = provider; 405fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca mgr->usecs = usecs; 406fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca LIST_INITHEAD(&mgr->delayed); 407fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca mgr->numDelayed = 0; 4080bb852fa49e7f9a31036089ea4f5dfbd312a4a3aBrian Paul pipe_mutex_init(mgr->mutex); 409fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca 410fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca return &mgr->base; 411fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8José Fonseca} 412