2010-05-18 17:58:33 +02:00
|
|
|
/*
|
2010-09-09 14:16:39 +02:00
|
|
|
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
2010-05-18 17:58:33 +02:00
|
|
|
*
|
2010-06-18 18:39:21 +02:00
|
|
|
* Use of this source code is governed by a BSD-style license
|
2010-06-04 22:19:40 +02:00
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
2010-06-18 18:39:21 +02:00
|
|
|
* in the file PATENTS. All contributing project authors may
|
2010-06-04 22:19:40 +02:00
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
2013-12-16 03:32:02 +01:00
|
|
|
#ifndef VPX_MEM_MEMORY_MANAGER_INCLUDE_HMM_INTRNL_H_
|
|
|
|
#define VPX_MEM_MEMORY_MANAGER_INCLUDE_HMM_INTRNL_H_
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
#ifdef __uClinux__
|
|
|
|
# include <lddk.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "heapmm.h"
|
|
|
|
|
|
|
|
#define U(BASE) HMM_UNIQUE(BASE)
|
|
|
|
|
|
|
|
/* Mask of high bit of variable of size_bau type. */
|
|
|
|
#define HIGH_BIT_BAU_SIZE \
|
2012-07-14 00:21:29 +02:00
|
|
|
((U(size_bau)) ~ (((U(size_bau)) ~ (U(size_bau)) 0) >> 1))
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Add a given number of AAUs to pointer. */
|
|
|
|
#define AAUS_FORWARD(PTR, AAU_OFFSET) \
|
2012-07-14 00:21:29 +02:00
|
|
|
(((char *) (PTR)) + ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT)))
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Subtract a given number of AAUs from pointer. */
|
|
|
|
#define AAUS_BACKWARD(PTR, AAU_OFFSET) \
|
2012-07-14 00:21:29 +02:00
|
|
|
(((char *) (PTR)) - ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT)))
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Add a given number of BAUs to a pointer. */
|
|
|
|
#define BAUS_FORWARD(PTR, BAU_OFFSET) \
|
2012-07-14 00:21:29 +02:00
|
|
|
AAUS_FORWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT))
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Subtract a given number of BAUs to a pointer. */
|
|
|
|
#define BAUS_BACKWARD(PTR, BAU_OFFSET) \
|
2012-07-14 00:21:29 +02:00
|
|
|
AAUS_BACKWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT))
|
2010-05-18 17:58:33 +02:00
|
|
|
|
2012-07-14 00:21:29 +02:00
|
|
|
typedef struct head_struct {
|
|
|
|
/* Sizes in Block Alignment Units. */
|
|
|
|
HMM_UNIQUE(size_bau) previous_block_size, block_size;
|
2010-05-18 17:58:33 +02:00
|
|
|
}
|
|
|
|
head_record;
|
|
|
|
|
2012-07-14 00:21:29 +02:00
|
|
|
typedef struct ptr_struct {
|
|
|
|
struct ptr_struct *self, *prev, *next;
|
2010-05-18 17:58:33 +02:00
|
|
|
}
|
|
|
|
ptr_record;
|
|
|
|
|
|
|
|
/* Divide and round up any fraction to the next whole number. */
|
|
|
|
#define DIV_ROUND_UP(NUMER, DENOM) (((NUMER) + (DENOM) - 1) / (DENOM))
|
|
|
|
|
|
|
|
/* Number of AAUs in a block head. */
|
|
|
|
#define HEAD_AAUS DIV_ROUND_UP(sizeof(head_record), HMM_ADDR_ALIGN_UNIT)
|
|
|
|
|
|
|
|
/* Number of AAUs in a block pointer record. */
|
|
|
|
#define PTR_RECORD_AAUS DIV_ROUND_UP(sizeof(ptr_record), HMM_ADDR_ALIGN_UNIT)
|
|
|
|
|
|
|
|
/* Number of BAUs in a dummy end record (at end of chunk). */
|
|
|
|
#define DUMMY_END_BLOCK_BAUS DIV_ROUND_UP(HEAD_AAUS, HMM_BLOCK_ALIGN_UNIT)
|
|
|
|
|
|
|
|
/* Minimum number of BAUs in a block (allowing room for the pointer record. */
|
|
|
|
#define MIN_BLOCK_BAUS \
|
2012-07-14 00:21:29 +02:00
|
|
|
DIV_ROUND_UP(HEAD_AAUS + PTR_RECORD_AAUS, HMM_BLOCK_ALIGN_UNIT)
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Return number of BAUs in block (masking off high bit containing block
|
|
|
|
** status). */
|
|
|
|
#define BLOCK_BAUS(HEAD_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
(((head_record *) (HEAD_PTR))->block_size & ~HIGH_BIT_BAU_SIZE)
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Return number of BAUs in previous block (masking off high bit containing
|
|
|
|
** block status). */
|
|
|
|
#define PREV_BLOCK_BAUS(HEAD_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
(((head_record *) (HEAD_PTR))->previous_block_size & ~HIGH_BIT_BAU_SIZE)
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Set number of BAUs in previous block, preserving high bit containing
|
|
|
|
** block status. */
|
|
|
|
#define SET_PREV_BLOCK_BAUS(HEAD_PTR, N_BAUS) \
|
2012-07-14 00:21:29 +02:00
|
|
|
{ register head_record *h_ptr = (head_record *) (HEAD_PTR); \
|
|
|
|
h_ptr->previous_block_size &= HIGH_BIT_BAU_SIZE; \
|
|
|
|
h_ptr->previous_block_size |= (N_BAUS); }
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Convert pointer to pointer record of block to pointer to block's head
|
|
|
|
** record. */
|
|
|
|
#define PTR_REC_TO_HEAD(PTR_REC_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
((head_record *) AAUS_BACKWARD(PTR_REC_PTR, HEAD_AAUS))
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Convert pointer to block head to pointer to block's pointer record. */
|
|
|
|
#define HEAD_TO_PTR_REC(HEAD_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
((ptr_record *) AAUS_FORWARD(HEAD_PTR, HEAD_AAUS))
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Returns non-zero if block is allocated. */
|
|
|
|
#define IS_BLOCK_ALLOCATED(HEAD_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
(((((head_record *) (HEAD_PTR))->block_size | \
|
|
|
|
((head_record *) (HEAD_PTR))->previous_block_size) & \
|
|
|
|
HIGH_BIT_BAU_SIZE) == 0)
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
#define MARK_BLOCK_ALLOCATED(HEAD_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
{ register head_record *h_ptr = (head_record *) (HEAD_PTR); \
|
|
|
|
h_ptr->block_size &= ~HIGH_BIT_BAU_SIZE; \
|
|
|
|
h_ptr->previous_block_size &= ~HIGH_BIT_BAU_SIZE; }
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Mark a block as free when it is not the first block in a bin (and
|
|
|
|
** therefore not a node in the AVL tree). */
|
|
|
|
#define MARK_SUCCESSIVE_BLOCK_IN_FREE_BIN(HEAD_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
{ register head_record *h_ptr = (head_record *) (HEAD_PTR); \
|
|
|
|
h_ptr->block_size |= HIGH_BIT_BAU_SIZE; }
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
/* Prototypes for internal functions implemented in one file and called in
|
|
|
|
** another.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void U(into_free_collection)(U(descriptor) *desc, head_record *head_ptr);
|
|
|
|
|
|
|
|
void U(out_of_free_collection)(U(descriptor) *desc, head_record *head_ptr);
|
|
|
|
|
|
|
|
void *U(alloc_from_bin)(
|
2012-07-14 00:21:29 +02:00
|
|
|
U(descriptor) *desc, ptr_record *bin_front_ptr, U(size_bau) n_baus);
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
#ifdef HMM_AUDIT_FAIL
|
|
|
|
|
|
|
|
/* Simply contains a reference to the HMM_AUDIT_FAIL macro and a
|
|
|
|
** dummy return. */
|
|
|
|
int U(audit_block_fail_dummy_return)(void);
|
|
|
|
|
|
|
|
|
|
|
|
/* Auditing a block consists of checking that the size in its head
|
|
|
|
** matches the previous block size in the head of the next block. */
|
|
|
|
#define AUDIT_BLOCK_AS_EXPR(HEAD_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
((BLOCK_BAUS(HEAD_PTR) == \
|
|
|
|
PREV_BLOCK_BAUS(BAUS_FORWARD(HEAD_PTR, BLOCK_BAUS(HEAD_PTR)))) ? \
|
|
|
|
0 : U(audit_block_fail_dummy_return)())
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
#define AUDIT_BLOCK(HEAD_PTR) \
|
2012-07-14 00:21:29 +02:00
|
|
|
{ void *h_ptr = (HEAD_PTR); AUDIT_BLOCK_AS_EXPR(h_ptr); }
|
2010-05-18 17:58:33 +02:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Interface to AVL tree generic package instantiation. */
|
|
|
|
|
|
|
|
#define AVL_UNIQUE(BASE) U(avl_ ## BASE)
|
|
|
|
|
|
|
|
#define AVL_HANDLE ptr_record *
|
|
|
|
|
|
|
|
#define AVL_KEY U(size_bau)
|
|
|
|
|
|
|
|
#define AVL_MAX_DEPTH 64
|
|
|
|
|
|
|
|
#include "cavl_if.h"
|
|
|
|
|
2013-12-16 03:32:02 +01:00
|
|
|
#endif // VPX_MEM_MEMORY_MANAGER_INCLUDE_HMM_INTRNL_H_
|