vpx/vpx_mem/memory_manager/hmm_shrink.c

104 lines
3.1 KiB
C
Raw Normal View History

2010-05-18 17:58:33 +02:00
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
2010-05-18 17:58:33 +02:00
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
2010-05-18 17:58:33 +02:00
*/
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#include "hmm_intrnl.h"
void U(shrink_chunk)(U(descriptor) *desc, U(size_bau) n_baus_to_shrink) {
head_record *dummy_end_block = (head_record *)
BAUS_BACKWARD(desc->end_of_shrinkable_chunk, DUMMY_END_BLOCK_BAUS);
2010-05-18 17:58:33 +02:00
#ifdef HMM_AUDIT_FAIL
if (dummy_end_block->block_size != 0)
/* Chunk does not have valid dummy end block. */
HMM_AUDIT_FAIL
2010-05-18 17:58:33 +02:00
#endif
if (n_baus_to_shrink) {
head_record *last_block = (head_record *)
BAUS_BACKWARD(
dummy_end_block, dummy_end_block->previous_block_size);
2010-05-18 17:58:33 +02:00
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(last_block)
2010-05-18 17:58:33 +02:00
#endif
if (last_block == desc->last_freed) {
U(size_bau) bs = BLOCK_BAUS(last_block);
/* Chunk will not be shrunk out of existence if
** 1. There is at least one allocated block in the chunk
** and the amount to shrink is exactly the size of the
** last block, OR
** 2. After the last block is shrunk, there will be enough
** BAUs left in it to form a minimal size block. */
int chunk_will_survive =
(PREV_BLOCK_BAUS(last_block) && (n_baus_to_shrink == bs)) ||
(n_baus_to_shrink <= (U(size_bau))(bs - MIN_BLOCK_BAUS));
if (chunk_will_survive ||
(!PREV_BLOCK_BAUS(last_block) &&
(n_baus_to_shrink ==
(U(size_bau))(bs + DUMMY_END_BLOCK_BAUS)))) {
desc->last_freed = 0;
if (chunk_will_survive) {
bs -= n_baus_to_shrink;
if (bs) {
/* The last (non-dummy) block was not completely
** eliminated by the shrink. */
last_block->block_size = bs;
/* Create new dummy end record.
*/
dummy_end_block =
(head_record *) BAUS_FORWARD(last_block, bs);
dummy_end_block->previous_block_size = bs;
dummy_end_block->block_size = 0;
2010-05-18 17:58:33 +02:00
#ifdef HMM_AUDIT_FAIL
if (desc->avl_tree_root)
AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
2010-05-18 17:58:33 +02:00
#endif
U(into_free_collection)(desc, last_block);
} else {
/* The last (non-dummy) block was completely
** eliminated by the shrink. Make its head
** the new dummy end block.
*/
last_block->block_size = 0;
last_block->previous_block_size &= ~HIGH_BIT_BAU_SIZE;
}
}
}
2010-05-18 17:58:33 +02:00
#ifdef HMM_AUDIT_FAIL
else
HMM_AUDIT_FAIL
2010-05-18 17:58:33 +02:00
#endif
}
2010-05-18 17:58:33 +02:00
#ifdef HMM_AUDIT_FAIL
else
HMM_AUDIT_FAIL
2010-05-18 17:58:33 +02:00
#endif
}
2010-05-18 17:58:33 +02:00
}