quakeforge/tools/qfcc/include/defspace.h
2012-12-02 22:04:54 +09:00

138 lines
4.8 KiB
C

/*
defspace.h
management of data segments
Copyright (C) 2011 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2011/01/16
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __defspace_h
#define __defspace_h
#include "QF/pr_comp.h"
#include "QF/pr_debug.h"
/** \defgroup qfcc_defspace Defspace handling
\ingroup qfcc
*/
//@{
/** Represent a block of memory in the progs data space.
*/
typedef struct defspace_s {
struct defspace_s *next; ///< for ALLOC
struct locref_s *free_locs; ///< list of free blocks in this space
struct def_s *defs; ///< list of defs using this space
struct def_s **def_tail; ///< for appending to \a defs
pr_type_t *data; ///< backing memory for this space
int size; ///< current high-water mark for alloced data
int max_size; ///< size of backing memory
/** Grow the backing memory of the defspace.
This function is called when more memory is needed for the space.
The default \a grow function expands the backing memory by 1024
pr_type_t words and initializes them to 0. If null, more space cannot
be allocated and an internal error will be generated.
\param space This defspace.
\return 1 for success, 0 for failure.
\bug The return value is ignored.
*/
int (*grow) (struct defspace_s *space);
int qfo_space; ///< index to space in qfo spaces
} defspace_t;
/** Create an empty defspace.
No backing memory is allocated, but the defspace_t::grow function is
initialized to the default grow function so the backing memory may be
accessed after space has been allocated via defspace_alloc_loc().
\return The new, empty defspace.
*/
defspace_t *defspace_new (void);
/** Allocate space from the defspace's backing memory.
If the memory is fragmented, then the first available location at least
as large as \a size is returned. This means that freeing a location then
allocating the same amount of space may return a different location.
If memory cannot be allocated (there is no free space in the currently
available memory and defspace_t::grow is null), then an internal error
will be generated.
\param space The space from which to allocate data.
\param size The amount of pr_type_t words to allocated. int and float
need 1 word, vector 3 words, and quaternion 4.
\return The offset of the first word of the freshly allocated
space. May be 0 if the allocated space is at the beginning
of the defspace.
\bug does not check for allocating 0 (or negative) words.
*/
int defspace_alloc_loc (defspace_t *space, int size);
/** Free a block of contiguous words, returning them to the defspace.
The block to be freed is specified by \a ofs indicating the offset of the
first word of the block and \a size indicating the number of words in the
block.
If the block to be freed has 0 words, or if the is partly or fully outside
the defspace (as defined by defspace_t::size), or if the block overlaps
any unallocated space in the defspace, then an internal error will be
generated. However, it is perfectly valid to allocate a large block and
subsequently free a small block from anywhere within the larger block.
This is because when memory is not fragmented, there is no difference
between allocating one large block and allocating several smaller blocks
when allocating the same amount of memory.
\param space The space to which the freed block will be returned.
\param ofs The first word of the block to be freed.
\param size The number of words in the block to be freed.
\bug \a size is not checked for being negative.
*/
void defspace_free_loc (defspace_t *space, int ofs, int size);
/** Copy a block of data into a defspace.
Space for the data is allocated from the defspace via
defspace_alloc_loc().
If \a data is null, then the copying stage is skipped and this function
because a synonym for defspace_alloc_loc().
\param space The space to which the data will be added.
\param data The data to be copied into the space.
\param size The number of words of data to be copied.
\return The offset of the block allocated for the data.
*/
int defspace_add_data (defspace_t *space, pr_type_t *data, int size);
//@}
#endif//__defspace_h