/* * Copyright (C) 1996-2017 Edward F. Valeev and Justin T. Fermann * * This file is part of Libint. * * Libint is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Libint is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Libint. If not, see . * */ #include #include #include #include #define MAXALLOC 10000 int free_block[MAXALLOC]; /* Marks of free-occupied blocks */ int block_length[MAXALLOC]; /* Keeps sizes of all blocks */ int last_free; /* Number of the last free block */ int max_mem; /* Amount of memory used by classes up to this point */ int mem_top; /* Total memory allocated up to this point */ /* initialize memory stack */ void init_mem(int memory) { last_free = 1; memset(free_block,0,MAXALLOC*sizeof(int)); /* All blocks are free */ memset(block_length,0,MAXALLOC*sizeof(int)); /* All of them are zero in length ... */ block_length[0] = memory; /* except for the first one */ max_mem = 0; mem_top = memory; } /* add memory */ void add_mem(int memory) { int i; int addto = 0; int himem = 0; mem_top += memory; /* Find the last free block and add all this memory to it */ for(i=0; i himem){ himem = free_block[i]; addto = i; } } #if 0 printf("adding %d to memory\n\tnew top = %d\n", memory, free_block[addto]+block_length[addto]+memory); #endif block_length[addto] = block_length[addto]+memory; } /* Find a block of the requested size */ int get_mem(int size) { int i, j; /* try to find one that fits exactly */ for(i=last_free-1; i>=0; i--){ if(block_length[i] == size){ j = free_block[i]; if(free_block[i]+block_length[i]==mem_top) add_mem(500); use(i, size); return j; } } /* ok, try to find a bigger one that will work */ for(i=last_free-1; i>=0; i--){ if(block_length[i] > size){ j = free_block[i]; use(i, size); return j; } } /* last resort, expand memory */ add_mem(1000); return get_mem(size); } void use(int n, int s) { int i; #if 0 printf("issuing %d doubles starting at %d out of free block %d\n", s, free_block[n], n); printf("last_free = %d\n", last_free); #endif if(s==block_length[n]){ for(i=n; imax_mem) max_mem = free_block[n]; } else exit(1); } void free_mem(int n, int size) { int i, j; free_block[last_free] = n; block_length[last_free] = size; last_free++; consolidate(); } void consolidate() { int i, j; int right_bound_i; int done = 1; do { done = 1; for(i=0; i