Call this V0.7.0
This commit is contained in:
parent
3bcdb74759
commit
83a56a9f18
330
src/inc/x3mem.h~
330
src/inc/x3mem.h~
@ -1,330 +0,0 @@
|
|||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* file information */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
// Filename: x3mem.h
|
|
||||||
// Purpose: Memory management
|
|
||||||
// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2021.
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* header file setup */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#ifndef _X3MEM_H /* skip this file if loaded */
|
|
||||||
#define _X3MEM_H 1 /* flag this file */
|
|
||||||
|
|
||||||
#include "deps.h"
|
|
||||||
#include "eprintf.h"
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* basic definitions */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#ifndef x3u_int
|
|
||||||
#define x3u_int unsigned int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef x3u_long
|
|
||||||
#define x3u_long unsigned long
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef V_OBJ
|
|
||||||
#define V_OBJ void
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* X3MEM package - overview */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* The X3MEM package includes the public functions listed be- */
|
|
||||||
/* low. For more information, see the functions themselves. */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* QLIST support functions: (*) = macro function */
|
|
||||||
|
|
||||||
/* 1. chk_qm0() -- checks a "qmalloc()" storage pointer */
|
|
||||||
/* 2. chk_qma() -- checks an entire QLIST */
|
|
||||||
/* (*) 3. chk_qmp() -- generic version of "chk_qm0()" */
|
|
||||||
/* 4. qcalloc() -- allocates and clears memory */
|
|
||||||
/* 5. qmalloc() -- allocates memory */
|
|
||||||
/* 6. qrealloc() -- re-allocates memory */
|
|
||||||
/* 7. qfree() -- frees allocated memory */
|
|
||||||
/* 8. qflush() -- frees an entire QLIST */
|
|
||||||
/* 9. sys_mem() -- returns amount of free system memory */
|
|
||||||
/* (*) 10. xqfree() -- generic version of "qfree()" */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* Simplified QLIST interface layer: */
|
|
||||||
|
|
||||||
/* 11. sqCalloc() -- similar to "calloc()" */
|
|
||||||
/* 12. sqChkHeap() -- checks the entire "sq..." heap */
|
|
||||||
/* 13. sqChkPtr() -- checks an "sq..." storage pointer */
|
|
||||||
/* 14. sqFlush() -- frees all "sq..." storage */
|
|
||||||
/* 15. sqFree() -- frees one "sq..." storage block */
|
|
||||||
/* 16. sqMalloc() -- similar to "malloc()" */
|
|
||||||
/* 17. sqRealloc() -- similar to "realloc()" */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* QLIST pointers - explanation */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* The X3MEM functions support multiple dynamic-memory allo- */
|
|
||||||
/* cation lists. The "qmalloc()" function, for example, */
|
|
||||||
/* allocates memory from a specified allocation list, and the */
|
|
||||||
/* "qfree()" function returns memory to the associated list. */
|
|
||||||
|
|
||||||
/* Multiple-allocation lists provide greater control over */
|
|
||||||
/* memory allocation; e.g., the caller can free up one list in */
|
|
||||||
/* its entirety without disturbing other lists. */
|
|
||||||
|
|
||||||
/* Additionally, the use of multiple allocation lists can */
|
|
||||||
/* reduce the fragmentation problems which occur on virtual- */
|
|
||||||
/* memory systems when free lists have grown large. */
|
|
||||||
|
|
||||||
/* Allocation lists are specified by QLIST pointers; to create */
|
|
||||||
/* a new allocation list, the user simply defines a new (empty) */
|
|
||||||
/* QLIST structure. */
|
|
||||||
|
|
||||||
/* If a program does not require multiple allocation lists, the */
|
|
||||||
/* predefined general-purpose list "QM_GEN" may be used. */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* QMALLOC structure definitions */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* alignment data type */
|
|
||||||
|
|
||||||
#ifdef QMSA /* stand-alone version */
|
|
||||||
#ifndef DEF_ALIGN /* set default alignment type */
|
|
||||||
#define DEF_ALIGN unsigned int
|
|
||||||
#endif
|
|
||||||
#endif /* endif "QMSA" */
|
|
||||||
|
|
||||||
#ifdef DEF_ALIGN /* is alignment type defined? */
|
|
||||||
typedef DEF_ALIGN QM_ALIGN; /* use specified alignment type */
|
|
||||||
#else /* use default alignment type */
|
|
||||||
typedef long QM_ALIGN; /* "long-integer" alignment */
|
|
||||||
#endif /* endif DEF_ALIGN */
|
|
||||||
|
|
||||||
/* size of an alignment unit */
|
|
||||||
#define QMASIZE (sizeof(QM_ALIGN))
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* "size" data type */
|
|
||||||
|
|
||||||
#define QM_SIZE_T unsigned int
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* QMALLOC memory block header */
|
|
||||||
|
|
||||||
union qm_header
|
|
||||||
{
|
|
||||||
QM_ALIGN qm_d; /* align the block header */
|
|
||||||
|
|
||||||
struct /* begin header proper (qm_h) */
|
|
||||||
{
|
|
||||||
union /* begin multi-use portion */
|
|
||||||
{ /* see explanation below */
|
|
||||||
union qm_header *n0_free;
|
|
||||||
struct qlist *q0_owner;
|
|
||||||
}
|
|
||||||
qm_x; /* end multi-use portion */
|
|
||||||
|
|
||||||
QM_SIZE_T q0_chk; /* consistency-check value */
|
|
||||||
QM_SIZE_T q0_size; /* block size */
|
|
||||||
}
|
|
||||||
qm_h; /* end header proper (qm_h) */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef union qm_header QM_HDR; /* typedef the block header */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* simplify the structure */
|
|
||||||
|
|
||||||
#define nxt_free qm_h.qm_x.n0_free
|
|
||||||
#define qa_size qm_h.q0_size
|
|
||||||
#define qm_chk qm_h.q0_chk
|
|
||||||
#define qm_owner qm_h.qm_x.q0_owner
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* QM_HDR structure */
|
|
||||||
|
|
||||||
/* The "QM_HDR" structure defines a block of dynamic memory. */
|
|
||||||
/* The block is aligned on a "QM_ALIGN" boundary, and begins */
|
|
||||||
/* with a header of type "QM_HDR". The rest of the block is */
|
|
||||||
/* used for storage. */
|
|
||||||
|
|
||||||
/* "qa_size" is the total size of the memory block (including */
|
|
||||||
/* the header itself) in "QM_ALIGN" alignment units (i.e., */
|
|
||||||
/* units of QMASIZE bytes). */
|
|
||||||
|
|
||||||
/* "nxt_free" and "qm_owner" are context-dependent. See the */
|
|
||||||
/* discussion of the QLIST structure below for additional */
|
|
||||||
/* information. */
|
|
||||||
|
|
||||||
/* "qm_chk" is used internally for consistency checking. */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* QLIST structure */
|
|
||||||
|
|
||||||
struct qlist
|
|
||||||
{
|
|
||||||
QM_HDR *qm_free; /* QLIST free list */
|
|
||||||
QM_HDR *qm_sysmem; /* QLIST system-memory list */
|
|
||||||
QM_SIZE_T qm_block; /* allocation blocking factor */
|
|
||||||
char qm_nofree; /* non-freeable flag */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct qlist QLIST; /* typedef the list header */
|
|
||||||
/* null structure pointer */
|
|
||||||
#define NULL_QLS ((QLIST *) ZERO)
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* QLIST free-list */
|
|
||||||
|
|
||||||
/* The "qm_free" field for a QLIST points to a list of free */
|
|
||||||
/* memory blocks associated with the QLIST. Each free block */
|
|
||||||
/* begins with a "QM_HDR" block header. The free blocks are */
|
|
||||||
/* linked together by the "nxt_free" field in the "QM_HDR" */
|
|
||||||
/* header. Blocks are allocated from this list by "qmalloc()" */
|
|
||||||
/* and freed onto the list by "qfree()". */
|
|
||||||
|
|
||||||
/* When "qmalloc()" allocates a block from a free-list, it */
|
|
||||||
/* points the "qm_owner" field in the header to the QLIST from */
|
|
||||||
/* which the block was obtained. "qfree()" uses this field */
|
|
||||||
/* subsequently when the block is freed. */
|
|
||||||
|
|
||||||
/* The memory blocks in the free list are carved out of a */
|
|
||||||
/* lower-level system memory chain, which is discussed in the */
|
|
||||||
/* next section. */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* QLIST system-memory list */
|
|
||||||
|
|
||||||
/* The "qm_sysmem" field for a QLIST points to a list of low- */
|
|
||||||
/* level "system memory" blocks associated with the QLIST. */
|
|
||||||
/* Each system memory block begins with a "QM_HDR" block head- */
|
|
||||||
/* er. The system memory blocks are linked together by the */
|
|
||||||
/* "nxt_free" field in the "QM_HDR" header. */
|
|
||||||
|
|
||||||
/* This linked list contains all of the dynamic storage */
|
|
||||||
/* currently associated with a QLIST (on the "qm_free" free */
|
|
||||||
/* list or not). The blocks in this list are obtained from the */
|
|
||||||
/* operating system. */
|
|
||||||
|
|
||||||
/* "qmalloc()" carves the storage portion of each system memory */
|
|
||||||
/* block up into sub-blocks, writes "QM_HDR" headers onto the */
|
|
||||||
/* sub-blocks, and uses these secondary headers to build */
|
|
||||||
/* higher-level (qm_free) allocation lists. */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* allocation blocking factor */
|
|
||||||
|
|
||||||
/* The "malloc"-based version of "qmalloc()" uses the standard */
|
|
||||||
/* library routine "malloc()" to allocate dynamic memory at the */
|
|
||||||
/* system level. */
|
|
||||||
|
|
||||||
/* The "stand-alone" version of "qmalloc()" uses an internal */
|
|
||||||
/* utility routine to allocate dynamic memory at the system */
|
|
||||||
/* level. */
|
|
||||||
|
|
||||||
/* The "qm_block" field in a QLIST header specifies the minimum */
|
|
||||||
/* amount of memory (in bytes) to be requested for the QLIST */
|
|
||||||
/* per system-level memory allocation call. */
|
|
||||||
|
|
||||||
/* If the "qm_block" field is not set, a reasonable default */
|
|
||||||
/* value is used. */
|
|
||||||
|
|
||||||
/* If the host system has virtual memory, setting "qm_block" */
|
|
||||||
/* as follows may improve performance: */
|
|
||||||
/* */
|
|
||||||
/* qm_block <- system memory page size minus total size of all */
|
|
||||||
/* system-level storage headers. */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* misc. global variables */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* "QM_GEN" is intended for use as a general-purpose QLIST. */
|
|
||||||
|
|
||||||
/* Note: Since "QM_GEN[]" is an array, "QM_GEN" serves both as */
|
|
||||||
/* a QLIST pointer and as the QLIST entry itself. */
|
|
||||||
|
|
||||||
UX3_EXT QLIST QM_GEN [ONE]; /* general-purpose QLIST */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* "qm_retsys" is a flag used by the "qflush()" function. See */
|
|
||||||
/* "qflush()" for additional information. */
|
|
||||||
|
|
||||||
UX3_EXT char qm_retsys; /* "qflush()" flag */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* macro functions */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* "chk_qmp(xp)" checks the pointer "xp" and terminates the */
|
|
||||||
/* caller with an error message if "xp" is not a valid */
|
|
||||||
/* "qmalloc()" storage pointer. "xp" may be a pointer of any */
|
|
||||||
/* type; "chk_qmp()" typecasts the pointer appropriately. */
|
|
||||||
|
|
||||||
/* Note: A valid storage pointer becomes invalid if the */
|
|
||||||
/* associated storage is freed. */
|
|
||||||
|
|
||||||
/* "chk_qmp()" is a macro interface to the function "chk_ */
|
|
||||||
/* qm0()". See the description of "chk_qm0()" for additional */
|
|
||||||
/* information. */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#define chk_qmp(xp) chk_qm0 ((V_OBJ *) (xp))
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* The macro function "xqfree()" is equivalent to the non-macro */
|
|
||||||
/* function "qfree()", with the distinction that "xqfree()" */
|
|
||||||
/* typecasts its argument appropriately. See the description */
|
|
||||||
/* of "qfree()" for additional information. */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#define xqfree(p) qfree ((V_OBJ *) (p))
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* X3MEM function prototypes */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
V_PROTO chk_qm0 (argp1 (V_OBJ *));
|
|
||||||
V_PROTO chk_qma (argp1 (QLIST *));
|
|
||||||
V_OBJ *qcalloc (argp3 (QLIST *,x3u_int,x3u_int));
|
|
||||||
V_PROTO qflush (argp1 (QLIST *));
|
|
||||||
V_PROTO qfree (argp1 (V_OBJ *));
|
|
||||||
V_OBJ *qmalloc (argp2 (QLIST *,int));
|
|
||||||
V_OBJ *qrealloc (argp2 (V_OBJ *,int));
|
|
||||||
long sys_mem (argp0 ());
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
V_OBJ *sqCalloc (argp2 (x3u_int, x3u_int));
|
|
||||||
V_PROTO sqChkHeap (argp0 ());
|
|
||||||
V_PROTO sqChkPtr (argp2 (V_OBJ *, char *));
|
|
||||||
V_PROTO sqFlush (argp0 ());
|
|
||||||
V_PROTO sqFree (argp1 (V_OBJ *));
|
|
||||||
V_OBJ *sqMalloc (argp1 (x3u_int));
|
|
||||||
V_OBJ *sqRealloc (argp2 (V_OBJ *, x3u_int));
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/* wrap it up */
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#endif /* endif _X3MEM_H */
|
|
Loading…
x
Reference in New Issue
Block a user