| /* |
| * Copyright (C) 2011 UChicago Argonne, LLC |
| * All Rights Reserved |
| * |
| * Permission to use, reproduce, prepare derivative works, and to redistribute |
| * to others this software, derivatives of this software, and future versions |
| * of this software as well as its documentation is hereby granted, provided |
| * that this notice is retained thereon and on all copies or modifications. |
| * This permission is perpetual, world-wide, and provided on a royalty-free |
| * basis. UChicago Argonne, LLC and all other contributors make no |
| * representations as to the suitability and operability of this software for |
| * any purpose. It is provided "as is" without express or implied warranty. |
| * |
| * Portions of this software are copyright by UChicago Argonne, LLC. Argonne |
| * National Laboratory with facilities in the state of Illinois, is owned by |
| * The United States Government, and operated by UChicago Argonne, LLC under |
| * provision of a contract with the Department of Energy. |
| * |
| * PORTIONS OF THIS SOFTWARE WERE PREPARED AS AN ACCOUNT OF WORK SPONSORED BY |
| * AN AGENCY OF THE UNITED STATES GOVERNMENT. NEITHER THE UNITED STATES |
| * GOVERNMENT NOR ANY AGENCY THEREOF, NOR THE UNIVERSITY OF CHICAGO, NOR ANY OF |
| * THEIR EMPLOYEES OR OFFICERS, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR |
| * ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, |
| * COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR |
| * PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY |
| * OWNED RIGHTS. REFERENCE HEREIN TO ANY SPECIFIC COMMERCIAL PRODUCT, PROCESS, |
| * OR SERVICE BY TRADE NAME, TRADEMARK, MANUFACTURER, OR OTHERWISE, DOES NOT |
| * NECESSARILY CONSTITUTE OR IMPLY ITS ENDORSEMENT, RECOMMENDATION, OR FAVORING |
| * BY THE UNITED STATES GOVERNMENT OR ANY AGENCY THEREOF. THE VIEW AND OPINIONS |
| * OF AUTHORS EXPRESSED HEREIN DO NOT NECESSARILY STATE OR REFLECT THOSE OF THE |
| * UNITED STATES GOVERNMENT OR ANY AGENCY THEREOF. |
| * |
| * Author: Hal Finkel <hfinkel@anl.gov> |
| */ |
| |
| #include "bigchunk.h" |
| #include <stdio.h> |
| |
| static void *_bigchunk_ptr = (void *) 0; |
| static size_t _bigchunk_last_alloc = (size_t) -1; |
| static size_t _bigchunk_sz = 0; |
| static size_t _bigchunk_used = 0; |
| static size_t _bigchunk_total = 0; |
| static const size_t min_alloc = 32; /* for alignment; must be 2^n */ |
| |
| void *bigchunk_malloc(size_t sz) |
| { |
| if (sz < min_alloc) |
| sz = min_alloc; |
| else { |
| size_t e = sz - (sz & ~(min_alloc-1)); |
| if (e != 0) sz += min_alloc - e; |
| } |
| |
| if (_bigchunk_sz - _bigchunk_used >= sz) { |
| /* this fits in the big chunk */ |
| void *r = (char *)_bigchunk_ptr + _bigchunk_used; |
| _bigchunk_last_alloc = _bigchunk_used; |
| _bigchunk_used += sz; |
| _bigchunk_total += sz; |
| return r; |
| } else if (_bigchunk_used == 0 && _bigchunk_sz > 0) { |
| /* this is smaller than the big chunk, but nothing |
| is currently using the big chunk, so just make |
| the big chunk bigger. |
| */ |
| |
| void *new_chuck = realloc(_bigchunk_ptr, sz); |
| if (new_chuck) { |
| _bigchunk_ptr = new_chuck; |
| _bigchunk_last_alloc = 0; |
| _bigchunk_sz = sz; |
| _bigchunk_used = sz; |
| _bigchunk_total += sz; |
| return _bigchunk_ptr; |
| } |
| } |
| |
| void *ptr = malloc(sz); |
| if (ptr) _bigchunk_total += sz; |
| return ptr; |
| } |
| |
| void bigchunk_free(void *ptr) |
| { |
| if (ptr < _bigchunk_ptr || ptr >= (char *)_bigchunk_ptr + _bigchunk_sz) { |
| free(ptr); |
| } else if (_bigchunk_last_alloc != (size_t) -1 && |
| ptr == (char *)_bigchunk_ptr + _bigchunk_last_alloc) { |
| /* this is the last allocation, so we can undo that easily... */ |
| _bigchunk_used = _bigchunk_last_alloc; |
| _bigchunk_last_alloc = (size_t) -1; |
| } |
| } |
| |
| void bigchunk_reset() |
| { |
| _bigchunk_used = 0; |
| _bigchunk_total = 0; |
| _bigchunk_last_alloc = (size_t) -1; |
| } |
| |
| void bigchunk_init(size_t sz) |
| { |
| _bigchunk_ptr = malloc(sz); |
| if (_bigchunk_ptr) { |
| _bigchunk_sz = sz; |
| _bigchunk_used = 0; |
| _bigchunk_last_alloc = (size_t) -1; |
| } |
| } |
| |
| void bigchunk_cleanup() |
| { |
| free(_bigchunk_ptr); |
| _bigchunk_ptr = 0; |
| _bigchunk_sz = 0; |
| _bigchunk_used = 0; |
| _bigchunk_total = 0; |
| _bigchunk_last_alloc = (size_t) -1; |
| } |
| |
| size_t bigchunk_get_size() |
| { |
| return _bigchunk_sz; |
| } |
| |
| |
| size_t bigchunk_get_total() |
| { |
| return _bigchunk_total; |
| } |
| |