--- al.c 2002/10/14 08:04:46 1.1
+++ al.c 2002/10/14 09:17:21 1.2
@@ -102,9 +102,19 @@
#define AL_RC(rv) (rv)
#endif /* WITH_EX */
+typedef struct {
+ void *(*malloc)(size_t);
+ void (*free)(void *);
+ void *(*balloc)(size_t);
+ void (*bfree)(void *);
+ size_t new_buffersize;
+ int max_freechunks;
+} al_memops_t;
+
struct al_st {
LIST(al_chunk_t) chunks;
size_t bytes;
+ al_memops_t m;
};
struct al_chunk_st {
@@ -161,24 +171,21 @@
#define AL_PRESIZE(al, alc, n) \
do { (alc)->begin -= n; (al)->bytes += (n); } while (0)
-#define AL_NEW_BUFFERSIZE 100
-#define AL_MAX_FREECHUNKS 500
-
/*
* allocate backing store and its control structure from heap
* can be freed when usecount drops to zero
*/
static
-al_rc_t new_buffer(al_buffer_t **bufp)
+al_rc_t new_buffer(al_t *al, al_buffer_t **bufp)
{
- size_t n = AL_NEW_BUFFERSIZE;
+ size_t n = al->m.new_buffersize;
al_buffer_t *buf;
- if ((buf = (al_buffer_t *)malloc(sizeof(al_buffer_t))) == NULL)
+ if ((buf = (al_buffer_t *)(al->m.malloc)(sizeof(al_buffer_t))) == NULL)
return AL_ERR_MEM;
- if ((buf->mem = malloc(n)) == NULL) {
- free(buf);
+ if ((buf->mem = (al->m.balloc)(n)) == NULL) {
+ (al->m.free)(buf);
return AL_ERR_MEM;
}
@@ -191,16 +198,16 @@
}
static
-al_rc_t dispose_buffer(al_buffer_t *buf)
+al_rc_t dispose_buffer(al_t *al, al_buffer_t *buf)
{
/* must not happen */
if (buf->usecount != 0)
return AL_ERR_INT;
if (buf->freemem)
- free(buf->mem);
+ (al->m.bfree)(buf->mem);
- free(buf);
+ (al->m.free)(buf);
return AL_OK;
}
@@ -210,11 +217,11 @@
* only the control structure will be freed later
*/
static
-al_rc_t make_buffer(char *p, size_t n, al_buffer_t **bufp)
+al_rc_t make_buffer(al_t *al, char *p, size_t n, al_buffer_t **bufp)
{
al_buffer_t *buf;
- if ((buf = (al_buffer_t *)malloc(sizeof(al_buffer_t))) == NULL)
+ if ((buf = (al_buffer_t *)(al->m.malloc)(sizeof(al_buffer_t))) == NULL)
return AL_ERR_MEM;
buf->mem = p;
@@ -244,14 +251,14 @@
int alc_freecount = 0;
static
-al_rc_t new_chunk(al_buffer_t *buf, al_chunk_t **alcp)
+al_rc_t new_chunk(al_t *al, al_buffer_t *buf, al_chunk_t **alcp)
{
al_chunk_t *alc;
if (ISEMPTY(&alc_freelist, chunks)) {
- if ((alc = (al_chunk_t *)malloc(sizeof(al_chunk_t))) == NULL) {
+ if ((alc = (al_chunk_t *)(al->m.malloc)(sizeof(al_chunk_t))) == NULL) {
if (buf->usecount == 0)
- dispose_buffer(buf);
+ dispose_buffer(al,buf);
return AL_ERR_MEM;
}
} else {
@@ -271,16 +278,16 @@
}
static
-void dispose_chunk(al_chunk_t *alc)
+void dispose_chunk(al_t *al, al_chunk_t *alc)
{
--alc->buf->usecount;
if (alc->buf->usecount == 0)
- dispose_buffer(alc->buf);
+ dispose_buffer(al,alc->buf);
alc->buf = NULL;
/* stop freelist from growing infinitely */
- if (alc_freecount >= AL_MAX_FREECHUNKS) {
- free(alc);
+ if (alc_freecount >= al->m.max_freechunks) {
+ (al->m.free)(alc);
} else {
ADDTAIL(&alc_freelist, chunks, alc);
++alc_freecount;
@@ -366,12 +373,21 @@
return AL_RC(AL_ERR_ARG);
/* allocate and initialize new assembly line object */
+ /* XXX - what malloc ? */
if ((al = (al_t *)malloc(sizeof(al_t))) == NULL)
return AL_RC(AL_ERR_MEM);
LISTINIT(al,chunks);
al->bytes = 0;
+ /* memory policy */
+ al->m.malloc = malloc; /* structure allocation */
+ al->m.free = free;
+ al->m.balloc = malloc; /* buffer allocation */
+ al->m.bfree = free;
+ al->m.new_buffersize = 4096;
+ al->m.max_freechunks = 500;
+
/* pass object to caller */
*alp = al;
@@ -388,10 +404,11 @@
/* free chunks and backing store */
FOREACHD(al,chunks,cur,pred) {
- dispose_chunk(cur);
+ dispose_chunk(al,cur);
}
/* free object itself */
+ /* XXX - which free() ? */
free(al);
return AL_OK;
@@ -410,9 +427,9 @@
while (n > 0) {
if (res == 0) {
- rc = new_buffer(&buf);
+ rc = new_buffer(al, &buf);
/* XXX handle error */
- rc = new_chunk(buf,&cur);
+ rc = new_chunk(al,buf,&cur);
/* XXX handle error */
res = AL_CHUNK_RESERVE(cur);
ADDTAIL(al, chunks, cur);
@@ -448,9 +465,9 @@
while (n > 0) {
if (res == 0) {
- rc = new_buffer(&buf);
+ rc = new_buffer(al, &buf);
if (rc != AL_OK) return rc;
- rc = new_chunk(buf,&cur);
+ rc = new_chunk(al,buf,&cur);
if (rc != AL_OK) return rc;
res = AL_CHUNK_PRESERVE(cur);
ADDHEAD(al, chunks, cur);
@@ -477,9 +494,9 @@
al_buffer_t *buf;
al_chunk_t *cur;
- rc = make_buffer(p, n, &buf);
+ rc = make_buffer(al, p, n, &buf);
if (rc != AL_OK) return rc;
- rc = new_chunk(buf, &cur);
+ rc = new_chunk(al,buf, &cur);
if (rc != AL_OK) return rc;
ADDTAIL(al, chunks, cur);
@@ -538,7 +555,7 @@
ADDTAIL(tal, chunks, cur);
tal->bytes += step;
} else {
- dispose_chunk(cur);
+ dispose_chunk(al,cur);
}
}
n -= step;
|