1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Buffer cache. 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \author Jose Fonseca <jrfonseca-at-tungstengraphics-dot-com> 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com> 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_compiler.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "os/os_thread.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_double_list.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_time.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pb_buffer.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pb_bufmgr.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convenience macro (type safe). 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SUPER(__derived) (&(__derived)->base) 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_cache_manager; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Wrapper around a pipe buffer which adds delayed destruction. 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_cache_buffer 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_buffer base; 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_buffer *buffer; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_manager *mgr; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** Caching time interval */ 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int64_t start, end; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head head; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_cache_manager 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_manager base; 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_manager *provider; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned usecs; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex mutex; 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head delayed; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_size numDelayed; 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct pb_cache_buffer * 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_buffer(struct pb_buffer *buf) 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(buf); 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (struct pb_cache_buffer *)buf; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct pb_cache_manager * 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_manager(struct pb_manager *mgr) 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(mgr); 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (struct pb_cache_manager *)mgr; 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Actually destroy the buffer. 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_pb_cache_buffer_destroy(struct pb_cache_buffer *buf) 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_manager *mgr = buf->mgr; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&buf->head); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(mgr->numDelayed); 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org --mgr->numDelayed; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!pipe_is_referenced(&buf->base.reference)); 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_reference(&buf->buffer, NULL); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(buf); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free as many cache buffers from the list head as possible. 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_pb_cache_buffer_list_check_free(struct pb_cache_manager *mgr) 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head *curr, *next; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int64_t now; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org now = os_time_get(); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = mgr->delayed.next; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while(curr != &mgr->delayed) { 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!os_time_timeout(buf->start, buf->end, now)) 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _pb_cache_buffer_destroy(buf); 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = next; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_buffer_destroy(struct pb_buffer *_buf) 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_manager *mgr = buf->mgr; 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(mgr->mutex); 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!pipe_is_referenced(&buf->base.reference)); 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _pb_cache_buffer_list_check_free(mgr); 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->start = os_time_get(); 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->end = buf->start + mgr->usecs; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_ADDTAIL(&buf->head, &mgr->delayed); 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++mgr->numDelayed; 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(mgr->mutex); 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void * 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_buffer_map(struct pb_buffer *_buf, 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned flags, void *flush_ctx) 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return pb_map(buf->buffer, flags, flush_ctx); 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_buffer_unmap(struct pb_buffer *_buf) 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_unmap(buf->buffer); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum pipe_error 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_buffer_validate(struct pb_buffer *_buf, 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_validate *vl, 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned flags) 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return pb_validate(buf->buffer, vl, flags); 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_buffer_fence(struct pb_buffer *_buf, 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_fence_handle *fence) 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_fence(buf->buffer, fence); 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_buffer_get_base_buffer(struct pb_buffer *_buf, 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_buffer **base_buf, 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_size *offset) 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf = pb_cache_buffer(_buf); 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_get_base_buffer(buf->buffer, base_buf, offset); 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst struct pb_vtbl 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_buffer_vtbl = { 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_cache_buffer_destroy, 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_cache_buffer_map, 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_cache_buffer_unmap, 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_cache_buffer_validate, 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_cache_buffer_fence, 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_cache_buffer_get_base_buffer 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_is_buffer_compat(struct pb_cache_buffer *buf, 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_size size, 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct pb_desc *desc) 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(buf->base.size < size) 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* be lenient with size */ 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(buf->base.size >= 2*size) 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!pb_check_alignment(desc->alignment, buf->base.alignment)) 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!pb_check_usage(desc->usage, buf->base.usage)) 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (buf->mgr->provider->is_buffer_busy) { 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (buf->mgr->provider->is_buffer_busy(buf->mgr->provider, buf->buffer)) 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ptr = pb_map(buf->buffer, PB_USAGE_DONTBLOCK, NULL); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ptr) 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_unmap(buf->buffer); 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pb_buffer * 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_manager_create_buffer(struct pb_manager *_mgr, 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_size size, 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct pb_desc *desc) 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_manager *mgr = pb_cache_manager(_mgr); 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf; 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *curr_buf; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head *curr, *next; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int64_t now; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ret = 0; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(mgr->mutex); 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf = NULL; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = mgr->delayed.next; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* search in the expired buffers, freeing them in the process */ 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org now = os_time_get(); 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while(curr != &mgr->delayed) { 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!buf && (ret = pb_cache_is_buffer_compat(curr_buf, size, desc) > 0)) 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf = curr_buf; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(os_time_timeout(curr_buf->start, curr_buf->end, now)) 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _pb_cache_buffer_destroy(curr_buf); 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This buffer (and all hereafter) are still hot in cache */ 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret == -1) 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = next; 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* keep searching in the hot buffers */ 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!buf && ret != -1) { 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while(curr != &mgr->delayed) { 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = pb_cache_is_buffer_compat(curr_buf, size, desc); 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret > 0) { 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf = curr_buf; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret == -1) 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no need to check the timeout here */ 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = next; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(buf) { 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&buf->head); 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org --mgr->numDelayed; 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(mgr->mutex); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Increase refcount */ 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_reference_init(&buf->base.reference, 1); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &buf->base; 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(mgr->mutex); 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf = CALLOC_STRUCT(pb_cache_buffer); 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!buf) 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->buffer = mgr->provider->create_buffer(mgr->provider, size, desc); 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Empty the cache and try again. */ 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!buf->buffer) { 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr->base.flush(&mgr->base); 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->buffer = mgr->provider->create_buffer(mgr->provider, size, desc); 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!buf->buffer) { 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(buf); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(pipe_is_referenced(&buf->buffer->reference)); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(pb_check_alignment(desc->alignment, buf->buffer->alignment)); 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(pb_check_usage(desc->usage, buf->buffer->usage)); 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(buf->buffer->size >= size); 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_reference_init(&buf->base.reference, 1); 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->base.alignment = buf->buffer->alignment; 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->base.usage = buf->buffer->usage; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->base.size = buf->buffer->size; 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->base.vtbl = &pb_cache_buffer_vtbl; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf->mgr = mgr; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &buf->base; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_manager_flush(struct pb_manager *_mgr) 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_manager *mgr = pb_cache_manager(_mgr); 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head *curr, *next; 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_buffer *buf; 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(mgr->mutex); 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = mgr->delayed.next; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while(curr != &mgr->delayed) { 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _pb_cache_buffer_destroy(buf); 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = next; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(mgr->mutex); 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(mgr->provider->flush); 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(mgr->provider->flush) 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr->provider->flush(mgr->provider); 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_manager_destroy(struct pb_manager *mgr) 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pb_cache_manager_flush(mgr); 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(mgr); 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pb_manager * 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpb_cache_manager_create(struct pb_manager *provider, 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned usecs) 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pb_cache_manager *mgr; 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!provider) 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr = CALLOC_STRUCT(pb_cache_manager); 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!mgr) 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr->base.destroy = pb_cache_manager_destroy; 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr->base.create_buffer = pb_cache_manager_create_buffer; 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr->base.flush = pb_cache_manager_flush; 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr->provider = provider; 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr->usecs = usecs; 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_INITHEAD(&mgr->delayed); 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mgr->numDelayed = 0; 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_init(mgr->mutex); 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &mgr->base; 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 412