/***************************************************************************
 * 
 * Copyright (c) 1999 Geodesic Systems, Inc.  All rights reserved.
 *
 ***************************************************************************
 */

#ifdef __cplusplus
extern "C" {
#endif

extern void mts_init_thread_heaps(
#ifdef __cplusplus
  int number_of_heaps
#endif
  );
extern void mts_set_sys_alloc_size( 
#ifdef __cplusplus
  long min_size, long max_size, int reset 
#endif
  );
extern void mts_set_spin_count(
#ifdef __cplusplus
  int spin_count
#endif
  );
extern int mts_which_heap();
extern unsigned long mts_heap_size();
extern unsigned long mts_heap_total_size();
unsigned long mts_alloc_count_current_heap();
unsigned long mts_alloc_count_all_heaps();
unsigned long mts_heap_start_current_heap();
unsigned long mts_heap_start_all_heaps();
unsigned long mts_heap_end_current_heap();
unsigned long mts_heap_end_all_heaps();
void mts_enable_shared_memory();
int mts_set_min_large_size(
#ifdef __cplusplus
  int min
#endif
);
extern int mts_set_df_size(
#ifdef __cplusplus
  int size
#endif
);

#ifdef __cplusplus
}
#endif

/****************************************************************************
MTS Pools Interface

void * (MTSMemHandler *)(void)

Calls that fail to allocate memory will call the function contained in this 
pointer.  If the pointer is NULL, then no call is made. The initial value will 
depend on a configuration variable in mts_config.h.

enum MTSstatus { MTSerror, MTSok };

Some of the calls return a status. The number of different status codes will 
likely change over time to allow greater precision in error reporting.

MTSPool *MTSPoolCreate(void)

This creates a memory pool.  We do not expect to know how large the pool is or 
the way it will be used.  Pools will reconfigure themselves as they grow and 
shrink. If the pool cannot be allocated, a NULL is returned.

MTSstatus MTSPoolDestroy(MTSPool*);

Delete a pool and free its resources. Further use of the Pool pointer in MTS 
calls is illegal.  MTSPoolFreeAll is implicitly called before the pool is 
destroyed. If the Pool pointer is illegal, it may or may not be detected in 
the optimized version of the library. 
The debug version of the library will catch an illegal pool pointer.

MTSstatus MTSPoolFreeAll(MTSPool *)

Free all the memory associated with the pool. If the argument is invalid, MTS 
returns MTSerror. In the optimized version of the library, an illegal Pool 
pointer may or may not be detected. 

size_t MTSPoolTotalSize(MTSPool *)

Return the current amount of memory allocated in the size of the memory pool. 
If the pool pointer is invalid, 0 is returned. 

Note: Pools can grow to the available size of memory allowed by a process. 
Therefore there is no notion of "available size" of a pool.

void *MTSPoolAlloc(MTSPool *, size_t, bool)

Return a block of memory in the pool with the given size.  If the third 
parameter is true, this memory is guaranteed to be set to be all 0's 
initially. If memory cannot be allocated, NULL is returned and the contents of 
MTSMemHandler is called (which must be a pointer to a void returning, void 
argument function). If MTSMemHandler is not set, the routine simply returns 
NULL. A size of 0 will cause the minimum size block to be returned.

void *MTSPoolRealloc(MTSPool *, void *, size_t, bool)

Reallocate a block of memory in a pool.  The block is extended (or reduced) in 
place if possible. Otherwise new memory is allocated from within the pool and 
the memory pointed to by the second parameter is copied to this new area. If 
the last parameter is true, the memory is effectively set to 0's before the 
copy is made (this clearly has no effect when reallocating smaller pieces). As 
above, if the reallocation cannot be done, NULL is returned and the contents 
of MTSMemHandler is called if set.

MTSstatus MTSPoolFree(void *)

Free the block given. If the pointer is invalid, return error.  Note that the 
pool is not given in this call; it is determined by the pointer. If a pool 
cannot be established for the pointer, MTSerror is returned. The contents of 
the memory may be immediately overwritten by the system; this is the current 
behavior of MTS.
 
size_t MTSPoolSize(void *)

Return the size of the memory block given as the parameter.  If the pointer is 
determined to be invalid then return 0. 

MTSPool *MTSPoolGet(void *)

The pool associated with a given piece of memory is returned. If the memory 
does not belong to a pool, NULL is returned.

Notes
In order to ensure the same levels of performance in this release of MTS as 
previous releases, the standard allocator is going to be largely unchanged. 
This prevents default pools from being associated with malloc/calloc.  It is 
probably advisable to make all of your memory allocations through pools and 
create default pools on your own.
It is unnecessary to specify pool page size or expected object size with 
pools; they will "self-adjust" to be as optimal as possible given the 
distribution of object sizes requested from the pool.

***************************************************************************/

typedef enum MTSstatus { MTSerror, MTSok } MTSstatus;
typedef struct mts_page_pool MTSPool;

#ifdef __cplusplus
extern "C" {
char (*MTSMemHandler)		();
MTSPool *MTSPoolCreate		();
MTSstatus MTSPoolDestroy	(MTSPool*);
MTSstatus MTSPoolFreeAll	(MTSPool*);
size_t	 MTSPoolTotalSize	(MTSPool*);
void *MTSPoolAlloc		(MTSPool*, size_t, int);
void *MTSPoolRealloc		(MTSPool*, void *, size_t, int);
MTSstatus MTSPoolFree		(MTSPool*, void*);
unsigned int MTSPoolSize	(void*);
MTSPool *MTSPoolGet		(void*);
}
#else
char (*MTSMemHandler)		();
MTSPool *MTSPoolCreate		();
MTSstatus MTSPoolDestroy	();
MTSstatus MTSPoolFreeAll	();
size_t MTSPoolTotalSize	();
void *MTSPoolAlloc		();
void *MTSPoolRealloc		();
MTSstatus MTSPoolFree		();
size_t MTSPoolSize		();
MTSPool *MTSPoolGet		();
#endif
