1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/* 2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * 4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * Use of this source code is governed by a BSD-style license 5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * that can be found in the LICENSE file in the root of the source 6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * tree. An additional intellectual property rights grant can be found 7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * in the file PATENTS. All contributing project authors may 8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org * be found in the AUTHORS file in the root of the source tree. 9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */ 10474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 11474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 12474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/* This code is in the public domain. 13474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org** Version: 1.1 Author: Walt Karas 14474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org*/ 15474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 16474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "hmm_intrnl.h" 17474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgint U(resize)(U(descriptor) *desc, void *mem, U(size_aau) n) { 196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org U(size_aau) i; 206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org head_record *next_head_ptr; 216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org head_record *head_ptr = PTR_REC_TO_HEAD(mem); 22474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Flag. */ 246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int next_block_free; 25474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Convert n from desired block size in AAUs to BAUs. */ 276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org n += HEAD_AAUS; 286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org n = DIV_ROUND_UP(n, HMM_BLOCK_ALIGN_UNIT); 29474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (n < MIN_BLOCK_BAUS) 316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org n = MIN_BLOCK_BAUS; 32474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 33474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#ifdef HMM_AUDIT_FAIL 34474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org AUDIT_BLOCK(head_ptr) 36474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (!IS_BLOCK_ALLOCATED(head_ptr)) 386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org HMM_AUDIT_FAIL 39474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (desc->avl_tree_root) 416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root)) 42474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 43474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif 44474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org i = head_ptr->block_size; 46474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org next_head_ptr = 486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (head_record *) BAUS_FORWARD(head_ptr, head_ptr->block_size); 49474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org next_block_free = 516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (next_head_ptr == desc->last_freed) || 526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org !IS_BLOCK_ALLOCATED(next_head_ptr); 53474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (next_block_free) 556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Block can expand into next free block. */ 566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org i += BLOCK_BAUS(next_head_ptr); 57474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (n > i) 596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Not enough room for block to expand. */ 606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return(-1); 61474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (next_block_free) { 63474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#ifdef HMM_AUDIT_FAIL 646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org AUDIT_BLOCK(next_head_ptr) 65474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif 66474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (next_head_ptr == desc->last_freed) 686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org desc->last_freed = 0; 696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else 706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org U(out_of_free_collection)(desc, next_head_ptr); 71474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org next_head_ptr = 736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (head_record *) BAUS_FORWARD(head_ptr, (U(size_bau)) i); 746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 75474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Set i to number of "extra" BAUs. */ 776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org i -= n; 78474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (i < MIN_BLOCK_BAUS) 806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* Not enough extra BAUs to be a block on their own, so just keep them 816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ** in the block being resized. 826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */ 836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org { 846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org n += i; 856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org i = n; 866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } else { 876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org /* There are enough "leftover" BAUs in the next block to 886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ** form a remainder block. */ 89474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org head_record *rem_head_ptr; 91474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org rem_head_ptr = (head_record *) BAUS_FORWARD(head_ptr, n); 93474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org rem_head_ptr->previous_block_size = (U(size_bau)) n; 956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org rem_head_ptr->block_size = (U(size_bau)) i; 96474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (desc->last_freed) { 98474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#ifdef HMM_AUDIT_FAIL 996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org AUDIT_BLOCK(desc->last_freed) 100474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif 101474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org U(into_free_collection)(desc, (head_record *)(desc->last_freed)); 103474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 1046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org desc->last_freed = 0; 105474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 106474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 1076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org desc->last_freed = rem_head_ptr; 1086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org head_ptr->block_size = (U(size_bau)) n; 1116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org next_head_ptr->previous_block_size = (U(size_bau)) i; 112474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 1136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return(0); 114474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 115