/************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-v10.html * * Contributors: Details at https://graphviz.org *************************************************************************/ #include #include #include typedef struct freenode { struct freenode *nextfree; } Freenode; typedef struct freeblock { struct freeblock *next; struct freenode *nodes; } Freeblock; #include #include #include static int gcd(int y, int x) { while (x != y) { if (y < x) x = x - y; else y = y - x; } return x; } #define LCM(x,y) ((x)%(y) == 0 ? (x) : (y)%(x) == 0 ? (y) : x*(y/gcd(x,y))) void freeinit(Freelist * fl, int size) { fl->head = NULL; fl->nodesize = LCM(size, sizeof(Freenode)); if (fl->blocklist != NULL) { Freeblock *bp, *np; bp = fl->blocklist; while (bp != NULL) { np = bp->next; free(bp->nodes); free(bp); bp = np; } } fl->blocklist = NULL; } void *getfree(Freelist * fl) { int i; Freenode *t; if (fl->head == NULL) { int size = fl->nodesize; char *cp; Freeblock *mem = gv_alloc(sizeof(Freeblock)); mem->nodes = gv_calloc(sqrt_nsites, size); cp = (char *) (mem->nodes); for (i = 0; i < sqrt_nsites; i++) { makefree(cp + i * size, fl); } mem->next = fl->blocklist; fl->blocklist = mem; } t = fl->head; fl->head = t->nextfree; return t; } void makefree(void *curr, Freelist * fl) { ((Freenode *) curr)->nextfree = fl->head; fl->head = curr; }