| /* $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 %d failed for %s\n", len, purpose); | |
| exit(SUCCESS); | |
| } | |
| return x; | |
| } | |