/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  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.
 */


/* This code is in the public domain.
** Version: 1.1  Author: Walt Karas
*/

/* External header file for Heap Memory Manager.  See documentation in
** heapmm.html.
*/

#undef HMM_PROCESS

/* Include once per configuration in a particular translation unit. */

#ifndef HMM_CNFG_NUM

/* Default configuration. */

#ifndef HMM_INC_CNFG_DFLT
#define HMM_INC_CNFG_DFLT
#define HMM_PROCESS
#endif

#elif HMM_CNFG_NUM == 0

/* Test configuration. */

#ifndef HMM_INC_CNFG_0
#define HMM_INC_CNFG_0
#define HMM_PROCESS
#endif

#elif HMM_CNFG_NUM == 1

#ifndef HMM_INC_CNFG_1
#define HMM_INC_CNFG_1
#define HMM_PROCESS
#endif

#elif HMM_CNFG_NUM == 2

#ifndef HMM_INC_CNFG_2
#define HMM_INC_CNFG_2
#define HMM_PROCESS
#endif

#elif HMM_CNFG_NUM == 3

#ifndef HMM_INC_CNFG_3
#define HMM_INC_CNFG_3
#define HMM_PROCESS
#endif

#elif HMM_CNFG_NUM == 4

#ifndef HMM_INC_CNFG_4
#define HMM_INC_CNFG_4
#define HMM_PROCESS
#endif

#elif HMM_CNFG_NUM == 5

#ifndef HMM_INC_CNFG_5
#define HMM_INC_CNFG_5
#define HMM_PROCESS
#endif

#endif

#ifdef HMM_PROCESS

#include "hmm_cnfg.h"

/* Heap descriptor. */
typedef struct HMM_UNIQUE(structure) {
  /* private: */

  /* Pointer to (payload of) root node in AVL tree.  This field should
  ** really be the AVL tree descriptor (type avl_avl).  But (in the
  ** instantiation of the AVL tree generic package used in package) the
  ** AVL tree descriptor simply contains a pointer to the root.  So,
  ** whenever a pointer to the AVL tree descriptor is needed, I use the
  ** cast:
  **
  ** (avl_avl *) &(heap_desc->avl_tree_root)
  **
  ** (where heap_desc is a pointer to a heap descriptor).  This trick
  ** allows me to avoid including cavl_if.h in this external header. */
  void *avl_tree_root;

  /* Pointer to first byte of last block freed, after any coalescing. */
  void *last_freed;

  /* public: */

  HMM_UNIQUE(size_bau) num_baus_can_shrink;
  void *end_of_shrinkable_chunk;
}
HMM_UNIQUE(descriptor);

/* Prototypes for externally-callable functions. */

void HMM_UNIQUE(init)(HMM_UNIQUE(descriptor) *desc);

void *HMM_UNIQUE(alloc)(
  HMM_UNIQUE(descriptor) *desc, HMM_UNIQUE(size_aau) num_addr_align_units);

/* NOT YET IMPLEMENTED */
void *HMM_UNIQUE(greedy_alloc)(
  HMM_UNIQUE(descriptor) *desc, HMM_UNIQUE(size_aau) needed_addr_align_units,
  HMM_UNIQUE(size_aau) coveted_addr_align_units);

int HMM_UNIQUE(resize)(
  HMM_UNIQUE(descriptor) *desc, void *mem,
  HMM_UNIQUE(size_aau) num_addr_align_units);

/* NOT YET IMPLEMENTED */
int HMM_UNIQUE(greedy_resize)(
  HMM_UNIQUE(descriptor) *desc, void *mem,
  HMM_UNIQUE(size_aau) needed_addr_align_units,
  HMM_UNIQUE(size_aau) coveted_addr_align_units);

void HMM_UNIQUE(free)(HMM_UNIQUE(descriptor) *desc, void *mem);

HMM_UNIQUE(size_aau) HMM_UNIQUE(true_size)(void *mem);

HMM_UNIQUE(size_aau) HMM_UNIQUE(largest_available)(
  HMM_UNIQUE(descriptor) *desc);

void HMM_UNIQUE(new_chunk)(
  HMM_UNIQUE(descriptor) *desc, void *start_of_chunk,
  HMM_UNIQUE(size_bau) num_block_align_units);

void HMM_UNIQUE(grow_chunk)(
  HMM_UNIQUE(descriptor) *desc, void *end_of_chunk,
  HMM_UNIQUE(size_bau) num_block_align_units);

/* NOT YET IMPLEMENTED */
void HMM_UNIQUE(shrink_chunk)(
  HMM_UNIQUE(descriptor) *desc,
  HMM_UNIQUE(size_bau) num_block_align_units);

#endif /* defined HMM_PROCESS */
