blob: f90da969248fb60394b676486381ed7f528ed285 [file] [log] [blame]
John Koleszar0ea50ce2010-05-18 11:58:33 -04001/*
John Koleszarc2140b82010-09-09 08:16:39 -04002 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar0ea50ce2010-05-18 11:58:33 -04003 *
John Koleszar94c52e42010-06-18 12:39:21 -04004 * Use of this source code is governed by a BSD-style license
John Koleszar09202d82010-06-04 16:19:40 -04005 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
John Koleszar94c52e42010-06-18 12:39:21 -04007 * in the file PATENTS. All contributing project authors may
John Koleszar09202d82010-06-04 16:19:40 -04008 * be found in the AUTHORS file in the root of the source tree.
John Koleszar0ea50ce2010-05-18 11:58:33 -04009 */
10
11
12/* This code is in the public domain.
13** Version: 1.1 Author: Walt Karas
14*/
15
16#include "hmm_intrnl.h"
17
18int U(resize)(U(descriptor) *desc, void *mem, U(size_aau) n)
19{
20 U(size_aau) i;
21 head_record *next_head_ptr;
22 head_record *head_ptr = PTR_REC_TO_HEAD(mem);
23
24 /* Flag. */
25 int next_block_free;
26
27 /* Convert n from desired block size in AAUs to BAUs. */
28 n += HEAD_AAUS;
29 n = DIV_ROUND_UP(n, HMM_BLOCK_ALIGN_UNIT);
30
31 if (n < MIN_BLOCK_BAUS)
32 n = MIN_BLOCK_BAUS;
33
34#ifdef HMM_AUDIT_FAIL
35
36 AUDIT_BLOCK(head_ptr)
37
38 if (!IS_BLOCK_ALLOCATED(head_ptr))
39 HMM_AUDIT_FAIL
40
41 if (desc->avl_tree_root)
42 AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
43
44#endif
45
46 i = head_ptr->block_size;
47
48 next_head_ptr =
49 (head_record *) BAUS_FORWARD(head_ptr, head_ptr->block_size);
50
51 next_block_free =
52 (next_head_ptr == desc->last_freed) ||
53 !IS_BLOCK_ALLOCATED(next_head_ptr);
54
55 if (next_block_free)
56 /* Block can expand into next free block. */
57 i += BLOCK_BAUS(next_head_ptr);
58
59 if (n > i)
60 /* Not enough room for block to expand. */
61 return(-1);
62
63 if (next_block_free)
64 {
65#ifdef HMM_AUDIT_FAIL
66 AUDIT_BLOCK(next_head_ptr)
67#endif
68
69 if (next_head_ptr == desc->last_freed)
70 desc->last_freed = 0;
71 else
72 U(out_of_free_collection)(desc, next_head_ptr);
73
74 next_head_ptr =
75 (head_record *) BAUS_FORWARD(head_ptr, (U(size_bau)) i);
76 }
77
78 /* Set i to number of "extra" BAUs. */
79 i -= n;
80
81 if (i < MIN_BLOCK_BAUS)
82 /* Not enough extra BAUs to be a block on their own, so just keep them
83 ** in the block being resized.
84 */
85 {
86 n += i;
87 i = n;
88 }
89 else
90 {
91 /* There are enough "leftover" BAUs in the next block to
92 ** form a remainder block. */
93
94 head_record *rem_head_ptr;
95
96 rem_head_ptr = (head_record *) BAUS_FORWARD(head_ptr, n);
97
98 rem_head_ptr->previous_block_size = (U(size_bau)) n;
99 rem_head_ptr->block_size = (U(size_bau)) i;
100
101 if (desc->last_freed)
102 {
103#ifdef HMM_AUDIT_FAIL
104 AUDIT_BLOCK(desc->last_freed)
105#endif
106
107 U(into_free_collection)(desc, (head_record *)(desc->last_freed));
108
109 desc->last_freed = 0;
110 }
111
112 desc->last_freed = rem_head_ptr;
113 }
114
115 head_ptr->block_size = (U(size_bau)) n;
116 next_head_ptr->previous_block_size = (U(size_bau)) i;
117
118 return(0);
119}