blob: bb4dcb842d35aac3ea0544bbbe89d59fd9625a46 [file] [log] [blame]
/* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
--------------------------------------------------------------------
By Bob Jenkins, September 1996. recycle.c
You may use this code in any way you wish, and it is free. No warranty.
This manages memory for commonly-allocated structures.
It allocates RESTART to REMAX items at a time.
Timings have shown that, if malloc is used for every new structure,
malloc will consume about 90% of the time in a program.
This module cuts down the number of mallocs by an order of magnitude.
This also decreases memory fragmentation, and freeing structures
only requires freeing the root.
--------------------------------------------------------------------
*/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jenkstd.h"
#include "jenkrecy.h"
reroot *remkroot(size_t size)
{
reroot *r = (reroot*) remalloc(sizeof(reroot), "recycle.c, root");
r->list = (recycle*)0;
r->trash = (recycle*)0;
r->size = align(size);
r->logsize = RESTART;
r->numleft = 0;
return r;
}
void refree(struct reroot *r)
{
recycle *temp;
if (temp = r->list) while (r->list)
{
temp = r->list->next;
free((char *)r->list);
r->list = temp;
}
free((char *)r);
return;
}
/* to be called from the macro renew only */
char *renewx(struct reroot *r)
{
recycle *temp;
if (r->trash)
{ /* pull a node off the trash heap */
temp = r->trash;
r->trash = temp->next;
(void)memset((void *)temp, 0, r->size);
}
else
{ /* allocate a new block of nodes */
r->numleft = (int) r->size*((ub4)1<<r->logsize);
if (r->numleft < REMAX) ++r->logsize;
temp = (recycle *)remalloc(sizeof(recycle) + r->numleft,
"recycle.c, data");
temp->next = r->list;
r->list = temp;
r->numleft -= (int) r->size;
temp = (recycle *)((char *)(r->list+1)+r->numleft);
}
return (char *)temp;
}
char *remalloc(size_t len, char* purpose)
{
char *x = (char*) malloc(len);
if (!x)
{
fprintf(stderr, "malloc %lu failed for %s\n", (unsigned long)len, purpose);
exit(SUCCESS);
}
return x;
}