2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * 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
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
12 /* This code is in the public domain.
13 ** Version: 1.1 Author: Walt Karas
16 #include "hmm_intrnl.h"
18 int U(resize
)(U(descriptor
) *desc
, void *mem
, U(size_aau
) n
)
21 head_record
*next_head_ptr
;
22 head_record
*head_ptr
= PTR_REC_TO_HEAD(mem
);
27 /* Convert n from desired block size in AAUs to BAUs. */
29 n
= DIV_ROUND_UP(n
, HMM_BLOCK_ALIGN_UNIT
);
31 if (n
< MIN_BLOCK_BAUS
)
38 if (!IS_BLOCK_ALLOCATED(head_ptr
))
41 if (desc
->avl_tree_root
)
42 AUDIT_BLOCK(PTR_REC_TO_HEAD(desc
->avl_tree_root
))
46 i
= head_ptr
->block_size
;
49 (head_record
*) BAUS_FORWARD(head_ptr
, head_ptr
->block_size
);
52 (next_head_ptr
== desc
->last_freed
) ||
53 !IS_BLOCK_ALLOCATED(next_head_ptr
);
56 /* Block can expand into next free block. */
57 i
+= BLOCK_BAUS(next_head_ptr
);
60 /* Not enough room for block to expand. */
66 AUDIT_BLOCK(next_head_ptr
)
69 if (next_head_ptr
== desc
->last_freed
)
72 U(out_of_free_collection
)(desc
, next_head_ptr
);
75 (head_record
*) BAUS_FORWARD(head_ptr
, (U(size_bau
)) i
);
78 /* Set i to number of "extra" BAUs. */
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.
91 /* There are enough "leftover" BAUs in the next block to
92 ** form a remainder block. */
94 head_record
*rem_head_ptr
;
96 rem_head_ptr
= (head_record
*) BAUS_FORWARD(head_ptr
, n
);
98 rem_head_ptr
->previous_block_size
= (U(size_bau
)) n
;
99 rem_head_ptr
->block_size
= (U(size_bau
)) i
;
101 if (desc
->last_freed
)
103 #ifdef HMM_AUDIT_FAIL
104 AUDIT_BLOCK(desc
->last_freed
)
107 U(into_free_collection
)(desc
, (head_record
*)(desc
->last_freed
));
109 desc
->last_freed
= 0;
112 desc
->last_freed
= rem_head_ptr
;
115 head_ptr
->block_size
= (U(size_bau
)) n
;
116 next_head_ptr
->previous_block_size
= (U(size_bau
)) i
;