├── AUTHORS ├── COPYING ├── Makefile ├── NOTES ├── README.md ├── examples ├── .mylog.swp ├── Makefile ├── falsesharing.cpp ├── memtest │ ├── Makefile │ ├── memt.h │ └── thread_memtest.c └── run.sh ├── heaplayers ├── adapt.h ├── adaptheap.h ├── addheap.h ├── ansiwrapper.h ├── bins.h ├── bins16k.h ├── bins4k.h ├── bins64k.h ├── bins8k.h ├── boundedfreelistheap.h ├── checkheap.h ├── chunkheap.h ├── coalesceableheap.h ├── coalesceheap.h ├── debugheap.h ├── dlheap.h ├── exceptionheap.h ├── experimental │ ├── alignedchunk.h │ ├── aoffheap.h │ ├── batchheap.h │ ├── bigchunk.h │ ├── binheap.h │ ├── cacheheap.h │ ├── cartesianheap.h │ ├── chunk.h │ ├── combineheap.h │ ├── counteddictionary.h │ ├── emptychunkheap.h │ ├── fifofreelist.h │ ├── kingsmodheap.h │ ├── lazyheap.h │ ├── lazyslotheap.h │ ├── looseslotheap.h │ ├── multiheap.h │ ├── multimalloc.h │ ├── objectmanager.h │ ├── pad.h │ ├── prefetchheap.h │ ├── scalableleaheap.h │ ├── seg.h │ ├── sizethreadheap.h │ ├── slotheap.h │ ├── splitheap.h │ ├── strictslotheap.h │ ├── testcoalesceableheap.h │ ├── theap.h │ ├── thinlock.h │ ├── topslotheap.h │ └── treap.h ├── fifodlfreelist.h ├── fifofreelist.h ├── firstfitheap.h ├── fixedsizeheap.h ├── freelistheap.h ├── freesllist.h ├── gnuwrapper.cpp ├── heaplayers.h ├── hldefines.h ├── hybridheap.h ├── kingsleyheap.h ├── leamallocheap.h ├── localmallocheap.h ├── lockedheap.h ├── logheap.h ├── mallocheap.h ├── mmapheap.h ├── mmapwrapper.h ├── nestedheap.h ├── nullheap.h ├── obstack.h ├── obstackheap.h ├── obstackreap.h ├── oneheap.h ├── padheap.h ├── perclassheap.h ├── phothreadheap.h ├── profileheap.h ├── sanitycheckheap.h ├── sbrk.c ├── sbrkheap.h ├── segheap.h ├── sizeheap.h ├── sizeownerheap.h ├── sizethreadheap.h ├── slopheap.h ├── spinlock.h ├── staticheap.h ├── stats.cpp ├── stats.h ├── stlallocator.h ├── threadheap.h ├── threadspecificheap.h ├── traceheap.h ├── tryheap.h ├── unique.h ├── util │ ├── bitindex.cpp │ ├── bitindex.h │ ├── bitstring.h │ ├── blockinglock.h │ ├── cpuinfo.h │ ├── dllist.h │ ├── dynarray.h │ ├── fred.h │ ├── guard.h │ ├── hash.h │ ├── myhashmap.h │ ├── posixlock.h │ ├── recursivelock.h │ ├── sassert.h │ ├── sllist.h │ ├── sparc-interchange.il │ ├── timer.h │ ├── winlock.h │ ├── x86-interchange.il │ └── x86_64-interchange.il ├── utility.h ├── wrapper.cpp ├── xallocHeap.h └── zoneheap.h ├── include ├── detect │ ├── callsite.h │ ├── objectinfo.h │ ├── stats.h │ ├── wordchangeinfo.h │ ├── xheapcleanup.h │ └── xtracker.h ├── heap │ ├── internalheap.h │ ├── privateheap.h │ ├── sourcesharedheap.h │ ├── warpheap.h │ ├── xadaptheap.h │ ├── xheap.h │ └── xoneheap.h ├── objectheader.h ├── objecttable.h ├── realfuncs.h ├── sync │ ├── xplock.h │ └── xsync.h ├── util │ ├── atomic.h │ ├── elfinfo.h │ ├── finetime.h │ └── mm.h ├── xdefines.h ├── xglobals.h ├── xmemory.h ├── xmemory_opt.h ├── xpageentry.h ├── xpageinfo.h ├── xpageprof.h ├── xpagestore.h ├── xpersist.h ├── xpersist_opt.h ├── xrun.h └── xthread.h ├── sheriff-oopsla2011.pdf └── source ├── dlmalloc.c ├── finetime.c ├── gnuwrapper.cpp ├── libsheriff.cpp ├── realfuncs.cpp └── xthread.cpp /AUTHORS: -------------------------------------------------------------------------------- 1 | Tongping Liu http://www.cs.umass.edu/~tonyliu 2 | Emery Berger http://www.cs.umass.edu/~emery 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCE_DIR = source 2 | INCLUDE_DIR = include 3 | 4 | SRCS = $(SOURCE_DIR)/libsheriff.cpp \ 5 | $(SOURCE_DIR)/realfuncs.cpp \ 6 | $(SOURCE_DIR)/xthread.cpp \ 7 | $(SOURCE_DIR)/dlmalloc.c \ 8 | $(SOURCE_DIR)/finetime.c \ 9 | $(SOURCE_DIR)/gnuwrapper.cpp 10 | 11 | INCS = $(INCLUDE_DIR)/xglobals.h \ 12 | $(INCLUDE_DIR)/xdefines.h \ 13 | $(INCLUDE_DIR)/xpersist.h \ 14 | $(INCLUDE_DIR)/xmemory.h \ 15 | $(INCLUDE_DIR)/xpersist_opt.h \ 16 | $(INCLUDE_DIR)/xmemory_opt.h \ 17 | $(INCLUDE_DIR)/xpageinfo.h \ 18 | $(INCLUDE_DIR)/xpageprof.h \ 19 | $(INCLUDE_DIR)/xpagestore.h \ 20 | $(INCLUDE_DIR)/xrun.h \ 21 | $(INCLUDE_DIR)/objectheader.h \ 22 | $(INCLUDE_DIR)/objecttable.h \ 23 | $(INCLUDE_DIR)/realfuncs.h \ 24 | $(INCLUDE_DIR)/detect/stats.h \ 25 | $(INCLUDE_DIR)/detect/xheapcleanup.h \ 26 | $(INCLUDE_DIR)/detect/callsite.h \ 27 | $(INCLUDE_DIR)/detect/xtracker.h \ 28 | $(INCLUDE_DIR)/heap/xadaptheap.h \ 29 | $(INCLUDE_DIR)/heap/xoneheap.h \ 30 | $(INCLUDE_DIR)/heap/warpheap.h \ 31 | $(INCLUDE_DIR)/heap/internalheap.h \ 32 | $(INCLUDE_DIR)/heap/privateheap.h \ 33 | $(INCLUDE_DIR)/heap/sourcesharedheap.h \ 34 | $(INCLUDE_DIR)/sync/xplock.h \ 35 | $(INCLUDE_DIR)/sync/xsync.h \ 36 | $(INCLUDE_DIR)/util/atomic.h \ 37 | $(INCLUDE_DIR)/util/elfinfo.h \ 38 | $(INCLUDE_DIR)/util/finetime.h \ 39 | $(INCLUDE_DIR)/util/mm.h 40 | 41 | DEPS = $(SRCS) $(INCS) 42 | 43 | CXX = g++ -g -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/detect -I$(INCLUDE_DIR)/heap -I$(INCLUDE_DIR)/util -I$(INCLUDE_DIR)/sync 44 | 45 | # Detection on 32bit 46 | # CXX = g++ -DSSE_SUPPORT -m32 -DX86_32BIT -O3 -fno-omit-frame-pointer -DDETECT_FALSE_SHARING 47 | # Detection on 64bit 48 | #CXX = g++ -DSSE_SUPPORT -m64 -fno-omit-frame-pointer -DDETECT_FALSE_SHARING 49 | 50 | 51 | # -march=core2 -msse3 -DSSE_SUPPORT 52 | #CFLAGS = -Wall -msse3 -DSSE_SUPPORT -fno-omit-frame-pointer 53 | CFLAGS = -msse3 -DSSE_SUPPORT -fno-omit-frame-pointer 54 | CFLAGS32 = $(CFLAGS) -m32 -DX86_32BIT # -O3 55 | CFLAGS64 = $(CFLAGS) #-m64 # -O3 56 | #CFLAGS64 = $(CFLAGS) -m64 # -O3 57 | 58 | INCLUDE_DIRS = -I. -I./heaplayers -I./heaplayers/util 59 | 60 | #GET_CHARACTERISTICS 61 | 62 | TARGETS = libsheriff_protect32.so libsheriff_detect32.so libsheriff_protect64.so libsheriff_detect64.so libsheriff_detect32_opt.so libsheriff_detect64_opt.so 63 | 64 | all: $(TARGETS) 65 | 66 | libsheriff_protect32.so: $(DEPS) 67 | $(CXX) $(CFLAGS32) $(INCLUDE_DIRS) -shared -fPIC -D'CUSTOM_PREFIX(x)=sheriff_##x' $(SRCS) -o libsheriff_protect32.so -ldl -lpthread 68 | 69 | libsheriff_detect32.so: $(DEPS) 70 | $(CXX) -DDETECT_FALSE_SHARING $(CFLAGS32) $(INCLUDE_DIRS) -shared -fPIC -D'CUSTOM_PREFIX(x)=sheriff_##x' $(SRCS) -o libsheriff_detect32.so -ldl -lpthread 71 | 72 | libsheriff_detect32_opt.so: $(DEPS) 73 | $(CXX) -DDETECT_FALSE_SHARING_OPT $(CFLAGS32) $(INCLUDE_DIRS) -shared -fPIC -D'CUSTOM_PREFIX(x)=sheriff_##x' $(SRCS) -o libsheriff_detect32_opt.so -ldl -lpthread 74 | 75 | libsheriff_protect64.so: $(DEPS) 76 | $(CXX) $(CFLAGS64) $(INCLUDE_DIRS) -shared -fPIC -D'CUSTOM_PREFIX(x)=sheriff_##x' $(SRCS) -o libsheriff_protect64.so -ldl -lpthread 77 | 78 | libsheriff_detect64.so: $(DEPS) 79 | $(CXX) -DDETECT_FALSE_SHARING $(CFLAGS64) $(INCLUDE_DIRS) -shared -fPIC -D'CUSTOM_PREFIX(x)=sheriff_##x' $(SRCS) -o libsheriff_detect64.so -ldl -lpthread 80 | 81 | libsheriff_detect64_opt.so: $(DEPS) 82 | $(CXX) -DDETECT_FALSE_SHARING_OPT $(CFLAGS64) $(INCLUDE_DIRS) -shared -fPIC -D'CUSTOM_PREFIX(x)=sheriff_##x' $(SRCS) -o libsheriff_detect64_opt.so -ldl -lpthread 83 | 84 | clean: 85 | rm -f $(TARGETS) 86 | 87 | -------------------------------------------------------------------------------- /NOTES: -------------------------------------------------------------------------------- 1 | NOTES: 2 | 3 | The threads-as-processes framework is helpful to improve performance 4 | for the following cases: 5 | 6 | a. Long transactions. 7 | b. False sharing inside. 8 | 9 | To work as a runtime system, we want to be passive. That is, we only 10 | protect pages when there is some benefit to do so. 11 | 12 | 1. Since we have to pay some overhead for transaction end and begin, 13 | which should be avoided as much as possible since the benefit of 14 | tolerating false sharing can easily be overwhelmed by the overhead 15 | of transaction overhead. 16 | 17 | 2. When one page has been protected before, which we can't find some 18 | benefit, we tend to un-protect this page forever even if there is 19 | memory re-usage in this page. So protection can happen only on one 20 | address once. 21 | 22 | 3. If we have a chance to detect some callsite which can cause the 23 | false sharing problem. We are trying to remember that for the 24 | future runs. 25 | 26 | 4. Sometimes we need to reprotect the memory if we find that is useful 27 | to do so. Thus, we are keeping track of the transaction size. If 28 | the transaction length is larger than one interval, we are 29 | protecting those new memory again. Then we can evaluate performance 30 | again later. 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sheriff: Precise Detection and Automatic Mitigation of False Sharing 2 | -------------------------------------------------------------------- 3 | 4 | Tongping Liu, Emery D. Berger 5 | 6 | 7 | 8 | 9 | 10 | 11 | Copyright (C) 2011-2012 University of Massachusetts Amherst 12 | 13 | 14 | ### Building Sheriff ### 15 | 16 | Running `make` builds two variants of the Sheriff library, in 32-bit and 64-bit versions: 17 | 18 | 1. *Sheriff_Protect*: Use either `libsheriff_protect32.so` or `libsheriff_protect64.so` as a replacement for the `pthreads` library to automatically eliminate false sharing problems. 19 | 20 | 2. *Sheriff_Detect*: Use either `libsheriff_detect32.so` or `libsheriff_detect64.so` to find false sharing problems (reported after the program finishes execution). 21 | 22 | ***NOTE: You may need to install the 32-bit libraries in order to build 32-bit executables. On Debian, for example, type `sudo yum install glibc-devel.i686` and `sudo yum install libstdc++.i686`. 23 | 24 | 25 | ### Using Sheriff ### 26 | 27 | Sheriff currently supports Linux x86 platforms. 28 | 29 | 1. Compile your program to object files (here, we use just one, `target.o`). 30 | 31 | 2. Link to the appropriate Sheriff library. There are two options (neither of which is particular to Sheriff). 32 | 33 | (a) Dynamic linking: this approach requires no environment variables, 34 | but the Sheriff library needs to be in a fixed, known location. 35 | Place the Sheriff library in a directory, e.g., `SHERIFF_DIR`. 36 | Then compile your program as follows: 37 | 38 | % g++ target.o -rdynamic SHERIFF_DIR/libsheriff_variant.so -ldl -o target 39 | 40 | (b) Ordinary dynamic linking: this approach is more flexible (you can 41 | change the location of the Sheriff library), but you must also 42 | set the `LD_LIBRARY_PATH` environment variable. 43 | 44 | % g++ target.o -LSHERIFF_DIR -lsheriff_variant -dl -o target 45 | % export LD_LIBRARY_PATH=SHERIFF_DIR:$LD_LIBRARY_PATH 46 | 47 | When using Sheriff_Detect, all reports of any discovered false sharing 48 | instances are printed out after the program finishes execution. 49 | 50 | ### Citing Sheriff ### 51 | 52 | If you use Sheriff, we would appreciate hearing about it. To cite 53 | Sheriff, please refer to the following paper, included as 54 | [`sheriff-oopsla2011.pdf`](https://github.com/plasma-umass/sheriff/blob/master/sheriff-oopsla2011.pdf?raw=true). 55 | 56 | ```latex 57 | @inproceedings{Liu:2011:SPD:2048066.2048070, 58 | author = {Liu, Tongping and Berger, Emery D.}, 59 | title = {SHERIFF: precise detection and automatic mitigation of false sharing}, 60 | booktitle = {Proceedings of the 2011 ACM International Conference on Object-Oriented Programming Systems, Languages, and Applications}, 61 | series = {OOPSLA '11}, 62 | year = {2011}, 63 | isbn = {978-1-4503-0940-0}, 64 | location = {Portland, Oregon, USA}, 65 | pages = {3--18}, 66 | numpages = {16}, 67 | url = {http://doi.acm.org/10.1145/2048066.2048070}, 68 | doi = {http://doi.acm.org/10.1145/2048066.2048070}, 69 | acmid = {2048070}, 70 | publisher = {ACM}, 71 | address = {New York, NY, USA}, 72 | keywords = {false sharing, multi-threaded}, 73 | } 74 | ``` 75 | 76 | -------------------------------------------------------------------------------- /examples/.mylog.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plasma-umass/sheriff/a5d7767f4c428de006236b601822f328a3fa6b7a/examples/.mylog.swp -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CXX= g++ 3 | #CFLAGS = -m32 -Wall -g 4 | CFLAGS = -Wall -g -O0 5 | LIBS = -lm -lrt -ldl 6 | 7 | SRCS := $(wildcard *.c) 8 | TESTS := $(SRCS:.c=) 9 | 10 | SRCS := $(wildcard *.cpp) 11 | TESTS := $(SRCS:.cpp=) 12 | 13 | PTHREAD_LIBS += $(LIBS) -lpthread 14 | PTHREAD_OBJS := $(addsuffix -pthread, $(TESTS)) 15 | 16 | #DTHREAD_LIBS = $(LIBS) -rdynamic ../libsheriff_detect32.so 17 | #DTHREAD_LIBS = $(LIBS) -rdynamic ../libsheriff_detect64_opt.so 18 | DTHREAD_LIBS = $(LIBS) -rdynamic ../libsheriff_detect64.so 19 | #DTHREAD_LIBS = $(LIBS) -rdynamic /nfs/cm/scratch1/tonyliu/grace/branches/sheriff/libsheriff.so 20 | #DTHREAD_LIBS = $(LIBS) -rdynamic sheriff/libsheriff.so 21 | DTHREAD_OBJS := $(addsuffix -dthread, $(TESTS)) 22 | 23 | COMPILE = $(CC) $(CFLAGS) 24 | COMPILE = $(CXX) $(CFLAGS) 25 | 26 | .PHONY : default all clean 27 | default: all 28 | all:$(PTHREAD_OBJS) $(DTHREAD_OBJS) 29 | clean: 30 | rm -f $(PTHREAD_OBJS) $(DTHREAD_OBJS) 31 | 32 | %-pthread:%.c 33 | $(COMPILE) -o $@ $< $(PTHREAD_LIBS) 34 | 35 | %-dthread:%.c 36 | $(COMPILE) -o $@ $< $(DTHREAD_LIBS) 37 | 38 | %-pthread:%.cpp 39 | $(COMPILE) -o $@ $< $(PTHREAD_LIBS) 40 | 41 | %-dthread:%.cpp 42 | $(COMPILE) -o $@ $< $(DTHREAD_LIBS) 43 | 44 | -------------------------------------------------------------------------------- /examples/falsesharing.cpp: -------------------------------------------------------------------------------- 1 | // g++ -g falsesharing.cpp -rdynamic ../libsheriff_protect64.so 2 | #include 3 | #include 4 | 5 | #include 6 | using namespace std; 7 | 8 | enum { MAX_THREADS = 8 }; 9 | //enum { NUM_ITERATIONS = 800000000 }; 10 | //enum { NUM_ITERATIONS = 800000000 }; 11 | enum { NUM_ITERATIONS = 800000000 }; 12 | //enum { NUM_ITERATIONS = 80000 }; 13 | 14 | class Item { 15 | public: 16 | volatile int x[MAX_THREADS]; 17 | }; 18 | 19 | #define SHARE_HEAP_OBJECT 0 20 | //#define SHARE_HEAP_OBJECT 1 21 | 22 | #if SHARE_HEAP_OBJECT 23 | Item * theItem; 24 | #else 25 | Item monkey; 26 | #endif 27 | 28 | void * worker (void * v) { 29 | long index = (long) v; 30 | fprintf(stderr, "%d: in worker %d\n", getpid(), index); 31 | 32 | for (int i = 0; i < NUM_ITERATIONS; i++) { 33 | #if SHARE_HEAP_OBJECT 34 | theItem->x[index]++; 35 | #else 36 | monkey.x[index]++; 37 | #endif 38 | // if(i % 100 == 0) 39 | // usleep(1); 40 | } 41 | //while(1); 42 | #if SHARE_HEAP_OBJECT 43 | fprintf(stderr, "%d: in worker %d done with item %d\n", getpid(), index, theItem->x[index]); 44 | #else 45 | fprintf(stderr, "%d: in worker %d done with item %d\n", getpid(), index, monkey.x[index]); 46 | #endif 47 | 48 | return NULL; 49 | } 50 | 51 | 52 | int 53 | main() 54 | { 55 | #if SHARE_HEAP_OBJECT 56 | theItem = new Item; 57 | #endif 58 | 59 | pthread_t thread[MAX_THREADS]; 60 | 61 | cout << "Starting threads." << endl; 62 | 63 | // cout << "theItem is at " << (void *) &theItem << endl; 64 | #if SHARE_HEAP_OBJECT 65 | fprintf(stderr, "theItem is at %p pointing to %p\n", &theItem, theItem); 66 | #else 67 | fprintf(stderr, "theItem is at %p\n", &monkey); 68 | #endif 69 | for (int i = 0; i < 8; i++) { 70 | #if SHARE_HEAP_OBJECT 71 | fprintf(stderr, "theItem[%d] is %lx\n", i, theItem->x[i]); 72 | #else 73 | fprintf(stderr, "theItem[%d] is %d\n", i, monkey.x[i]); 74 | #endif 75 | } 76 | 77 | for (int i = 0; i < 8; i++) { 78 | pthread_create (&thread[i], NULL, worker, (void *) i); 79 | } 80 | 81 | for (int i = 0; i < 8; i++) { 82 | pthread_join (thread[i], NULL); 83 | } 84 | 85 | cout << "Done." << endl; 86 | 87 | for (int i = 0; i < 8; i++) { 88 | #if SHARE_HEAP_OBJECT 89 | fprintf(stderr, "theItem[%d] is %lx\n", i, theItem->x[i]); 90 | #else 91 | fprintf(stderr, "theItem[%d] is %d\n", i, monkey.x[i]); 92 | #endif 93 | } 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /examples/memtest/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CXX= g++ 3 | CFLAGS = -m32 -Wall -g 4 | CFLAGS = -Wall -g -O0 5 | LIBS = -lm -lrt -ldl 6 | 7 | SRCS := $(wildcard *.c) 8 | TESTS := $(SRCS:.c=) 9 | 10 | #SRCS := $(wildcard *.cpp) 11 | #TESTS := $(SRCS:.cpp=) 12 | 13 | PTHREAD_LIBS += $(LIBS) -lpthread 14 | PTHREAD_OBJS := $(addsuffix -pthread, $(TESTS)) 15 | 16 | #DTHREAD_LIBS = $(LIBS) -rdynamic ../../libsheriff_detect32.so 17 | DTHREAD_LIBS = $(LIBS) -rdynamic ../../libsheriff_detect64.so 18 | #DTHREAD_LIBS = $(LIBS) -rdynamic ../../../sheriff-bak-beforesharedstack/libsheriff_detect64.so 19 | #DTHREAD_LIBS = $(LIBS) -rdynamic /nfs/cm/scratch1/tonyliu/grace/branches/sheriffrelease/sheriff/libsheriff_detect64.so 20 | #DTHREAD_LIBS = $(LIBS) -rdynamic /nfs/cm/scratch1/tonyliu/grace/branches/sheriff/libsheriff.so 21 | #DTHREAD_LIBS = $(LIBS) -rdynamic sheriff/libsheriff.so 22 | DTHREAD_OBJS := $(addsuffix -dthread, $(TESTS)) 23 | 24 | COMPILE = $(CC) $(CFLAGS) 25 | COMPILE = $(CXX) $(CFLAGS) 26 | 27 | .PHONY : default all clean 28 | default: all 29 | all:$(PTHREAD_OBJS) $(DTHREAD_OBJS) 30 | clean: 31 | rm -f $(PTHREAD_OBJS) $(DTHREAD_OBJS) 32 | 33 | %-pthread:%.c 34 | $(COMPILE) -o $@ $< $(PTHREAD_LIBS) 35 | 36 | %-dthread:%.c 37 | $(COMPILE) -o $@ $< $(DTHREAD_LIBS) 38 | 39 | %-pthread:%.cpp 40 | $(COMPILE) -o $@ $< $(PTHREAD_LIBS) 41 | 42 | %-dthread:%.cpp 43 | $(COMPILE) -o $@ $< $(DTHREAD_LIBS) 44 | 45 | -------------------------------------------------------------------------------- /examples/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | program="./falsesharing-dthread"; 4 | 5 | for i in {1..2001} 6 | do 7 | #./fprintf-dthread 8 | $program 9 | exit_code="$?" 10 | if [[ "${exit_code}" -ne 0 ]]; then 11 | exit; 12 | fi 13 | echo "$i times" 14 | done 15 | 16 | #strace -ff -o out ./fprintf-dthread 17 | -------------------------------------------------------------------------------- /heaplayers/adapt.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | 28 | #ifndef _ADAPT_H_ 29 | #define _ADAPT_H_ 30 | 31 | /** 32 | * @class AdaptHeap 33 | * @brief Maintains dictionary entries through freed objects. 34 | * Sample dictionaries include DLList and SLList. 35 | */ 36 | 37 | namespace HL { 38 | 39 | template 40 | class AdaptHeap : public SuperHeap { 41 | public: 42 | 43 | /// Allocate an object (remove from the dictionary). 44 | inline void * malloc (const size_t) { 45 | void * ptr = (Entry *) dict.get(); 46 | return ptr; 47 | } 48 | 49 | /// Deallocate the object (return to the dictionary). 50 | inline void free (void * ptr) { 51 | Entry * entry = (Entry *) ptr; 52 | dict.insert (entry); 53 | } 54 | 55 | /// Remove an object from the dictionary. 56 | inline int remove (void * ptr) { 57 | dict.remove ((Entry *) ptr); 58 | return 1; 59 | } 60 | 61 | /// Clear the dictionary. 62 | inline void clear (void) { 63 | Entry * ptr; 64 | while ((ptr = (Entry *) dict.get()) != NULL) { 65 | SuperHeap::free (ptr); 66 | } 67 | dict.clear(); 68 | SuperHeap::clear(); 69 | } 70 | 71 | 72 | private: 73 | 74 | /// The dictionary object. 75 | Dictionary dict; 76 | 77 | class Entry : public Dictionary::Entry {}; 78 | }; 79 | 80 | } 81 | 82 | #endif // _ADAPT_H_ 83 | -------------------------------------------------------------------------------- /heaplayers/adaptheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | 28 | #ifndef _ADAPT_H_ 29 | #define _ADAPT_H_ 30 | 31 | /** 32 | * @class AdaptHeap 33 | * @brief Maintains dictionary entries through freed objects. 34 | * Sample dictionaries include DLList and SLList. 35 | */ 36 | 37 | namespace HL { 38 | 39 | template 40 | class AdaptHeap : public SuperHeap { 41 | public: 42 | 43 | /// Allocate an object (remove from the dictionary). 44 | inline void * malloc (const size_t) { 45 | void * ptr = (Entry *) dict.get(); 46 | return ptr; 47 | } 48 | 49 | /// Deallocate the object (return to the dictionary). 50 | inline void free (void * ptr) { 51 | Entry * entry = (Entry *) ptr; 52 | dict.insert (entry); 53 | } 54 | 55 | /// Remove an object from the dictionary. 56 | inline int remove (void * ptr) { 57 | dict.remove ((Entry *) ptr); 58 | return 1; 59 | } 60 | 61 | /// Clear the dictionary. 62 | inline void clear (void) { 63 | Entry * ptr; 64 | while ((ptr = (Entry *) dict.get()) != NULL) { 65 | SuperHeap::free (ptr); 66 | } 67 | dict.clear(); 68 | SuperHeap::clear(); 69 | } 70 | 71 | 72 | private: 73 | 74 | /// The dictionary object. 75 | Dictionary dict; 76 | 77 | class Entry : public Dictionary::Entry {}; 78 | }; 79 | 80 | } 81 | 82 | #endif // _ADAPT_H_ 83 | -------------------------------------------------------------------------------- /heaplayers/addheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _ADDHEAP_H_ 4 | #define _ADDHEAP_H_ 5 | 6 | /* 7 | 8 | Heap Layers: An Extensible Memory Allocation Infrastructure 9 | 10 | Copyright (C) 2000-2003 by Emery Berger 11 | http://www.cs.umass.edu/~emery 12 | emery@cs.umass.edu 13 | 14 | This program is free software; you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation; either version 2 of the License, or 17 | (at your option) any later version. 18 | 19 | This program is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | 24 | You should have received a copy of the GNU General Public License 25 | along with this program; if not, write to the Free Software 26 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 | 28 | */ 29 | 30 | // Reserve space for a class in the head of every allocated object. 31 | 32 | #include 33 | 34 | namespace HL { 35 | 36 | template 37 | class AddHeap : public Super { 38 | public: 39 | 40 | inline void * malloc (size_t sz) { 41 | void * ptr = Super::malloc (sz + align(sizeof(Add))); 42 | void * newPtr = (void *) align ((size_t) ((Add *) ptr + 1)); 43 | return ptr; 44 | } 45 | 46 | inline void free (void * ptr) { 47 | void * origPtr = (void *) ((Add *) ptr - 1); 48 | Super::free (origPtr); 49 | } 50 | 51 | inline size_t getSize (void * ptr) { 52 | void * origPtr = (void *) ((Add *) ptr - 1); 53 | return Super::getSize (origPtr); 54 | } 55 | 56 | private: 57 | static inline size_t align (size_t sz) { 58 | return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1); 59 | } 60 | 61 | }; 62 | 63 | }; 64 | #endif 65 | -------------------------------------------------------------------------------- /heaplayers/ansiwrapper.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _ANSIWRAPPER_H_ 4 | #define _ANSIWRAPPER_H_ 5 | 6 | #include 7 | #include 8 | 9 | /* 10 | * @class ANSIWrapper 11 | * @brief Provide ANSI C behavior for malloc & free. 12 | * 13 | * Implements all prescribed ANSI behavior, including zero-sized 14 | * requests & aligned request sizes to a double word (or long word). 15 | */ 16 | 17 | namespace HL { 18 | 19 | template 20 | class ANSIWrapper : public SuperHeap { 21 | public: 22 | 23 | ANSIWrapper (void) 24 | {} 25 | 26 | inline void * malloc (size_t sz) { 27 | if (sz < 2 * sizeof(size_t)) { 28 | // Make sure it's at least big enough to hold two pointers (and 29 | // conveniently enough, that's at least the size of a double, as 30 | // required by ANSI). 31 | sz = 2 * sizeof(size_t); 32 | } 33 | sz = align(sz); 34 | void * ptr = SuperHeap::malloc (sz); 35 | return ptr; 36 | } 37 | 38 | inline void free (void * ptr) { 39 | if (ptr != 0) { 40 | SuperHeap::free (ptr); 41 | } 42 | } 43 | 44 | inline void * calloc (const size_t s1, const size_t s2) { 45 | void * ptr = malloc (s1 * s2); 46 | if (ptr) { 47 | memset (ptr, 0, s1 * s2); 48 | } 49 | return ptr; 50 | } 51 | 52 | inline void * realloc (void * ptr, const size_t sz) { 53 | if (ptr == 0) { 54 | return malloc (sz); 55 | } 56 | if (sz == 0) { 57 | free (ptr); 58 | return 0; 59 | } 60 | size_t objSize = getSize (ptr); 61 | if (objSize == sz) { 62 | return ptr; 63 | } 64 | 65 | // Allocate a new block of size sz. 66 | void * buf = malloc (sz); 67 | 68 | // Copy the contents of the original object 69 | // up to the size of the new block. 70 | 71 | size_t minSize = (objSize < sz) ? objSize : sz; 72 | if (buf) { 73 | memcpy (buf, ptr, minSize); 74 | } 75 | 76 | // Free the old block. 77 | free (ptr); 78 | return buf; 79 | } 80 | 81 | inline size_t getSize (void * ptr) { 82 | if (ptr) { 83 | return SuperHeap::getSize (ptr); 84 | } else { 85 | return 0; 86 | } 87 | } 88 | 89 | private: 90 | inline static size_t align (size_t sz) { 91 | return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1); 92 | } 93 | 94 | }; 95 | 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /heaplayers/bins.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINS_H_ 2 | #define _BINS_H_ 3 | 4 | namespace HL { 5 | 6 | template 7 | class bins; 8 | 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /heaplayers/bins4k.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #if !defined(_BINS4K_H_) 4 | #define _BINS4K_H_ 5 | 6 | #include "bins.h" 7 | #include "sassert.h" 8 | 9 | namespace HL { 10 | 11 | template 12 | class bins { 13 | 14 | public: 15 | bins (void) {} 16 | 17 | enum { NUM_BINS = 33 }; 18 | enum { BIG_OBJECT = 4096 - sizeof(Header) }; 19 | 20 | static const size_t _bins[NUM_BINS]; 21 | 22 | static inline int getSizeClass (size_t sz) { 23 | assert (sz <= BIG_OBJECT); 24 | if (sz < 8) { 25 | return 0; 26 | } else if (sz <= 128) { 27 | return ((sz + 7) >> 3) - 1; 28 | } else { 29 | return slowLookupSizeClass (sz); 30 | } 31 | } 32 | 33 | static inline size_t getClassSize (const int i) { 34 | assert (i >= 0); 35 | assert (i < NUM_BINS); 36 | return _bins[i]; 37 | } 38 | 39 | private: 40 | 41 | static int slowLookupSizeClass (const size_t sz) { 42 | // Find the size class for a given object size 43 | // (the smallest i such that _bins[i] >= sz). 44 | int sizeclass = 0; 45 | while (_bins[sizeclass] < sz) 46 | { 47 | sizeclass++; 48 | assert (sizeclass < NUM_BINS); 49 | } 50 | return sizeclass; 51 | } 52 | 53 | sassert<(BIG_OBJECT > 0)> verifyHeaderSize; 54 | 55 | }; 56 | } 57 | 58 | template 59 | const size_t HL::bins::_bins[NUM_BINS] = {8UL, 16UL, 24UL, 32UL, 40UL, 48UL, 56UL, 64UL, 72UL, 80UL, 88UL, 96UL, 104UL, 112UL, 120UL, 128UL, 152UL, 176UL, 208UL, 248UL, 296UL, 352UL, 416UL, 496UL, 592UL, 704UL, 856UL, 1024UL, 1224UL, 1712UL, 2048UL, 3416UL, 4096UL - sizeof(Header)}; 60 | 61 | #endif 62 | 63 | -------------------------------------------------------------------------------- /heaplayers/boundedfreelistheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _BOUNDEDFREELISTHEAP_H_ 4 | #define _BOUNDEDFREELISTHEAP_H_ 5 | 6 | // Beware -- this is for one "size class" only!! 7 | 8 | template 9 | class BoundedFreeListHeap : public Super { 10 | public: 11 | 12 | BoundedFreeListHeap (void) 13 | : nObjects (0), 14 | myFreeList (NULL) 15 | {} 16 | 17 | ~BoundedFreeListHeap (void) 18 | { 19 | clear(); 20 | } 21 | 22 | inline void * malloc (size_t sz) { 23 | // Check the free list first. 24 | void * ptr = myFreeList; 25 | if (ptr == NULL) { 26 | ptr = Super::malloc (sz); 27 | } else { 28 | myFreeList = myFreeList->next; 29 | } 30 | return ptr; 31 | } 32 | 33 | inline void free (void * ptr) { 34 | if (nObjects < numObjects) { 35 | // Add this object to the free list. 36 | ((freeObject *) ptr)->next = myFreeList; 37 | myFreeList = (freeObject *) ptr; 38 | nObjects++; 39 | } else { 40 | clear(); 41 | // Super::free (ptr); 42 | } 43 | } 44 | 45 | inline void clear (void) { 46 | // Delete everything on the free list. 47 | void * ptr = myFreeList; 48 | while (ptr != NULL) { 49 | void * oldptr = ptr; 50 | ptr = (void *) ((freeObject *) ptr)->next; 51 | Super::free (oldptr); 52 | } 53 | myFreeList = NULL; 54 | nObjects = 0; 55 | } 56 | 57 | private: 58 | 59 | class freeObject { 60 | public: 61 | freeObject * next; 62 | }; 63 | 64 | int nObjects; 65 | freeObject * myFreeList; 66 | }; 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /heaplayers/checkheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _CHECKHEAP_H_ 2 | #define _CHECKHEAP_H_ 3 | 4 | 5 | template 6 | class CheckHeap : public SuperHeap { 7 | private: 8 | enum { RECEIVED_A_NULL_OBJECT_FROM_MALLOC = 0 }; 9 | enum { RECEIVED_AN_UNALIGNED_OBJECT_FROM_MALLOC = 0 }; 10 | public: 11 | inline void * malloc (size_t sz) { 12 | void * addr = SuperHeap::malloc (sz); 13 | if (addr == NULL) { 14 | assert (RECEIVED_A_NULL_OBJECT_FROM_MALLOC); 15 | printf ("RECEIVED_A_NULL_OBJECT_FROM_MALLOC\n"); 16 | abort(); 17 | } 18 | if ((unsigned long) addr % sizeof(double) != 0) { 19 | assert (RECEIVED_AN_UNALIGNED_OBJECT_FROM_MALLOC); 20 | printf ("RECEIVED_AN_UNALIGNED_OBJECT_FROM_MALLOC\n"); 21 | abort(); 22 | } 23 | return addr; 24 | } 25 | }; 26 | 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /heaplayers/chunkheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _CHUNKHEAP_H_ 4 | #define _CHUNKHEAP_H_ 5 | 6 | /* 7 | 8 | Heap Layers: An Extensible Memory Allocation Infrastructure 9 | 10 | Copyright (C) 2000-2003 by Emery Berger 11 | http://www.cs.umass.edu/~emery 12 | emery@cs.umass.edu 13 | 14 | This program is free software; you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation; either version 2 of the License, or 17 | (at your option) any later version. 18 | 19 | This program is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | 24 | You should have received a copy of the GNU General Public License 25 | along with this program; if not, write to the Free Software 26 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 | 28 | */ 29 | 30 | #include 31 | 32 | /** 33 | * @class ChunkHeap 34 | * @brief Allocates memory from the superheap in chunks. 35 | * @param ChunkSize The minimum size for allocating memory from the superheap. 36 | */ 37 | 38 | namespace HL { 39 | 40 | template 41 | class ChunkHeap : public SuperHeap { 42 | public: 43 | 44 | inline ChunkHeap (void) 45 | : buffer (NULL), 46 | eob (NULL) 47 | {} 48 | 49 | inline void * malloc (const size_t sz) { 50 | void * ptr = buffer; 51 | buffer += sz; 52 | if (buffer <= eob) { 53 | assert (eob != NULL); 54 | assert ((size_t) (eob - (char *) ptr + 1) >= sz); 55 | return ptr; 56 | } 57 | buffer -= sz; // we didn't succeed, back up 58 | return getMoreMemory(sz); 59 | } 60 | 61 | inline void clear (void) { 62 | buffer = NULL; 63 | eob = NULL; 64 | SuperHeap::clear (); 65 | } 66 | 67 | private: 68 | 69 | // Disabled. 70 | inline int remove (void *); 71 | 72 | void * getMoreMemory (size_t sz) { 73 | assert (sz > 0); 74 | // Round sz to the next chunk size. 75 | size_t reqSize = (((sz-1) / ChunkSize) + 1) * ChunkSize; 76 | char * buf = (char *) SuperHeap::malloc (reqSize); 77 | if (buf == NULL) { 78 | return NULL; 79 | } 80 | // If the current end of buffer is not the same as the new buffer, 81 | // reset the buffer pointer. 82 | if (eob != buf) { 83 | buffer = buf; 84 | } 85 | else { 86 | // we still have a bit leftover at the end of previous buffer 87 | reqSize += eob - buffer; 88 | } 89 | eob = buffer + reqSize; 90 | 91 | void * ptr = buffer; 92 | buffer += sz; 93 | return ptr; 94 | } 95 | 96 | /// The current allocation buffer. 97 | char * buffer; 98 | 99 | /// The end of the buffer. 100 | char * eob; 101 | }; 102 | 103 | } 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /heaplayers/debugheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | 4 | #ifndef _DEBUGHEAP_H_ 5 | #define _DEBUGHEAP_H_ 6 | 7 | #include 8 | 9 | /** 10 | * 11 | * 12 | */ 13 | 14 | namespace HL { 15 | 16 | template 18 | class DebugHeap : public Super { 19 | private: 20 | 21 | enum { CANARY = 0xdeadbeef }; 22 | 23 | public: 24 | 25 | // Fill with A's. 26 | inline void * malloc (size_t sz) { 27 | // Add a guard area at the end. 28 | void * ptr; 29 | ptr = Super::malloc (sz + sizeof(unsigned long)); 30 | memset (ptr, 'A', sz); 31 | *((unsigned long *) ((char *) ptr + sz)) = (unsigned long) CANARY; 32 | assert (Super::getSize(ptr) >= sz); 33 | return ptr; 34 | } 35 | 36 | // Fill with F's. 37 | inline void free (void * ptr) { 38 | char * b = (char *) ptr; 39 | size_t sz = Super::getSize(ptr); 40 | // Check for the canary. 41 | unsigned long storedCanary = *((unsigned long *) b + sz - sizeof(unsigned long)); 42 | if (storedCanary != CANARY) { 43 | abort(); 44 | } 45 | memset (ptr, freeChar, sz); 46 | Super::free (ptr); 47 | } 48 | }; 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /heaplayers/exceptionheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _EXCEPTION_HEAP 28 | #define _EXCEPTION_HEAP 29 | 30 | #include 31 | #include 32 | 33 | class std::bad_alloc; 34 | 35 | namespace HL { 36 | 37 | template 38 | class ExceptionHeap : public Super { 39 | public: 40 | inline void * malloc (size_t sz) throw (std::bad_alloc) { 41 | void * ptr = Super::malloc (sz); 42 | if (ptr == NULL) { 43 | throw new std::bad_alloc; 44 | } 45 | return ptr; 46 | } 47 | }; 48 | 49 | 50 | template 51 | class CatchExceptionHeap : public Super { 52 | public: 53 | inline void * malloc (size_t sz) { 54 | void * ptr; 55 | try { 56 | ptr = Super::malloc (sz); 57 | } catch (std::bad_alloc) { 58 | ptr = NULL; 59 | } 60 | return ptr; 61 | } 62 | }; 63 | 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /heaplayers/experimental/batchheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _BATCHHEAP_H_ 4 | #define _BATCHHEAP_H_ 5 | 6 | #include 7 | 8 | 9 | template 10 | class MultiMalloc : public SuperHeap { 11 | public: 12 | // Sets ptr to a list of up to num objects of size sz 13 | // and returns how many free objects ptr points to. 14 | int multimalloc (int num, size_t sz, void *& ptr) 15 | { 16 | int i = 0; 17 | ptr = (freeObject *) SuperHeap::malloc (sz); 18 | freeObject * p = (freeObject *) ptr; 19 | if (ptr != NULL) { 20 | for (i = 1; i < num; i++) { 21 | p->next = (freeObject *) SuperHeap::malloc (sz); 22 | if (p->next == NULL) 23 | break; 24 | p = p->next; 25 | } 26 | p->next = NULL; 27 | } 28 | return i; 29 | } 30 | 31 | // Frees all num items pointed to by ptr 32 | // and sets ptr to NULL. 33 | void multifree (int num, void *& ptr) 34 | { 35 | freeObject * p; 36 | freeObject * prev = (freeObject *) ptr; 37 | for (int i = 0; i < num; i++) { 38 | p = prev->next; 39 | SuperHeap::free (prev); 40 | prev = p; 41 | } 42 | ptr = NULL; 43 | } 44 | 45 | private: 46 | 47 | class freeObject { 48 | public: 49 | freeObject * next; 50 | }; 51 | 52 | 53 | }; 54 | 55 | 56 | template 57 | class BatchHeap : public SuperHeap { 58 | public: 59 | 60 | BatchHeap (void) 61 | : nObjects (0) 62 | { 63 | freeList[0] = NULL; 64 | freeList[1] = NULL; 65 | } 66 | 67 | 68 | ~BatchHeap (void) { 69 | if (nObjects <= BatchNumber) { 70 | SuperHeap::multifree (nObjects, (void *&) freeList[0]); 71 | } else { 72 | SuperHeap::multifree (BatchNumber, (void *&) freeList[0]); 73 | SuperHeap::multifree (nObjects - BatchNumber, (void *&) freeList[1]); 74 | } 75 | } 76 | 77 | inline void * malloc (size_t sz) { 78 | if (nObjects == 0) { 79 | // Obtain BatchNumber objects if we're out. 80 | nObjects = SuperHeap::multimalloc (BatchNumber, sz, (void *&) freeList[0]); 81 | } 82 | assert (nObjects >= 1); 83 | freeObject * ptr; 84 | if (nObjects > BatchNumber) { 85 | freeObject *& head = freeList[1]; 86 | ptr = head; 87 | nObjects--; 88 | head = head->next; 89 | return (void *) ptr; 90 | } else { 91 | freeObject *& head = freeList[0]; 92 | ptr = head; 93 | nObjects--; 94 | head = head->next; 95 | return (void *) ptr; 96 | } 97 | } 98 | 99 | inline void free (void * ptr) { 100 | if (nObjects <= BatchNumber) { 101 | freeObject *& head = freeList[0]; 102 | ((freeObject *) ptr)->next = head; 103 | head = (freeObject *) ptr; 104 | } else { 105 | freeObject *& head = freeList[1]; 106 | ((freeObject *) ptr)->next = head; 107 | head = (freeObject *) ptr; 108 | } 109 | nObjects++; 110 | if (nObjects == 2 * BatchNumber) { 111 | // Free half of them. 112 | assert (freeList[1] != NULL); 113 | SuperHeap::multifree (BatchNumber, (void *&) freeList[1]); 114 | } 115 | } 116 | 117 | private: 118 | 119 | class freeObject { 120 | public: 121 | freeObject * next; 122 | }; 123 | 124 | int nObjects; 125 | 126 | // The first free list holds the first BatchNumber objects, 127 | // while the second free list holds the rest. 128 | freeObject * freeList[2]; 129 | }; 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /heaplayers/experimental/binheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _BINHEAP_H_ 4 | #define _BINHEAP_H_ 5 | 6 | #include 7 | 8 | 9 | template 10 | class BinHeap { 11 | public: 12 | 13 | inline void * malloc (size_t sz) { 14 | // Find bin. 15 | int bin = findBin (sz); 16 | void * ptr = myHeaps[bin].malloc (sz); 17 | return ptr; 18 | } 19 | 20 | inline void free (void * ptr) { 21 | size_t sz = Super::size (ptr); 22 | int bin = findBin (sz); 23 | myHeaps[bin].free (ptr); 24 | } 25 | 26 | private: 27 | 28 | inline int findBin (size_t sz) { 29 | int i; 30 | for (i = 0; i < NumBins; i++) { 31 | if (Bins[i] >= sz) { 32 | break; 33 | } 34 | } 35 | return i; 36 | } 37 | 38 | Super myHeaps[NumBins + 1]; 39 | 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /heaplayers/experimental/cacheheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _CACHEHEAP_H_ 4 | #define _CACHEHEAP_H_ 5 | 6 | template 7 | class CacheHeap : public Super { 8 | public: 9 | 10 | inline void * malloc (size_t sz) { 11 | void * ptr = mySuper.malloc (sz); 12 | return ptr; 13 | } 14 | 15 | inline void free (void * ptr) { 16 | // Insert checks here! 17 | mySuper.free (ptr); 18 | } 19 | 20 | private: 21 | 22 | Super mySuper; 23 | }; 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /heaplayers/experimental/cartesianheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _CARTESIANHEAP_H_ 2 | #define _CARTESIANHEAP_H_ 3 | 4 | //#include "heaplayers.h" 5 | //#include "treap.h" 6 | 7 | // NB: All objects are rounded up to at least the size of a treap node 8 | // (around 24 bytes on a 32-bit architecture). 9 | 10 | template 11 | class CartesianHeap : public SuperHeap { 12 | 13 | // Provide a freelist wrapper for treap nodes. 14 | class MyTreap : public Treap { 15 | public: 16 | // class Node : public PerClassHeap::Node, FreelistHeap > {}; 17 | }; 18 | 19 | public: 20 | 21 | ~CartesianHeap (void) { 22 | // FIX ME 23 | // free everything from the treap. 24 | } 25 | 26 | void * malloc (size_t sz) { 27 | // Round sz up. 28 | sz = (sz < sizeof(MyTreap::Node)) ? sizeof(MyTreap::Node) : sz; 29 | MyTreap::Node * n = (MyTreap::Node *) treap.lookupGreater (sz); 30 | if (n != NULL) { 31 | assert (n->getValue() == (void *) n); 32 | void * ptr = n->getValue(); 33 | treap.remove (n); 34 | // delete n; // onto a freelist 35 | return ptr; 36 | } else { 37 | return SuperHeap::malloc (sz); 38 | } 39 | } 40 | 41 | void free (void * ptr) { 42 | // MyTreap::Node * n = new MyTreap::Node; // from a freelist 43 | // cout << "n = " << (void *) n << endl; 44 | MyTreap::Node * n = (MyTreap::Node *) ptr; 45 | treap.insert (n, getSize(ptr), ptr, (unsigned int) ptr); 46 | } 47 | 48 | // Removes a pointer from the treap. 49 | void remove (void * ptr) { 50 | treap.remove ((MyTreap::Node *) ptr); 51 | } 52 | 53 | private: 54 | 55 | MyTreap treap; 56 | 57 | }; 58 | 59 | #endif // _CARTESIANHEAP_H_ 60 | -------------------------------------------------------------------------------- /heaplayers/experimental/combineheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _COMBINEHEAP_H_ 28 | #define _COMBINEHEAP_H_ 29 | 30 | 31 | /** 32 | * @class CombineHeap 33 | * @brief Combines MallocHeap and FreeHeap: MallocHeap for malloc, FreeHeap for the rest 34 | */ 35 | 36 | namespace HL { 37 | 38 | template 39 | class CombineHeap : public FreeHeap { 40 | 41 | public: 42 | 43 | inline void * malloc (size_t sz) { 44 | return mallocheap.malloc (sz); 45 | } 46 | 47 | MallocHeap& getMallocHeap (void) { 48 | return mallocheap; 49 | } 50 | 51 | inline void clear (void) { 52 | mallocheap.clear(); 53 | FreeHeap::clear(); 54 | } 55 | 56 | inline void free (void * ptr) { 57 | printf ("combineheap: free %x, sz = %d!\n", ptr, getSize(ptr)); 58 | FreeHeap::free (ptr); 59 | } 60 | 61 | private: 62 | MallocHeap mallocheap; 63 | 64 | }; 65 | 66 | }; 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /heaplayers/experimental/counteddictionary.h: -------------------------------------------------------------------------------- 1 | #ifndef _COUNTEDDICTIONARY_H_ 2 | #define _COUNTEDDICTIONARY_H_ 3 | 4 | template 5 | class CountedDictionary : public Dict { 6 | public: 7 | class Entry : public Dict::Entry {}; 8 | 9 | __forceinline CountedDictionary (void) 10 | : num (0) 11 | {} 12 | 13 | __forceinline void clear (void) { 14 | num = 0; 15 | Dict::clear(); 16 | } 17 | 18 | __forceinline Entry * get (void) { 19 | Entry * e = (Entry *) Dict::get(); 20 | if (e) { 21 | --num; 22 | } 23 | return e; 24 | } 25 | 26 | __forceinline Entry * remove (void) { 27 | Entry * e = (Entry *) Dict::remove(); 28 | if (e) { 29 | --num; 30 | } 31 | return e; 32 | } 33 | 34 | __forceinline void insert (Entry * e) { 35 | Dict::insert (e); 36 | ++num; 37 | } 38 | 39 | __forceinline int getNumber (void) const { 40 | return num; 41 | } 42 | 43 | private: 44 | int num; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /heaplayers/experimental/emptychunkheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _LAZYSLOTHEAP_H_ 4 | #define _LAZYSLOTHEAP_H_ 5 | 6 | /* 7 | This heap manages memory in units of Chunks. 8 | malloc returns a slot within a chunk, 9 | while free returns slots back to a chunk. 10 | 11 | Once a chunk is COMPLETELY empty, it is returned to the superheap. 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | template 18 | class LazySlotHeap : public Super { 19 | public: 20 | 21 | LazySlotHeap (void) 22 | : myChunk (new (Super::malloc (sz)) Chunk()) 23 | {} 24 | 25 | ~LazySlotHeap (void) 26 | { 27 | // Give up our chunk. 28 | Super::free (myChunk); 29 | } 30 | 31 | inline void * malloc (size_t sz) { 32 | assert (sz == chunkSize); 33 | void * ptr = myChunk->getSlot(); 34 | if (ptr == NULL) { 35 | myChunk = new (Super::malloc (sz)) Chunk(); 36 | ptr = myChunk->getSlot(); 37 | assert (ptr != NULL); 38 | } 39 | return ; 40 | } 41 | 42 | inline void free (void * ptr) { 43 | /// Return a slot to its chunk. 44 | Chunk * ch = Chunk::getChunk (ptr); 45 | ch->putSlot (ptr); 46 | // Once the chunk is completely empty, free it. 47 | if (ch->getNumSlotsAvailable() == ch->getNumSlots()) { 48 | if (ch == myChunk) { 49 | // If this was 'our' chunk, get another one. 50 | myChunk = new (Super::malloc (sz)) Chunk(); 51 | } 52 | Super::free (ch); 53 | } 54 | } 55 | 56 | private: 57 | 58 | Chunk * myChunk; 59 | 60 | }; 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /heaplayers/experimental/fifofreelist.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _FIFOFREELIST_H_ 4 | #define _FIFOFREELIST_H_ 5 | 6 | #include 7 | 8 | #ifdef NDEBUG 9 | #define IFDEBUG(x) 10 | #else 11 | #define IFDEBUG(x) x 12 | #endif 13 | 14 | 15 | template 16 | class FIFOFreelistHeap : public SuperHeap { 17 | public: 18 | 19 | FIFOFreelistHeap (void) 20 | IFDEBUG(: nObjects (0)) 21 | { 22 | head.next = &tail; 23 | tail.next = &tail; 24 | assert (isEmpty()); 25 | } 26 | 27 | ~FIFOFreelistHeap (void) 28 | { 29 | // printf ("Adios free list.\n"); 30 | // Delete everything on the free list. 31 | freeObject * ptr = head.next; 32 | while (ptr != &tail) { 33 | void * oldptr = ptr; 34 | ptr = ptr->next; 35 | SuperHeap::free (oldptr); 36 | } 37 | } 38 | 39 | inline void * malloc (size_t sz) { 40 | assert (isValid()); 41 | // Check the free list first. 42 | freeObject * ptr = head.next; 43 | if (ptr == &tail) { 44 | assert (nObjects == 0); 45 | assert (isEmpty()); 46 | ptr = (freeObject *) SuperHeap::malloc (sz); 47 | } else { 48 | assert (nObjects > 0); 49 | head.next = ptr->next; 50 | if (head.next == &tail) { 51 | tail.next = &tail; 52 | } 53 | IFDEBUG (nObjects--); 54 | } 55 | assert (isValid()); 56 | return (void *) ptr; 57 | } 58 | 59 | inline void free (void * ptr) { 60 | assert (isValid()); 61 | // Add this object to the free list. 62 | assert (ptr != NULL); 63 | IFDEBUG (nObjects++); 64 | freeObject * p = (freeObject *) ptr; 65 | p->next = &tail; 66 | tail.next->next = p; 67 | tail.next = p; 68 | if (head.next == &tail) { 69 | head.next = p; 70 | } 71 | assert (!isEmpty()); 72 | assert (isValid()); 73 | } 74 | 75 | private: 76 | 77 | int isValid (void) { 78 | // Make sure every object is the right size. 79 | freeObject * ptr = head.next; 80 | if (ptr != &tail) { 81 | size_t sz = SuperHeap::getSize(ptr); 82 | while (ptr != &tail) { 83 | void * oldptr = ptr; 84 | ptr = ptr->next; 85 | assert (SuperHeap::getSize(oldptr) >= sz); 86 | } 87 | } 88 | return 1; 89 | } 90 | 91 | int isEmpty (void) { 92 | return (head.next == &tail); 93 | } 94 | 95 | class freeObject { 96 | public: 97 | freeObject * prev; 98 | freeObject * next; 99 | }; 100 | 101 | freeObject head, tail; 102 | IFDEBUG (int nObjects); 103 | }; 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /heaplayers/experimental/kingsmodheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _KINGSMODHEAP_H_ 2 | #define _KINGSMODHEAP_H_ 3 | 4 | #include "segheap.h" 5 | 6 | /* KingsMod (segregated fits) allocator */ 7 | 8 | namespace KingsMod { 9 | 10 | inline size_t class2Size (int i); 11 | 12 | inline int pow2Class (size_t sz) { 13 | static size_t sizeTable[] = {8UL, 16UL, 24UL, 32UL, 40UL, 48UL, 56UL, 72UL, 80UL, 96UL, 120UL, 144UL, 168UL, 200UL, 240UL, 288UL, 344UL, 416UL, 496UL, 592UL, 712UL, 856UL, 1024UL, 1232UL, 1472UL, 1768UL, 2120UL, 2544UL, 3048UL, 3664UL}; 14 | int c = 0; 15 | while (c < 30 && sz < sizeTable[c]) { 16 | c++; 17 | } 18 | return c; 19 | } 20 | 21 | inline size_t class2Size (int i) { 22 | assert (i >= 0); 23 | assert (i < 30); 24 | static size_t sizeTable[] = {8UL, 16UL, 24UL, 32UL, 40UL, 48UL, 56UL, 72UL, 80UL, 96UL, 120UL, 144UL, 168UL, 200UL, 240UL, 288UL, 344UL, 416UL, 496UL, 592UL, 712UL, 856UL, 1024UL, 1232UL, 1472UL, 1768UL, 2120UL, 2544UL, 3048UL, 3664UL}; 25 | return sizeTable[i]; 26 | } 27 | 28 | }; 29 | 30 | 31 | template 32 | class KingsModHeap : public SegHeap<29, KingsMod::pow2Class, KingsMod::class2Size, PerClassHeap, PerClassHeap> {}; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /heaplayers/experimental/lazyheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #ifndef _LAZYHEAP_H_ 4 | #define _LAZYHEAP_H_ 5 | 6 | template 7 | class LazyHeap { 8 | public: 9 | 10 | LazyHeap (void) 11 | : initialized (0) 12 | {} 13 | 14 | ~LazyHeap (void) { 15 | if (initialized) { 16 | delete lazyheap; 17 | } 18 | } 19 | 20 | inline void * malloc (size_t sz) { 21 | return getHeap()->malloc (sz); 22 | } 23 | inline void free (void * ptr) { 24 | getHeap()->free (ptr); 25 | } 26 | inline void clear (void) { 27 | if (initialized) { 28 | getHeap()->clear(); 29 | } 30 | } 31 | 32 | private: 33 | 34 | SuperHeap * getHeap (void) { 35 | if (!initialized) { 36 | lazyheap = new SuperHeap; 37 | initialized = 1; 38 | } 39 | return lazyheap; 40 | } 41 | 42 | bool initialized; 43 | SuperHeap * lazyheap; 44 | }; 45 | 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /heaplayers/experimental/lazyslotheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _LAZYSLOTHEAP_H_ 4 | #define _LAZYSLOTHEAP_H_ 5 | 6 | /* 7 | This heap manages memory in units of Chunks. 8 | malloc returns a slot within a chunk, 9 | while free returns slots back to a chunk. 10 | 11 | We completely exhaust the first chunk before we ever get another one. 12 | Once a chunk (except for our current one) is COMPLETELY empty, it is returned to the superheap. 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | #include "chunk.h" 19 | 20 | 21 | template 22 | class LazySlotHeap : public Super { 23 | public: 24 | 25 | LazySlotHeap (void) 26 | : myChunk (new (Super::malloc (chunkSize)) Chunk()) 27 | {} 28 | 29 | ~LazySlotHeap (void) 30 | { 31 | // Give up our chunk. 32 | Super::free (myChunk); 33 | } 34 | 35 | inline void * malloc (size_t sz) { 36 | assert (sz <= slotSize); 37 | void * ptr = myChunk->getSlot(); 38 | if (ptr == NULL) { 39 | myChunk = new (Super::malloc (chunkSize)) Chunk(); 40 | ptr = myChunk->getSlot(); 41 | assert (ptr != NULL); 42 | } 43 | return ptr; 44 | } 45 | 46 | inline void free (void * ptr) { 47 | /// Return a slot to its chunk. 48 | Chunk * ch = Chunk::getChunk (ptr); 49 | ch->putSlot (ptr); 50 | // check if it's completely empty. If so, free it. 51 | if (ch != myChunk) { 52 | // Once the chunk is completely empty, free it. 53 | if (ch->getNumSlotsAvailable() == ch->getNumSlots()) { 54 | Super::free (ch); 55 | } 56 | } 57 | 58 | #if 0 59 | // If this chunk isn't the one we're currently holding, 60 | // free it. NB: It is NOT guaranteed to be empty! 61 | if (ch != myChunk) { 62 | Super::free (ch); 63 | } 64 | #endif 65 | #if 0 66 | template 67 | class StrictSlotHeap : public LazySlotHeap { 68 | public: 69 | inline void free (void * ptr) { 70 | /// Return a slot to its chunk. 71 | Chunk * ch = Chunk::getChunk (ptr); 72 | ch->putSlot (ptr); 73 | // check if it's completely empty. If so, free it. 74 | if (ch != myChunk) { 75 | // Once the chunk is completely empty, free it. 76 | if (ch->getNumSlotsAvailable() == ch->getNumSlots()) { 77 | Super::free (ch); 78 | } 79 | } 80 | } 81 | 82 | }; 83 | #endif 84 | 85 | } 86 | 87 | inline static size_t size (void * ptr) 88 | { 89 | return slotSize; 90 | } 91 | 92 | 93 | protected: 94 | 95 | Chunk * myChunk; 96 | 97 | }; 98 | 99 | 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /heaplayers/experimental/multiheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _MULTIHEAP_H_ 2 | #define _MULTIHEAP_H_ 3 | 4 | #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) 5 | #ifndef WIN32 6 | #define WIN32 1 7 | #endif 8 | #include 9 | #include 10 | #endif 11 | 12 | template 13 | class MultiHeap : public Super { 14 | public: 15 | 16 | inline void * malloc (size_t sz) { 17 | // Hash the thread id. 18 | // We assume that it's impossible for two threads to collide. 19 | int tid = getThreadId() % NumHeaps; 20 | void * ptr = mySuper[tid].malloc (sz + sizeof(double)); 21 | *((int *) ptr) = tid; 22 | void * newPtr = (void *) ((double *) ptr + 1); 23 | return newPtr; 24 | } 25 | 26 | inline void free (void * ptr) { 27 | // Return the object to its own heap. 28 | void * originalPtr = (void *) ((double *) ptr - 1); 29 | int heapIndex = *((int *) originalPtr); 30 | // FIX ME! A 'cache' would be nice here... 31 | // FIX ME! We need a lock here. 32 | mySuper[heapIndex].free (originalPtr); 33 | } 34 | 35 | private: 36 | 37 | Super mySuper[NumHeaps]; 38 | 39 | int getThreadId (void) { 40 | #if WIN32 41 | return GetCurrentThreadId(); 42 | #endif 43 | } 44 | 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /heaplayers/experimental/multimalloc.h: -------------------------------------------------------------------------------- 1 | #ifndef _MULTIMALLOC_H_ 2 | #define _MULTIMALLOC_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | #include "dynarray.h" 10 | #include "stack.h" 11 | 12 | 13 | template 14 | class MultiMalloc : public SuperHeap { 15 | public: 16 | 17 | 18 | MultiMalloc (void) { 19 | //f.open ("multimalloc.log"); 20 | } 21 | 22 | ~MultiMalloc (void) { 23 | //f.close (); 24 | } 25 | 26 | // Sets ptr to a list of up to num objects of size sz 27 | // and returns how many free objects ptr points to. 28 | int multimalloc (int num, size_t sz, void *& ptr) 29 | { 30 | //f << "multimalloc from " << this << endl << flush; 31 | // printf ("multimalloc\n"); 32 | assert (num > 0); 33 | if (stk.empty()) { 34 | #if 0 35 | //f << "malloc " << num << ", " << sz << "\n" << flush; 36 | ptr = SuperHeap::malloc (sz); 37 | assert (size(ptr) >= sz); 38 | assert (sz >= sizeof(FreeObject *)); 39 | FreeObject * p = (FreeObject *) ptr; 40 | for (int i = 1; i < num; i++) { 41 | p->next = (FreeObject *) SuperHeap::malloc (sz); 42 | p = p->next; 43 | assert (size(p) >= sz); 44 | } 45 | p->next = NULL; 46 | #else 47 | size_t sz1 = align(sz + sizeof(double)); 48 | ptr = SuperHeap::malloc (num * sz1); // Allow room for size & thread info. 49 | ptr = (double *) ptr + 1; 50 | FreeObject * p = (FreeObject *) ptr; 51 | for (int i = 0; i < num - 1; i++) { 52 | size(p) = sz; 53 | FreeObject * next = (FreeObject *) (((unsigned long) p) + sz1); 54 | p->next = next; 55 | p = p->next; 56 | } 57 | size(p) = sz; 58 | p->next = NULL; 59 | assert (size(p) + ((unsigned long) p) <= ((unsigned long) ptr + num * sz1)); 60 | #endif 61 | 62 | #ifndef NDEBUG 63 | p = (FreeObject *) ptr; 64 | int c = 0; 65 | while (p != NULL) { 66 | c++; 67 | p = p->next; 68 | } 69 | assert (c == num); 70 | #endif 71 | return num; 72 | } else { 73 | // Pop off some memory from the stack. 74 | assert (!stk.empty()); 75 | np v = stk.pop(); 76 | // JUST FOR CHECKING -- 77 | assert (v.num == num); 78 | ptr = v.ptr; 79 | assert (v.num > 0); 80 | assert (size(ptr) >= sz); 81 | //f << "multimalloc " << v.num << ", " << sz << "\n" << flush; 82 | return v.num; 83 | } 84 | } 85 | 86 | // Frees all num items pointed to by ptr. 87 | void multifree (int num, void * ptr) 88 | { 89 | // printf ("multifree\n"); 90 | np v; 91 | //f << "multifree " << num << ", size = " << size(ptr) << "\n" << flush; 92 | v.num = num; 93 | v.ptr = ptr; 94 | stk.push (v); 95 | } 96 | 97 | private: 98 | 99 | MultiMalloc (const MultiMalloc&); 100 | MultiMalloc& operator=(const MultiMalloc&); 101 | 102 | class np { 103 | public: 104 | int num; 105 | void * ptr; 106 | }; 107 | 108 | class FreeObject { 109 | public: 110 | FreeObject * next; 111 | }; 112 | 113 | void * malloc (size_t); 114 | void free (void *); 115 | 116 | Stack > stk; 117 | //ofstream f; 118 | 119 | static inline size_t align (size_t sz) { 120 | return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1); 121 | } 122 | 123 | }; 124 | 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /heaplayers/experimental/pad.h: -------------------------------------------------------------------------------- 1 | #ifndef _PAD_H_ 2 | #define _PAD_H_ 3 | 4 | 5 | // Add a cache-pad to an object. 6 | 7 | template 8 | class Pad : public Super { 9 | private: 10 | // Add a pad field with a name that is unlikely 11 | // to conflict with a real field name. 12 | char _pad_QWERTYUIOP1234567890[CacheLineSize]; 13 | }; 14 | 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /heaplayers/experimental/prefetchheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _PREFETCHHEAP_H_ 4 | #define _PREFETCHHEAP_H_ 5 | 6 | #define prefetcht0 __asm _emit 0x0f __asm _emit 0x18 __asm _emit 0x08 7 | 8 | 9 | template 10 | class PrefetchHeap : public Super { 11 | public: 12 | 13 | inline void * malloc (size_t sz) { 14 | void * Address = Super::malloc (sz); 15 | #ifdef _M_IX86 16 | // Prefetch this ptr before we return. 17 | __asm 18 | { 19 | mov eax,Address // Load Address. 20 | prefetcht0 // Prefetch into the L1. 21 | } 22 | #endif 23 | return Address; 24 | } 25 | 26 | inline void free (void * ptr) { 27 | Super::free (ptr); 28 | } 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /heaplayers/experimental/scalableleaheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCALABLELEAHEAP_H_ 2 | #define _SCALABLELEAHEAP_H_ 3 | 4 | #include "heaplayers.h" 5 | 6 | namespace ScalableHeapNS { 7 | 8 | template 9 | class GlobalHeapWrapper : public SuperHeap { 10 | public: 11 | inline void * malloc (size_t sz) { 12 | void * ptr = SuperHeap::malloc (sz); 13 | if (ptr != NULL) { 14 | assert (!isFree(ptr)); 15 | } 16 | return ptr; 17 | } 18 | inline void free (void * ptr) { 19 | // Set this object's heap to an unassigned heap (NumHeaps), 20 | // then free it. 21 | setHeap (ptr, NumHeaps); // This should be an unassigned heap number. 22 | assert (getHeap(ptr) == NumHeaps); 23 | setPrevHeap(getNext(ptr), NumHeaps); 24 | assert (getPrevHeap(getNext(ptr)) == NumHeaps); 25 | SuperHeap::free (ptr); 26 | } 27 | private: 28 | inline int remove (void *); 29 | }; 30 | 31 | 32 | template 33 | class TryHeap : public Heap2 { 34 | public: 35 | TryHeap (void) 36 | : reserved (0) 37 | {} 38 | 39 | inline void * malloc (size_t sz) { 40 | void * ptr = heap1.malloc (sz); 41 | if (ptr == NULL) { 42 | #if 1 43 | // Get a big chunk. 44 | size_t chunkSize = (Threshold / 2) > sz ? (Threshold / 2) : sz; 45 | ptr = Heap2::malloc (chunkSize); 46 | if (ptr == NULL) { 47 | return NULL; 48 | } 49 | // Split it. 50 | void * splitPiece = CoalesceHeap::split (ptr, sz); 51 | assert (splitPiece != ptr); 52 | assert (!isFree(ptr)); 53 | // Put the split piece on heap 1. 54 | if (splitPiece != NULL) { 55 | reserved += getSize(splitPiece); 56 | heap1.free (splitPiece); 57 | } 58 | #else 59 | ptr = Heap2::malloc (sz); 60 | #endif 61 | } else { 62 | reserved -= getSize(ptr); 63 | } 64 | // assert (getHeap(ptr) == tid); 65 | return ptr; 66 | } 67 | inline void free (void * ptr) { 68 | reserved += getSize(ptr); 69 | heap1.free (ptr); 70 | if (reserved > Threshold) { 71 | // We've crossed the threshold. 72 | // Free objects from heap 1 and give them to heap 2. 73 | // Start big. 74 | size_t sz = Threshold / 2; 75 | while ((sz > sizeof(double)) && (reserved > Threshold / 2)) { 76 | void * p = NULL; 77 | while ((p == NULL) && (sz >= sizeof(double))) { 78 | p = heap1.malloc (sz); 79 | if (p == NULL) { 80 | sz >>= 1; 81 | } 82 | } 83 | if (p != NULL) { 84 | reserved -= getSize(p); 85 | Heap2::free (p); 86 | } 87 | } 88 | } 89 | } 90 | 91 | 92 | private: 93 | inline int remove (void * ptr); 94 | #if 0 95 | { 96 | assert (0); 97 | abort(); 98 | } 99 | #endif 100 | 101 | Heap1 heap1; 102 | int reserved; 103 | }; 104 | 105 | 106 | template 107 | class SmallHeap : public 108 | ScalableHeapNS::TryHeap, 110 | MarkThreadHeap > > {}; 111 | 112 | template 113 | class MTHeap : 114 | public PHOThreadHeap > > {}; 116 | 117 | }; 118 | 119 | 120 | template 121 | class ScalableHeap : 122 | public SelectMmapHeap<128 * 1024, 123 | ScalableHeapNS::MTHeap, 124 | LockedHeap > {}; 125 | #endif 126 | -------------------------------------------------------------------------------- /heaplayers/experimental/sizethreadheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _SIZETHREADHEAP_H_ 4 | #define _SIZETHREADHEAP_H_ 5 | 6 | #include 7 | 8 | template 9 | class SizeThreadHeap : public Super { 10 | public: 11 | 12 | inline void * malloc (size_t sz) { 13 | // Add room for a size field & a thread field. 14 | // Both of these must fit in a double. 15 | assert (sizeof(st) <= sizeof(double)); 16 | st * ptr = (st *) Super::malloc (sz + sizeof(double)); 17 | // Store the requested size. 18 | ptr->size = sz; 19 | assert (getOrigPtr(ptr + 1) == ptr); 20 | return (void *) (ptr + 1); 21 | } 22 | 23 | inline void free (void * ptr) { 24 | void * origPtr = (void *) getOrigPtr(ptr); 25 | Super::free (origPtr); 26 | } 27 | 28 | static inline volatile int getThreadId (void); 29 | 30 | static inline size_t& size (void * ptr) { 31 | return getOrigPtr(ptr)->size; 32 | } 33 | 34 | static inline int& thread (void * ptr) { 35 | return getOrigPtr(ptr)->tid; 36 | } 37 | 38 | private: 39 | 40 | typedef struct _st { 41 | size_t size; 42 | int tid; 43 | } st; 44 | 45 | static inline st * getOrigPtr (void * ptr) { 46 | return (st *) ((double *) ptr - 1); 47 | } 48 | 49 | }; 50 | 51 | 52 | 53 | // A platform-dependent way to get a thread id. 54 | 55 | // Include the necessary platform-dependent crud. 56 | #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) 57 | #ifndef WIN32 58 | #define WIN32 1 59 | #endif 60 | #include 61 | #include 62 | #endif 63 | 64 | template 65 | inline volatile int 66 | SizeThreadHeap::getThreadId (void) { 67 | #if defined(WIN32) 68 | return GetCurrentThreadId(); 69 | #endif 70 | #if defined(__BEOS__) 71 | return find_thread(0); 72 | #endif 73 | #if defined(__linux) 74 | // Consecutive thread id's in Linux are 1024 apart; 75 | // dividing off the 1024 gives us an appropriate thread id. 76 | return (int) pthread_self() >> 10; // (>> 10 = / 1024) 77 | #endif 78 | #if defined(__SVR4) 79 | return (int) lwp_self(); 80 | #endif 81 | #if defined(POSIX) // FIX ME?? 82 | return (int) pthread_self(); 83 | #endif 84 | #if USE_SPROC // FIX ME 85 | // This hairiness has the same effect as calling getpid(), 86 | // but it's MUCH faster since it avoids making a system call 87 | // and just accesses the sproc-local data directly. 88 | int pid = (int) PRDA->sys_prda.prda_sys.t_pid; 89 | return pid; 90 | #endif 91 | } 92 | 93 | 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /heaplayers/experimental/slotheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _SLOTHEAP_H_ 4 | #define _SLOTHEAP_H_ 5 | 6 | // NOTE: All size requests to malloc must be identical! 7 | 8 | /* 9 | 10 | A "slot" allocator. 11 | 12 | All allocations come from a fixed-size chunk of memory 13 | that is carved into a number of pieces. 14 | 15 | The "chunk" class must support the following methods: 16 | 17 | void * getSlot (void); // Returns NULL if there is no slot left. 18 | void putSlot (void *); // Puts a slot back into its chunk. 19 | 20 | */ 21 | 22 | #include 23 | 24 | #include "chunkheap.h" 25 | 26 | /* A "slot" heap. 27 | 28 | This heap reserves exactly one "chunk" that is divided into 29 | a number of fixed-size slots. When the chunk is used up, 30 | the heap requests another one. */ 31 | 32 | template 33 | class SlotInterface; 34 | 35 | template 36 | class SlotHeap : public SlotInterface >{}; 37 | 38 | template 39 | class SlotInterface : public Super { 40 | public: 41 | 42 | SlotInterface (void) 43 | : currentChunk (new (Super::malloc(chunkSize)) Chunk) 44 | {} 45 | 46 | inline void * malloc (size_t sz) { 47 | assert (sz == slotSize); 48 | // Use up all of the slots in one chunk, 49 | // and get another chunk if we need one. 50 | void * ptr = currentChunk->getSlot(); 51 | if (ptr == NULL) { 52 | // This chunk is empty -- get another one. 53 | currentChunk = new (Super::malloc(chunkSize)) Chunk; 54 | ptr = currentChunk->getSlot(); 55 | } 56 | assert (ptr != NULL); 57 | return ptr; 58 | } 59 | 60 | inline void free (void * ptr) { 61 | // If this object belongs to "our" chunk, 62 | // free it directly; otherwise, pass it up. 63 | if (getChunk(ptr) == currentChunk) { 64 | currentChunk->putSlot (ptr); 65 | } else { 66 | Super::free (ptr); 67 | } 68 | } 69 | 70 | private: 71 | 72 | Chunk * currentChunk; 73 | 74 | }; 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /heaplayers/experimental/splitheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _SPLITHEAP_H_ 2 | #define _SPLITHEAP_H_ 3 | 4 | template 5 | class SplitHeap : public SuperHeap { 6 | public: 7 | inline void * malloc (const size_t sz) 8 | { 9 | void * ptr = SuperHeap::malloc (sz); 10 | if (ptr != NULL) { 11 | markInUse (ptr); 12 | size_t oldSize = getSize(ptr); 13 | if (oldSize <= sz + sizeof(double)) { 14 | return ptr; 15 | } else { 16 | void * splitPiece = split (ptr, sz); 17 | if (splitPiece != NULL) { 18 | // printf ("split %d into %d and %d\n", oldSize, getSize(ptr), getSize(splitPiece)); 19 | markFree (splitPiece); 20 | SuperHeap::free (splitPiece); 21 | } 22 | } 23 | } 24 | return ptr; 25 | } 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /heaplayers/experimental/strictslotheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _LAZYSLOTHEAP_H_ 4 | #define _LAZYSLOTHEAP_H_ 5 | 6 | /* 7 | This heap manages memory in units of Chunks. 8 | malloc returns a slot within a chunk, 9 | while free returns slots back to a chunk. 10 | 11 | We completely exhaust the first chunk before we ever get another one. 12 | Once a chunk is COMPLETELY empty, it is returned to the superheap. 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | #include "chunk.h" 19 | 20 | template 21 | class LazySlotHeap : public Super { 22 | public: 23 | 24 | LazySlotHeap (void) 25 | : myChunk (new (Super::malloc (chunkSize)) Chunk()) 26 | {} 27 | 28 | virtual ~LazySlotHeap (void) 29 | { 30 | // Give up our chunk. 31 | Super::free (myChunk); 32 | } 33 | 34 | inline void * malloc (size_t sz) { 35 | assert (sz <= chunkSize); 36 | void * ptr = myChunk->getSlot(); 37 | if (ptr == NULL) { 38 | myChunk = new (Super::malloc (chunkSize)) Chunk(); 39 | ptr = myChunk->getSlot(); 40 | assert (ptr != NULL); 41 | } 42 | return ptr; 43 | } 44 | 45 | inline void free (void * ptr) { 46 | /// Return a slot to its chunk. 47 | Chunk * ch = Chunk::getChunk (ptr); 48 | ch->putSlot (ptr); 49 | // Once the chunk is completely empty, free it. 50 | if (ch->getNumSlotsAvailable() == ch->getNumSlots()) { 51 | if (ch == myChunk) { 52 | // If this was 'our' chunk, get another one. 53 | myChunk = new (Super::malloc (chunkSize)) Chunk(); 54 | } 55 | Super::free (ch); 56 | } 57 | } 58 | 59 | protected: 60 | 61 | inline static size_t size (void * ptr) 62 | { 63 | return slotSize; 64 | } 65 | 66 | 67 | private: 68 | 69 | Chunk * myChunk; 70 | 71 | }; 72 | 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /heaplayers/experimental/theap.h: -------------------------------------------------------------------------------- 1 | #ifndef _THEAP_H_ 2 | #define _THEAP_H_ 3 | 4 | // A general threshold-based heap. 5 | 6 | // Threshold layer. 7 | // Once we have more than Threshold bytes on our freelist, 8 | // return memory to the superheap. 9 | 10 | // The class argument FH should be some freelist heap that subclasses NullHeap. 11 | 12 | template 13 | class THeap : public SuperHeap { 14 | public: 15 | THeap (void) 16 | : total (0) 17 | {} 18 | 19 | ~THeap (void) 20 | {} 21 | 22 | inline void * malloc (size_t sz) { 23 | void * ptr; 24 | ptr = fHeap.malloc (sz); 25 | if (ptr == NULL) { 26 | // We have no memory on our freelist. 27 | // Get it from the superheap. 28 | ptr = SuperHeap::malloc (sz); 29 | } else { 30 | total -= size(ptr); 31 | // printf ("total = %d\n", total); 32 | } 33 | assert (size(ptr) >= sz); 34 | return ptr; 35 | } 36 | 37 | inline void free (void * ptr) { 38 | if (total < Threshold) { 39 | // printf ("FREE TO FREELIST.\n"); 40 | total += size(ptr); 41 | fHeap.free (ptr); 42 | //printf ("total = %d\n", total); 43 | } else { 44 | // Dump the freelist heap. 45 | void * p = fHeap.malloc (1); 46 | while (p != NULL) { 47 | SuperHeap::free (p); 48 | p = fHeap.malloc (1); 49 | } 50 | SuperHeap::free (ptr); 51 | total = 0; 52 | } 53 | } 54 | 55 | private: 56 | // Provide a free list that will return NULL if it is out of memory. 57 | FH fHeap; 58 | int total; 59 | }; 60 | 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /heaplayers/experimental/thinlock.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #ifndef _THINLOCK_H_ 4 | #define _THINLOCK_H_ 5 | 6 | #include 7 | 8 | class ThinLock { 9 | public: 10 | 11 | ThinLock (void) 12 | { 13 | InitializeCriticalSection (&crit); 14 | } 15 | 16 | inline void lock (void) { 17 | EnterCriticalSection (&crit); 18 | } 19 | 20 | inline void unlock (void) { 21 | LeaveCriticalSection (&crit); 22 | } 23 | 24 | private: 25 | CRITICAL_SECTION crit; 26 | }; 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /heaplayers/experimental/topslotheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _TOPSLOTHEAP_H_ 4 | #define _TOPSLOTHEAP_H_ 5 | 6 | #include 7 | 8 | #include "bigchunk.h" 9 | 10 | /* 11 | TopSlotHeap. 12 | 13 | malloc returns objects of size chunkSize. 14 | 15 | free returns objects of size chunkSize. 16 | 17 | */ 18 | 19 | template 20 | class TopSlotHeap : public Super { 21 | public: 22 | 23 | TopSlotHeap (void) 24 | : myChunks (NULL) 25 | {} 26 | 27 | // Get a chunkSize object. 28 | inline void * malloc (size_t sz); 29 | 30 | // Free a chunkSize object. 31 | inline void free (void * ptr); 32 | 33 | protected: 34 | 35 | virtual inline void localFree (void * ptr); 36 | 37 | 38 | private: 39 | 40 | BigChunk * myChunks; 41 | 42 | }; 43 | 44 | 45 | template 46 | void * TopSlotHeap::malloc (size_t sz) 47 | { 48 | assert (sz <= chunkSize); 49 | if (myChunks == NULL) { 50 | return new (Super::malloc (chunkSize)) BigChunk; 51 | } else { 52 | printf ("Recycled a chunk.\n"); 53 | BigChunk * ch = myChunks; 54 | myChunks = myChunks->getNext(); 55 | ch->setNext (NULL); 56 | ch->setHeap (NULL); 57 | return ch; 58 | } 59 | } 60 | 61 | 62 | template 63 | void TopSlotHeap::free (void * ptr) { 64 | printf ("Freed a chunk.\n"); 65 | BigChunk * ch = (BigChunk *) ptr; 66 | ch->setNext (myChunks); 67 | ch->setHeap (this); 68 | myChunks = ch; 69 | } 70 | 71 | 72 | template 73 | void TopSlotHeap::localFree (void * ptr) { 74 | free (ptr); 75 | } 76 | 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /heaplayers/fifodlfreelist.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _FIFODLFREELIST_H_ 4 | #define _FIFODLFREELIST_H_ 5 | 6 | #include 7 | 8 | template 9 | class FIFODLFreelistHeap : public Super { 10 | public: 11 | 12 | FIFODLFreelistHeap (void) 13 | { 14 | head.prev = &head; 15 | head.next = &tail; 16 | tail.prev = &head; 17 | tail.next = &tail; 18 | assert (isEmpty()); 19 | } 20 | 21 | ~FIFODLFreelistHeap (void) 22 | { 23 | // Delete everything on the free list. 24 | freeObject * ptr = head.next; 25 | while (ptr != &tail) { 26 | void * oldptr = ptr; 27 | ptr = ptr->next; 28 | Super::free (oldptr); 29 | } 30 | } 31 | 32 | inline void * malloc (size_t sz) { 33 | //printf ("flist malloc %d\n", sz); 34 | // Check the free list first. 35 | freeObject * ptr = tail.prev; 36 | if (ptr == &head) { 37 | assert (isEmpty()); 38 | ptr = (freeObject *) Super::malloc (sz); 39 | } else { 40 | ptr->prev->next = &tail; 41 | tail.prev = ptr->prev; 42 | #if 0 43 | ptr->prev = NULL; 44 | ptr->next = NULL; 45 | #endif 46 | } 47 | assert (getSize(ptr) >= sz); 48 | assert (getSize(ptr) >= sizeof(freeObject)); 49 | return (void *) ptr; 50 | } 51 | 52 | inline void free (void * ptr) { 53 | // Add this object to the free list. 54 | assert (ptr != NULL); 55 | freeObject * p = (freeObject *) ptr; 56 | p->next = head.next; 57 | p->next->prev = p; 58 | p->prev = &head; 59 | head.next = p; 60 | assert (!isEmpty()); 61 | } 62 | 63 | #if 0 64 | // Returns the entire linked list of freed objects. 65 | inline void * multimalloc (size_t sz) { 66 | freeObject * ptr = head.next; 67 | ptr->prev = NULL; 68 | tail.prev->next = NULL; 69 | head.next = &tail; 70 | tail.prev = &head; 71 | return ptr; 72 | } 73 | #endif 74 | 75 | inline static void remove (void * rptr) 76 | { 77 | freeObject * p = (freeObject *) rptr; 78 | assert (p->next != NULL); 79 | assert (p->prev != NULL); 80 | p->prev->next = p->next; 81 | p->next->prev = p->prev; 82 | p->prev = p->next = NULL; 83 | } 84 | 85 | 86 | private: 87 | 88 | int isEmpty (void) { 89 | return (head.next == &tail); 90 | } 91 | 92 | class freeObject { 93 | public: 94 | freeObject * prev; 95 | freeObject * next; 96 | }; 97 | 98 | freeObject head, tail; 99 | }; 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /heaplayers/fifofreelist.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _FIFOFREELIST_H_ 4 | #define _FIFOFREELIST_H_ 5 | 6 | #include 7 | 8 | #ifdef NDEBUG 9 | #define IFDEBUG(x) 10 | #else 11 | #define IFDEBUG(x) x 12 | #endif 13 | 14 | 15 | template 16 | class FIFOFreelistHeap : public SuperHeap { 17 | public: 18 | 19 | FIFOFreelistHeap (void) 20 | IFDEBUG(: nObjects (0)) 21 | { 22 | head.next = &tail; 23 | tail.next = &tail; 24 | assert (isEmpty()); 25 | } 26 | 27 | ~FIFOFreelistHeap (void) 28 | { 29 | // printf ("Adios free list.\n"); 30 | // Delete everything on the free list. 31 | freeObject * ptr = head.next; 32 | while (ptr != &tail) { 33 | void * oldptr = ptr; 34 | ptr = ptr->next; 35 | SuperHeap::free (oldptr); 36 | } 37 | } 38 | 39 | inline void * malloc (size_t sz) { 40 | assert (isValid()); 41 | // Check the free list first. 42 | freeObject * ptr = head.next; 43 | if (ptr == &tail) { 44 | assert (nObjects == 0); 45 | assert (isEmpty()); 46 | ptr = (freeObject *) SuperHeap::malloc (sz); 47 | } else { 48 | assert (nObjects > 0); 49 | head.next = ptr->next; 50 | if (head.next == &tail) { 51 | tail.next = &tail; 52 | } 53 | IFDEBUG (nObjects--); 54 | } 55 | assert (isValid()); 56 | return (void *) ptr; 57 | } 58 | 59 | inline void free (void * ptr) { 60 | assert (isValid()); 61 | // Add this object to the free list. 62 | assert (ptr != NULL); 63 | IFDEBUG (nObjects++); 64 | freeObject * p = (freeObject *) ptr; 65 | p->next = &tail; 66 | tail.next->next = p; 67 | tail.next = p; 68 | if (head.next == &tail) { 69 | head.next = p; 70 | } 71 | assert (!isEmpty()); 72 | assert (isValid()); 73 | } 74 | 75 | private: 76 | 77 | int isValid (void) { 78 | // Make sure every object is the right size. 79 | freeObject * ptr = head.next; 80 | if (ptr != &tail) { 81 | size_t sz = SuperHeap::getSize(ptr); 82 | while (ptr != &tail) { 83 | void * oldptr = ptr; 84 | ptr = ptr->next; 85 | assert (SuperHeap::getSize(oldptr) >= sz); 86 | } 87 | } 88 | return 1; 89 | } 90 | 91 | int isEmpty (void) { 92 | return (head.next == &tail); 93 | } 94 | 95 | class freeObject { 96 | public: 97 | freeObject * prev; 98 | freeObject * next; 99 | }; 100 | 101 | freeObject head, tail; 102 | IFDEBUG (int nObjects); 103 | }; 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /heaplayers/firstfitheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _FIRSTFITHEAP_H_ 4 | #define _FIRSTFITHEAP_H_ 5 | 6 | template 7 | class FirstFitHeap : public Super { 8 | public: 9 | 10 | FirstFitHeap (void) 11 | : myFreeList (NULL) 12 | #ifndef NDEBUG 13 | ,nObjects (0) 14 | #endif 15 | { 16 | assert (classInvariant()); 17 | } 18 | 19 | ~FirstFitHeap (void) 20 | { 21 | #if 1 22 | // Delete everything on the free list. 23 | void * ptr = myFreeList; 24 | while (ptr != NULL) { 25 | // assert (nObjects > 0); 26 | assert (ptr != NULL); 27 | void * oldptr = ptr; 28 | ptr = (void *) ((freeObject *) ptr)->next; 29 | Super::free (oldptr); 30 | #ifndef NDEBUG 31 | --nObjects; 32 | #endif 33 | } 34 | #endif 35 | } 36 | 37 | inline void * malloc (size_t sz) { 38 | // Check the free list first. 39 | assert (classInvariant()); 40 | void * ptr = myFreeList; 41 | if (ptr == NULL) { 42 | assert (nObjects == 0); 43 | ptr = Super::malloc (sz); 44 | } else { 45 | assert (nObjects > 0); 46 | freeObject * p = myFreeList; 47 | freeObject * prev = NULL; 48 | while ((p != NULL) && (getSize((void *) p) < sz)) { 49 | prev = p; 50 | p = p->next; 51 | } 52 | if (p == NULL) { 53 | ptr = Super::malloc (sz); 54 | } else { 55 | assert (getSize((void *) p) >= sz); 56 | if (prev == NULL) { 57 | myFreeList = p->next; 58 | } else { 59 | assert (prev->next == p); 60 | prev->next = p->next; 61 | } 62 | #ifndef NDEBUG 63 | nObjects--; 64 | #endif 65 | ptr = p; 66 | } 67 | } 68 | assert (classInvariant()); 69 | return ptr; 70 | } 71 | 72 | inline void free (void * ptr) { 73 | // Add this object to the free list. 74 | assert (ptr != NULL); 75 | assert (classInvariant()); 76 | #ifndef NDEBUG 77 | nObjects++; 78 | #endif 79 | freeObject * p = myFreeList; 80 | freeObject * prev = NULL; 81 | // Insert the object "in order". 82 | #if 1 83 | while ((p != NULL) & (p <= ptr)) { 84 | prev = p; 85 | p = p->next; 86 | } 87 | #endif 88 | if (prev == NULL) { 89 | ((freeObject *) ptr)->next = myFreeList; 90 | myFreeList = (freeObject *) ptr; 91 | } else { 92 | ((freeObject *) ptr)->next = prev->next; 93 | prev->next = (freeObject *) ptr; 94 | } 95 | assert (classInvariant()); 96 | } 97 | 98 | private: 99 | 100 | int classInvariant (void) { 101 | return (((myFreeList == NULL) && (nObjects == 0)) 102 | || ((myFreeList != NULL) && (nObjects > 0))); 103 | } 104 | 105 | class freeObject { 106 | public: 107 | freeObject * next; 108 | }; 109 | 110 | freeObject * myFreeList; 111 | #ifndef NDEBUG 112 | int nObjects; 113 | #endif 114 | 115 | }; 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /heaplayers/fixedsizeheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _FIXEDSIZEHEAP_H_ 2 | #define _FIXEDSIZEHEAP_H_ 3 | 4 | 5 | template 6 | class FixedSizeHeap : public SH { 7 | public: 8 | inline void * malloc (size_t sz) { 9 | assert (sz <= Size); 10 | //printf ("malloc\n"); 11 | return SH::malloc (Size); 12 | } 13 | inline void free (void * ptr) { 14 | //printf ("free\n"); 15 | SH::free (ptr); 16 | } 17 | protected: 18 | inline static size_t size (void * p) { 19 | return Size; 20 | } 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /heaplayers/freelistheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _FREELISTHEAP_H_ 4 | #define _FREELISTHEAP_H_ 5 | 6 | /** 7 | * @class FreelistHeap 8 | * @brief Manage freed memory on a linked list. 9 | * @warning This is for one "size class" only. 10 | * 11 | * Note that the linked list is threaded through the freed objects, 12 | * meaning that such objects must be at least the size of a pointer. 13 | */ 14 | 15 | #include "freesllist.h" 16 | #include 17 | 18 | namespace HL { 19 | 20 | template 21 | class FreelistHeap : public SuperHeap { 22 | public: 23 | 24 | FreelistHeap (void) 25 | { 26 | } 27 | 28 | inline void * malloc (size_t sz) { 29 | // Check the free list first. 30 | void * ptr = _freelist.get(); 31 | // If it's empty, get more memory; 32 | // otherwise, advance the free list pointer. 33 | if (ptr == 0) { 34 | ptr = SuperHeap::malloc (sz); 35 | } 36 | return ptr; 37 | } 38 | 39 | inline void free (void * ptr) { 40 | if (ptr == 0) { 41 | return; 42 | } 43 | _freelist.insert (ptr); 44 | } 45 | 46 | inline void clear (void) { 47 | void * ptr; 48 | while (ptr = _freelist.get()) { 49 | SuperHeap::free (ptr); 50 | } 51 | } 52 | 53 | private: 54 | 55 | FreeSLList _freelist; 56 | 57 | }; 58 | 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /heaplayers/freesllist.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #ifndef _FREESLLIST_H_ 4 | #define _FREESLLIST_H_ 5 | 6 | #include 7 | 8 | /** 9 | * @class FreeSLList 10 | * @brief A "memory neutral" singly-linked list, 11 | * 12 | * Uses the free space in objects to store 13 | * the pointers. 14 | */ 15 | 16 | 17 | class FreeSLList { 18 | public: 19 | 20 | inline void clear (void) { 21 | head.next = NULL; 22 | } 23 | 24 | class Entry; 25 | 26 | /// Get the head of the list. 27 | inline Entry * get (void) { 28 | const Entry * e = head.next; 29 | if (e == NULL) { 30 | return NULL; 31 | } 32 | head.next = e->next; 33 | return const_cast(e); 34 | } 35 | 36 | inline Entry * remove (void) { 37 | const Entry * e = head.next; 38 | if (e == NULL) { 39 | return NULL; 40 | } 41 | head.next = e->next; 42 | return const_cast(e); 43 | } 44 | 45 | inline void insert (void * e) { 46 | Entry * entry = reinterpret_cast(e); 47 | entry->next = head.next; 48 | head.next = entry; 49 | } 50 | 51 | class Entry { 52 | public: 53 | Entry (void) 54 | : next (NULL) 55 | {} 56 | Entry * next; 57 | #if 0 58 | private: 59 | Entry (const Entry&); 60 | Entry& operator=(const Entry&); 61 | #endif 62 | }; 63 | 64 | private: 65 | Entry head; 66 | }; 67 | 68 | 69 | #endif 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /heaplayers/gnuwrapper.cpp: -------------------------------------------------------------------------------- 1 | #ifndef __GNUC__ 2 | #error "This file requires the GNU compiler." 3 | #endif 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define CUSTOM_PREFIX(n) _custom##n 11 | #include "libhoard.cpp" 12 | 13 | extern "C" { 14 | 15 | void * CUSTOM_PREFIX(malloc) (size_t); 16 | void CUSTOM_PREFIX(free) (void *); 17 | void * CUSTOM_PREFIX(realloc) (void *, size_t); 18 | void * CUSTOM_PREFIX(memalign) (size_t, size_t); 19 | 20 | static void my_init_hook (void); 21 | 22 | // New hooks for allocation functions. 23 | static void * my_malloc_hook (size_t, const void *); 24 | static void my_free_hook (void *, const void *); 25 | static void * my_realloc_hook (void *, size_t, const void *); 26 | static void * my_memalign_hook (size_t, size_t, const void *); 27 | 28 | // Store the old hooks just in case. 29 | static void * (*old_malloc_hook) (size_t, const void *); 30 | static void (*old_free_hook) (void *, const void *); 31 | static void *(*old_realloc_hook)(void *ptr, size_t size, const void *caller); 32 | static void *(*old_memalign_hook)(size_t alignment, size_t size, const void *caller); 33 | 34 | void (*__malloc_initialize_hook) (void) = my_init_hook; 35 | 36 | static void my_init_hook (void) { 37 | // Store the old hooks. 38 | old_malloc_hook = __malloc_hook; 39 | old_free_hook = __free_hook; 40 | old_realloc_hook = __realloc_hook; 41 | old_memalign_hook = __memalign_hook; 42 | 43 | // Point the hooks to the replacement functions. 44 | __malloc_hook = my_malloc_hook; 45 | __free_hook = my_free_hook; 46 | __realloc_hook = my_realloc_hook; 47 | __memalign_hook = my_memalign_hook; 48 | 49 | } 50 | 51 | // static size_t counter = 0; 52 | 53 | static void * my_malloc_hook (size_t size, const void * caller) { 54 | void * result; 55 | // fprintf (stderr, "malloc\n"); 56 | #if 0 57 | counter++; 58 | if (counter > 900000) 59 | abort(); 60 | #endif 61 | result = CUSTOM_PREFIX(malloc) (size); 62 | return result; 63 | } 64 | 65 | static void my_free_hook (void * ptr, const void * caller) { 66 | CUSTOM_PREFIX(free) (ptr); 67 | } 68 | 69 | static void * my_realloc_hook (void * ptr, size_t size, const void * caller) { 70 | return CUSTOM_PREFIX(realloc) (ptr, size); 71 | } 72 | 73 | static void * my_memalign_hook (size_t size, size_t alignment, const void * caller) { 74 | return CUSTOM_PREFIX(memalign) (size, alignment); 75 | } 76 | 77 | #if 0 78 | void finalizer (void) __attribute__((destructor)); 79 | 80 | void finalizer (void) { 81 | printf ("counter = %d\n", counter); 82 | } 83 | #endif 84 | 85 | } 86 | 87 | -------------------------------------------------------------------------------- /heaplayers/hldefines.h: -------------------------------------------------------------------------------- 1 | #ifndef _HLDEFINES_H_ 2 | #define _HLDEFINES_H_ 3 | 4 | /* 5 | * @file hldefines.h 6 | * @brief Defines macros used throughout Heap Layers. 7 | * 8 | */ 9 | 10 | // Define HL_EXECUTABLE_HEAP as 1 if you want that (i.e., you're doing 11 | // dynamic code generation). 12 | 13 | #define HL_EXECUTABLE_HEAP 0 14 | 15 | #if defined(_MSC_VER) 16 | 17 | // Microsoft Visual Studio 18 | #pragma inline_depth(255) 19 | #define INLINE __forceinline 20 | #define inline __forceinline 21 | #define NO_INLINE __declspec(noinline) 22 | #pragma warning(disable: 4530) 23 | #define MALLOC_FUNCTION 24 | #define RESTRICT 25 | 26 | #elif defined(__GNUC__) 27 | 28 | // GNU C 29 | 30 | #define NO_INLINE __attribute__ ((noinline)) 31 | #define INLINE inline 32 | #define MALLOC_FUNCTION __attribute__((malloc)) 33 | #define RESTRICT __restrict__ 34 | 35 | #else 36 | 37 | // All others 38 | 39 | #define NO_INLINE 40 | #define INLINE inline 41 | #define MALLOC_FUNCTION 42 | #define RESTRICT 43 | 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /heaplayers/hybridheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _HYBRIDHEAP_H_ 4 | #define _HYBRIDHEAP_H_ 5 | 6 | #include 7 | #include "sassert.h" 8 | #include "hldefines.h" 9 | 10 | /** 11 | * @class HybridHeap 12 | * Objects no bigger than BigSize are allocated and freed to SmallHeap. 13 | * Bigger objects are passed on to the super heap. 14 | */ 15 | 16 | namespace HL { 17 | 18 | template 19 | class HybridHeap : public SmallHeap { 20 | public: 21 | 22 | HybridHeap (void) 23 | { 24 | } 25 | 26 | enum { Alignment = ((int) SmallHeap::Alignment < (int) BigHeap::Alignment) ? 27 | (int) SmallHeap::Alignment : 28 | (int) BigHeap::Alignment }; 29 | 30 | MALLOC_FUNCTION INLINE void * malloc (size_t sz) { 31 | if (sz <= BigSize) { 32 | return SmallHeap::malloc (sz); 33 | } else { 34 | return slowPath (sz); 35 | } 36 | } 37 | 38 | inline void free (void * ptr) { 39 | if (SmallHeap::getSize(ptr) <= BigSize) { 40 | SmallHeap::free (ptr); 41 | } else { 42 | bm.free (ptr); 43 | } 44 | } 45 | 46 | inline void clear (void) { 47 | bm.clear(); 48 | SmallHeap::clear(); 49 | } 50 | 51 | 52 | private: 53 | 54 | MALLOC_FUNCTION NO_INLINE 55 | void * slowPath (size_t sz) { 56 | return bm.malloc (sz); 57 | } 58 | 59 | 60 | HL::sassert<(BigSize > 0)> checkBigSizeNonZero; 61 | 62 | BigHeap bm; 63 | }; 64 | 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /heaplayers/kingsleyheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _KINGSLEYHEAP_H_ 28 | #define _KINGSLEYHEAP_H_ 29 | 30 | #include "segheap.h" 31 | 32 | /** 33 | * @file kingsleyheap.h 34 | * @brief Classes to implement a Kingsley (power-of-two, segregated fits) allocator. 35 | */ 36 | 37 | /** 38 | * @namespace Kingsley 39 | * @brief Functions to implement KingsleyHeap. 40 | */ 41 | 42 | 43 | 44 | namespace Kingsley { 45 | 46 | size_t class2Size (const int i); 47 | 48 | #if defined(__sparc) && defined(__GNUC__) 49 | inline int popc (int v) { 50 | int r; 51 | asm volatile ("popc %1, %0" 52 | : "=r" (r) 53 | : "r" (v)); 54 | return r; 55 | } 56 | #endif 57 | 58 | /** 59 | * A speed optimization: 60 | * we use this array to quickly return the size class of objects 61 | * from 8 to 128 bytes. 62 | */ 63 | const int cl[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; 64 | 65 | inline int size2Class (size_t sz) { 66 | #if defined(__sparc) && defined(__GNUC__) 67 | // Adapted from _Hacker's Delight_, by Henry Warren (p.80) 68 | size_t x = sz; 69 | x = x | (x >> 1); 70 | x = x | (x >> 2); 71 | x = x | (x >> 4); 72 | x = x | (x >> 8); 73 | x = x | (x >> 16); 74 | return popc(x) - 3; 75 | #else 76 | if (sz < sizeof(double)) { 77 | sz = sizeof(double); 78 | } 79 | if (sz <= 128 ) { 80 | int index = (sz - 1) >> 3; 81 | int c = cl[index]; 82 | assert (class2Size(c) >= sz); 83 | return c; 84 | } else { 85 | // 86 | // We know that the object is more than 128 bytes long, 87 | // so we can avoid iterating 5 times. 88 | // 89 | int c = 5; 90 | size_t sz1 = ((sz - 1) >> 5); 91 | while (sz1 > 7) { 92 | sz1 >>= 1; 93 | c++; 94 | } 95 | assert (class2Size(c) >= sz); 96 | return c; 97 | } 98 | #endif 99 | 100 | } 101 | 102 | inline size_t class2Size (const int i) { 103 | return (size_t) (1UL << (i+3)); 104 | } 105 | 106 | enum { NUMBINS = 29 }; 107 | 108 | }; 109 | 110 | /** 111 | * @class KingsleyHeap 112 | * @brief The Kingsley-style allocator. 113 | * @param PerClassHeap The heap to use for each size class. 114 | * @param BigHeap The heap for "large" objects. 115 | * @see Kingsley 116 | */ 117 | 118 | namespace HL { 119 | 120 | template 121 | class KingsleyHeap : 122 | public StrictSegHeap {}; 127 | 128 | }; 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /heaplayers/leamallocheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _LEAMALLOCHEAP_H_ 28 | #define _LEAMALLOCHEAP_H_ 29 | 30 | #include 31 | 32 | /** 33 | * @class LeaMallocHeap 34 | * @brief A "source heap" that uses the Lea allocator. 35 | */ 36 | 37 | extern "C" void * dlmalloc (size_t); 38 | extern "C" void dlfree (void *); 39 | extern "C" size_t dlmalloc_usable_size (void *); 40 | 41 | namespace HL { 42 | 43 | class LeaMallocHeap { 44 | public: 45 | inline void * malloc (size_t sz) { 46 | void * ptr = dlmalloc (sz); 47 | return ptr; 48 | } 49 | 50 | inline void free (void * p) { 51 | dlfree (p); 52 | } 53 | 54 | inline size_t getSize (const void * p) { 55 | return dlmalloc_usable_size ((void *) p); 56 | } 57 | }; 58 | 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /heaplayers/localmallocheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOCALMALLOCHEAP_H_ 2 | #define _LOCALMALLOCHEAP_H_ 3 | 4 | #include 5 | 6 | #include "ansiwrapper.h" 7 | #include "sizeheap.h" 8 | #include "staticheap.h" 9 | 10 | extern "C" { 11 | size_t malloc_usable_size (void *); 12 | 13 | typedef void * mallocFunction (size_t); 14 | typedef void freeFunction (void *); 15 | typedef size_t msizeFunction (void *); 16 | 17 | typedef void exitFunction (int); 18 | exitFunction * trueExitFunction; 19 | } 20 | 21 | namespace HL { 22 | 23 | class LocalMallocHeap { 24 | public: 25 | 26 | LocalMallocHeap (void) 27 | : freefn (NULL), 28 | msizefn (NULL), 29 | mallocfn (NULL), 30 | firsttime (true) 31 | {} 32 | 33 | inline void * malloc (size_t sz) { 34 | if (firsttime) { 35 | 36 | firsttime = false; 37 | 38 | // We haven't initialized anything yet. 39 | // Initialize all of the malloc shim functions. 40 | 41 | freefn = (freeFunction *) dlsym (RTLD_NEXT, "free"); 42 | msizefn = (msizeFunction *) dlsym (RTLD_NEXT, "malloc_usable_size"); 43 | trueExitFunction = (exitFunction *) dlsym (RTLD_NEXT, "exit"); 44 | mallocfn = (mallocFunction *) dlsym (RTLD_NEXT, "malloc"); 45 | 46 | if (!(freefn && msizefn && trueExitFunction && mallocfn)) { 47 | fprintf (stderr, "Serious problem!\n"); 48 | abort(); 49 | } 50 | 51 | assert (freefn); 52 | assert (msizefn); 53 | assert (trueExitFunction); 54 | assert (mallocfn); 55 | 56 | // Go get some memory from malloc! 57 | return (*mallocfn)(sz); 58 | } 59 | 60 | // Now, once we have mallocfn resolved, we can use it. 61 | // Otherwise, we're still in dlsym-land, and have to use our local heap. 62 | 63 | if (mallocfn) { 64 | return (*mallocfn)(sz); 65 | } else { 66 | void * ptr = localHeap.malloc (sz); 67 | assert (ptr); 68 | return ptr; 69 | } 70 | } 71 | 72 | inline void free (void * ptr) { 73 | if (mallocfn) { 74 | if (localHeap.isValid (ptr)) { 75 | // We got a pointer to the temporary allocation buffer. 76 | localHeap.free (ptr); 77 | } else { 78 | (*freefn)(ptr); 79 | } 80 | } 81 | } 82 | 83 | inline size_t getSize (void * ptr) { 84 | if (localHeap.isValid (ptr)) { 85 | return localHeap.getSize (ptr); 86 | } else if (mallocfn) { 87 | return (*msizefn)(ptr); 88 | } else { 89 | // This should never happen. 90 | return 0; 91 | } 92 | } 93 | 94 | private: 95 | 96 | bool firsttime; /// True iff we haven't initialized the shim functions. 97 | 98 | // Shim functions below. 99 | 100 | freeFunction * freefn; 101 | msizeFunction * msizefn; 102 | mallocFunction * mallocfn; 103 | 104 | /// The local heap (for use while we are in dlsym, installing the 105 | /// shim functions). Hopefully 64K is enough... 106 | 107 | ANSIWrapper > > localHeap; 108 | 109 | }; 110 | 111 | } 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /heaplayers/lockedheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _LOCKEDHEAP_H_ 28 | #define _LOCKEDHEAP_H_ 29 | 30 | #include "guard.h" 31 | 32 | namespace HL { 33 | 34 | template 35 | class LockedHeap : public Super { 36 | public: 37 | 38 | inline void * malloc (size_t sz) { 39 | Guard l (thelock); 40 | return Super::malloc (sz); 41 | } 42 | 43 | inline void free (void * ptr) { 44 | Guard l (thelock); 45 | Super::free (ptr); 46 | } 47 | 48 | inline void lock (void) { 49 | thelock.lock(); 50 | } 51 | 52 | inline void unlock (void) { 53 | thelock.unlock(); 54 | } 55 | 56 | private: 57 | LockType thelock; 58 | }; 59 | 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /heaplayers/mallocheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2005 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _MALLOCHEAP_H_ 28 | #define _MALLOCHEAP_H_ 29 | 30 | #include 31 | 32 | #if defined(__SVR4) 33 | extern "C" size_t malloc_usable_size (void *); 34 | #else 35 | extern "C" size_t malloc_usable_size (void *) throw (); 36 | #endif 37 | 38 | #if defined(_WIN32) || defined(linux) 39 | #include 40 | #elif defined(__APPLE__) 41 | #include 42 | #endif 43 | 44 | /** 45 | * @class mallocHeap 46 | * @brief A "source heap" that uses malloc and free. 47 | */ 48 | 49 | namespace HL { 50 | 51 | class mallocHeap { 52 | public: 53 | 54 | ~mallocHeap (void) {} 55 | 56 | inline void * malloc (size_t sz) { 57 | return ::malloc (sz); 58 | } 59 | 60 | 61 | inline void free (void * ptr) { 62 | ::free (ptr); 63 | } 64 | 65 | #if defined(_MSC_VER) 66 | inline size_t getSize (void * ptr) { 67 | return ::_msize (ptr); 68 | } 69 | #elif defined(__GNUC__) && !defined(__SVR4) 70 | inline size_t getSize (void * ptr) { 71 | return ::malloc_usable_size (ptr); 72 | } 73 | #elif defined(__APPLE__) 74 | inline size_t getSize (void * ptr) { 75 | return ::malloc_size (ptr); 76 | } 77 | #endif 78 | 79 | }; 80 | 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /heaplayers/mmapwrapper.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2005 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _MMAPWRAPPER_H_ 28 | #define _MMAPWRAPPER_H_ 29 | 30 | #if defined(_WIN32) 31 | #include 32 | #else 33 | // UNIX 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #endif 41 | 42 | #if HL_EXECUTABLE_HEAP 43 | #define HL_MMAP_PROTECTION_MASK (PROT_READ | PROT_WRITE | PROT_EXEC) 44 | #else 45 | #define HL_MMAP_PROTECTION_MASK (PROT_READ | PROT_WRITE) 46 | #endif 47 | 48 | #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) 49 | #define MAP_ANONYMOUS MAP_ANON 50 | #endif 51 | 52 | namespace HL { 53 | 54 | class MmapWrapper { 55 | public: 56 | 57 | #if defined(_WIN32) 58 | 59 | // Microsoft Windows has 4K pages aligned to a 64K boundary. 60 | enum { Size = 4 * 1024 }; 61 | enum { Alignment = 64 * 1024 }; 62 | 63 | static void * map (size_t sz) { 64 | void * ptr; 65 | #if HL_EXECUTABLE_HEAP 66 | const int permflags = PAGE_EXECUTE_READWRITE; 67 | #else 68 | const int permflags = PAGE_READWRITE; 69 | #endif 70 | ptr = VirtualAlloc (NULL, sz, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, permflags); 71 | return ptr; 72 | } 73 | 74 | static void unmap (void * ptr, size_t) { 75 | VirtualFree (ptr, 0, MEM_RELEASE); 76 | } 77 | 78 | #else 79 | 80 | #if defined(__SVR4) 81 | // Solaris aligns 8K pages to a 64K boundary. 82 | enum { Size = 8 * 1024 }; 83 | enum { Alignment = 64 * 1024 }; 84 | #else 85 | // Linux and most other operating systems align memory to a 4K boundary. 86 | enum { Size = 4 * 1024 }; 87 | enum { Alignment = 4 * 1024 }; 88 | #endif 89 | 90 | static void * map (size_t sz) { 91 | 92 | if (sz == 0) { 93 | return NULL; 94 | } 95 | 96 | void * ptr; 97 | 98 | #if defined(MAP_ALIGN) && defined(MAP_ANON) 99 | // Request memory aligned to the Alignment value above. 100 | ptr = mmap ((char *) Alignment, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE | MAP_ALIGN | MAP_ANON, -1, 0); 101 | #elif !defined(MAP_ANONYMOUS) 102 | static int fd = ::open ("/dev/zero", O_RDWR); 103 | ptr = mmap (NULL, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE, fd, 0); 104 | #else 105 | ptr = mmap (0, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 106 | #endif 107 | 108 | if (ptr == MAP_FAILED) { 109 | return NULL; 110 | } else { 111 | return ptr; 112 | } 113 | } 114 | 115 | static void unmap (void * ptr, size_t sz) { 116 | munmap (reinterpret_cast(ptr), sz); 117 | } 118 | 119 | #endif 120 | 121 | }; 122 | 123 | } 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /heaplayers/nullheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _NULLHEAP_H_ 28 | #define _NULLHEAP_H_ 29 | 30 | #include 31 | 32 | /** 33 | * @class NullHeap 34 | * @brief A source heap that does nothing. 35 | */ 36 | 37 | namespace HL { 38 | 39 | class NullHeap { 40 | public: 41 | inline void * malloc (size_t) const { return 0; } 42 | inline void free (void *) const {} 43 | inline int remove (void *) const { return 0; } 44 | inline void clear (void) const {} 45 | inline size_t getSize (void *) const { return 0; } 46 | }; 47 | 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /heaplayers/oneheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _ONEHEAP_H_ 28 | #define _ONEHEAP_H_ 29 | 30 | // 31 | // Wrap a single instance of a heap. 32 | // 33 | 34 | namespace HL { 35 | 36 | template 37 | class OneHeap { 38 | public: 39 | OneHeap (void) 40 | : theHeap (getHeap()) 41 | {} 42 | 43 | inline void * malloc (const size_t sz) { 44 | return theHeap->malloc (sz); 45 | } 46 | inline void free (void * ptr) { 47 | theHeap->free (ptr); 48 | } 49 | inline int remove (void * ptr) { 50 | return theHeap->remove (ptr); 51 | } 52 | inline void clear (void) { 53 | theHeap->clear(); 54 | } 55 | inline size_t getSize (void * ptr) { 56 | return theHeap->getSize (ptr); 57 | } 58 | 59 | enum { Alignment = SuperHeap::Alignment }; 60 | 61 | private: 62 | 63 | SuperHeap * theHeap; 64 | 65 | inline static SuperHeap * getHeap (void) { 66 | static SuperHeap theHeap; 67 | return &theHeap; 68 | } 69 | // SuperHeap theHeap; 70 | }; 71 | 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /heaplayers/padheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _PADHEAP_H_ 4 | #define _PADHEAP_H_ 5 | 6 | #include 7 | 8 | // Pad object size requests. 9 | 10 | template 11 | class PadHeap : public SuperHeap { 12 | public: 13 | 14 | inline void * malloc (size_t sz) { 15 | return SuperHeap::malloc (roundup(sz)); 16 | } 17 | 18 | private: 19 | 20 | inline size_t roundup (size_t sz) { 21 | // NB: CacheLineSize MUST be a power of two. 22 | // The assertion below checks this. 23 | assert ((CacheLineSize & (CacheLineSize-1)) == 0); 24 | size_t roundup = (sz + CacheLineSize - 1) & ~((int) CacheLineSize-1); 25 | assert (roundup >= sz); 26 | return roundup; 27 | } 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /heaplayers/perclassheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _PERCLASSHEAP_H 2 | #define _PERCLASSHEAP_H 3 | 4 | #include 5 | 6 | /** 7 | * @class PerClassHeap 8 | * @brief Enable the use of one heap for all class memory allocation. 9 | * 10 | * This class contains one instance of the SuperHeap argument. The 11 | * example below shows how to make a subclass of Foo that uses a 12 | * FreelistHeap to manage its memory, overloading operators new and 13 | * delete. 14 | * 15 | * 16 | * class NewFoo : public Foo, PerClassHeap > {}; 17 | * 18 | */ 19 | 20 | namespace HL { 21 | 22 | template 23 | class PerClassHeap { 24 | public: 25 | inline void * operator new (size_t sz) { 26 | return getHeap()->malloc (sz); 27 | } 28 | inline void operator delete (void * ptr) { 29 | getHeap()->free (ptr); 30 | } 31 | inline void * operator new[] (size_t sz) { 32 | return getHeap()->malloc (sz); 33 | } 34 | inline void operator delete[] (void * ptr) { 35 | getHeap()->free (ptr); 36 | } 37 | // For some reason, g++ needs placement new to be overridden 38 | // as well, at least in conjunction with use of the STL. 39 | // Otherwise, this should be superfluous. 40 | inline void * operator new (size_t sz, void * p) { return p; } 41 | inline void * operator new[] (size_t sz, void * p) { return p; } 42 | 43 | private: 44 | inline static SuperHeap * getHeap (void) { 45 | static SuperHeap theHeap; 46 | return &theHeap; 47 | } 48 | }; 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /heaplayers/phothreadheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _PHOThreadHeap_H_ 4 | #define _PHOThreadHeap_H_ 5 | 6 | #include 7 | 8 | static volatile int getThreadId (void); 9 | 10 | template 11 | class MarkThreadHeap : public super { 12 | public: 13 | 14 | inline void * malloc (size_t sz) { 15 | int tid = getThreadId() % NumHeaps; 16 | void * ptr = super::malloc (sz); 17 | if (ptr != NULL) { 18 | super::setHeap(ptr, tid); 19 | super::setPrevHeap(super::getNext(ptr), tid); 20 | } 21 | return ptr; 22 | } 23 | }; 24 | 25 | 26 | template 27 | class CheckThreadHeap : public super { 28 | public: 29 | 30 | inline void * malloc (size_t sz) { 31 | int tid = getThreadId() % NumHeaps; 32 | void * ptr = super::malloc (sz); 33 | if (ptr != NULL) 34 | assert (super::getHeap(ptr) == tid); 35 | return ptr; 36 | } 37 | 38 | inline void free (void * ptr) { 39 | super::free (ptr); 40 | } 41 | }; 42 | 43 | 44 | 45 | /* 46 | 47 | A PHOThreadHeap comprises NumHeaps "per-thread" heaps. 48 | 49 | To pick a per-thread heap, the current thread id is hashed (mod NumHeaps). 50 | 51 | malloc gets memory from its hashed per-thread heap. 52 | free returns memory to its originating heap. 53 | 54 | NB: We assume that the thread heaps are 'locked' as needed. */ 55 | 56 | 57 | template 58 | class PHOThreadHeap { // : public MarkThreadHeap { 59 | public: 60 | 61 | inline void * malloc (size_t sz) { 62 | int tid = getThreadId() % NumHeaps; 63 | void * ptr = selectHeap(tid)->malloc (sz); 64 | return ptr; 65 | } 66 | 67 | inline void free (void * ptr) { 68 | int tid = super::getHeap(ptr); 69 | selectHeap(tid)->free (ptr); 70 | } 71 | 72 | 73 | inline int remove (void * ptr); 74 | #if 0 75 | { 76 | int tid = super::getHeap(ptr); 77 | selectHeap(tid)->remove (ptr); 78 | } 79 | #endif 80 | 81 | private: 82 | 83 | // Access the given heap within the buffer. 84 | MarkThreadHeap * selectHeap (int index) { 85 | assert (index >= 0); 86 | assert (index < NumHeaps); 87 | return &ptHeaps[index]; 88 | } 89 | 90 | MarkThreadHeap ptHeaps[NumHeaps]; 91 | 92 | }; 93 | 94 | 95 | // A platform-dependent way to get a thread id. 96 | 97 | // Include the necessary platform-dependent crud. 98 | #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) 99 | #ifndef WIN32 100 | #define WIN32 1 101 | #endif 102 | #include 103 | #include 104 | #endif 105 | 106 | #if defined(__SVR4) 107 | extern "C" unsigned int lwp_self (void); 108 | #endif 109 | 110 | 111 | static volatile int getThreadId (void) { 112 | #if defined(WIN32) 113 | // It looks like thread id's are always multiples of 4, so... 114 | int tid = GetCurrentThreadId() >> 2; 115 | // Now hash in some of the first bits. 116 | // return tid; 117 | return (tid & ~(1024-1)) ^ tid; 118 | #endif 119 | #if defined(__BEOS__) 120 | return find_thread(0); 121 | #endif 122 | #if defined(__linux) 123 | // Consecutive thread id's in Linux are 1024 apart; 124 | // dividing off the 1024 gives us an appropriate thread id. 125 | return (int) pthread_self() >> 10; // (>> 10 = / 1024) 126 | #endif 127 | #if defined(__SVR4) 128 | return (int) lwp_self(); 129 | #endif 130 | #if defined(POSIX) 131 | return (int) pthread_self(); 132 | #endif 133 | #if USE_SPROC 134 | // This hairiness has the same effect as calling getpid(), 135 | // but it's MUCH faster since it avoids making a system call 136 | // and just accesses the sproc-local data directly. 137 | int pid = (int) PRDA->sys_prda.prda_sys.t_pid; 138 | return pid; 139 | #endif 140 | } 141 | 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /heaplayers/profileheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _PROFILEHEAP_H_ 4 | #define _PROFILEHEAP_H_ 5 | 6 | 7 | #include 8 | 9 | extern int memRequested; 10 | extern int maxMemRequested; 11 | 12 | // Maintain & print memory usage info. 13 | // Requires a superheap with the size() method (e.g., SizeHeap). 14 | 15 | template 16 | class ProfileHeap : public super { 17 | public: 18 | 19 | ProfileHeap (void) 20 | { 21 | memRequested = 0; 22 | maxMemRequested = 0; 23 | } 24 | 25 | ~ProfileHeap (void) 26 | { 27 | if (maxMemRequested > 0) { 28 | stats(); 29 | } 30 | } 31 | 32 | inline void * malloc (size_t sz) { 33 | void * ptr = super::malloc (sz); 34 | // Notice that we use the size reported by the allocator 35 | // for the object rather than the requested size. 36 | memRequested += super::getSize(ptr); 37 | if (memRequested > maxMemRequested) { 38 | maxMemRequested = memRequested; 39 | } 40 | return ptr; 41 | } 42 | 43 | inline void free (void * ptr) { 44 | memRequested -= super::getSize (ptr); 45 | super::free (ptr); 46 | } 47 | 48 | private: 49 | void stats (void) { 50 | printf ("Heap: %d\n", HeapNumber); 51 | printf ("Max memory requested = %d\n", maxMemRequested); 52 | printf ("Memory still in use = %d\n", memRequested); 53 | } 54 | 55 | int memRequested; 56 | int maxMemRequested; 57 | 58 | }; 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /heaplayers/sanitycheckheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _SANITYCHECKHEAP_H_ 4 | #define _SANITYCHECKHEAP_H_ 5 | 6 | /** 7 | * @class SanityCheckHeap 8 | * @brief Checks for memory allocation usage errors at runtime. 9 | * See the "error messages" for the kinds of errors this layer can catch. 10 | * @author Emery Berger 11 | */ 12 | 13 | #include 14 | 15 | #include "mallocheap.h" 16 | #include "zoneheap.h" 17 | #include "stlallocator.h" 18 | #include "mmapheap.h" 19 | 20 | namespace HL { 21 | 22 | template 23 | class SanityCheckHeap : public SuperHeap { 24 | private: 25 | 26 | /// Define a local allocator that lets us use the SuperHeap for the map. 27 | /// This approach lets us use SanityCheckHeaps when we're replacing malloc. 28 | 29 | // The objects are pairs, mapping void * pointers to sizes. 30 | typedef std::pair objType; 31 | 32 | // The heap is a simple freelist heap. 33 | typedef HL::FreelistHeap > heapType; 34 | 35 | // And we wrap it up so it can be used as an STL allocator. 36 | typedef HL::STLAllocator localAllocator; 37 | 38 | typedef std::less localComparator; 39 | 40 | /// A map of pointers to objects and their allocated sizes. 41 | typedef std::map mapType; 42 | 43 | /// A freed object has a special size, -1. 44 | enum { FREED = -1 }; 45 | 46 | /** 47 | * @brief "Error messages", used in asserts. 48 | * These must all equal zero. 49 | */ 50 | enum { MALLOC_RETURNED_ALLOCATED_OBJECT = 0, 51 | FREE_CALLED_ON_OBJECT_I_NEVER_ALLOCATED = 0, 52 | FREE_CALLED_TWICE_ON_SAME_OBJECT = 0 }; 53 | 54 | public: 55 | 56 | inline void * malloc (size_t sz) { 57 | void * ptr = SuperHeap::malloc (sz); 58 | if (ptr == NULL) { 59 | return NULL; 60 | } 61 | // Fill the space with a known value. 62 | memset (ptr, 'A', sz); 63 | // Record this object as allocated. 64 | mapType::iterator i; 65 | // Look for this object in the map of allocated objects. 66 | i = allocatedObjects.find (ptr); 67 | if (i == allocatedObjects.end()) { 68 | // We didn't find it (this is good). 69 | // Add the tuple (ptr, sz). 70 | allocatedObjects.insert (std::pair(ptr, sz)); 71 | } else { 72 | // We found it. 73 | // It really should have been freed. 74 | if ((*i).second != FREED) { 75 | // This object is still in use! 76 | assert ( MALLOC_RETURNED_ALLOCATED_OBJECT ); 77 | return NULL; 78 | } else { 79 | // This object has been freed. Mark it as allocated. 80 | (*i).second = sz; 81 | } 82 | } 83 | return ptr; 84 | } 85 | 86 | inline void free (void * ptr) { 87 | // Look for this object in the list of allocated objects. 88 | mapType::iterator i; 89 | i = allocatedObjects.find (ptr); 90 | if (i == allocatedObjects.end()) { 91 | assert ( FREE_CALLED_ON_OBJECT_I_NEVER_ALLOCATED ); 92 | return; 93 | } 94 | // We found the object. It should not have been freed already. 95 | if ((*i).second == FREED) { 96 | // Oops, this object WAS freed before. 97 | assert ( FREE_CALLED_TWICE_ON_SAME_OBJECT ); 98 | return; 99 | } 100 | // Fill the space with a known value. 101 | memset (ptr, 'F', (*i).second); 102 | // Really free the pointer. 103 | (*i).second = FREED; 104 | SuperHeap::free (ptr); 105 | } 106 | 107 | private: 108 | 109 | /// A map of tuples: (obj address, size). 110 | mapType allocatedObjects; 111 | }; 112 | 113 | }; 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /heaplayers/sbrk.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* Sbrk implementation for Win32 by Emery Berger, http://www.cs.utexas.edu/users/emery */ 6 | 7 | void * sbrk (long size) { 8 | 9 | /* Reserve up to 1 GB of RAM */ 10 | /* 11 | We pre-reserve a very large chunk of memory 12 | and commit pages as we go. */ 13 | 14 | #define PRE_RESERVE 1024 * 1024 * 1024 15 | 16 | static long remainingReserved = PRE_RESERVE; 17 | 18 | static int initialized = 0; 19 | static char * currentPosition = NULL; 20 | static char * nextPage = NULL; 21 | static long remainingCommitted = 0; 22 | static long pageSize; 23 | void * p; 24 | 25 | if (!initialized) { 26 | 27 | /* 28 | Do one-time initialization stuff: 29 | get the page size from the system, 30 | reserve a large range of memory, 31 | and initialize the appropriate variables. 32 | 33 | */ 34 | 35 | SYSTEM_INFO sSysInfo; 36 | LPVOID base; 37 | GetSystemInfo(&sSysInfo); 38 | 39 | pageSize = sSysInfo.dwPageSize; 40 | 41 | /* Reserve pages in the process's virtual address space. */ 42 | 43 | #if 1 44 | base = VirtualAlloc(NULL, remainingReserved, MEM_RESERVE, PAGE_NOACCESS); 45 | #else 46 | base = VirtualAlloc(NULL, remainingReserved, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 47 | remainingCommitted = PRE_RESERVE; 48 | #endif 49 | 50 | if (base == NULL ) 51 | exit (1); /* VirtualAlloc reserve failed */ 52 | 53 | currentPosition = nextPage = (char *) base; 54 | initialized = 1; 55 | } 56 | 57 | if (size < 0) { 58 | 59 | #if 0 60 | /* Uncommit pages if possible. 61 | Round the size down to a multiple of the page size, 62 | and decommit those pages. 63 | */ 64 | 65 | 66 | int bytesToUncommit = (-size & ~(pageSize - 1)); 67 | 68 | if (bytesToUncommit > PRE_RESERVE - remainingReserved) { 69 | /* Error -- the user has tried to free memory that we never 70 | even reserved. */ 71 | return currentPosition; 72 | } 73 | 74 | if (bytesToUncommit > 0) { 75 | 76 | int result = VirtualFree (nextPage - bytesToUncommit, bytesToUncommit, MEM_DECOMMIT); 77 | if (result == 0) { 78 | /* Error -- don't change a thing. */ 79 | return currentPosition; 80 | } 81 | remainingCommitted -= bytesToUncommit; 82 | } 83 | 84 | currentPosition -= size; 85 | remainingReserved += size; 86 | #endif 87 | return currentPosition; 88 | 89 | } 90 | 91 | if (size > 0) { 92 | void * p; 93 | if (size > remainingCommitted) { 94 | 95 | /* Commit some more pages. 96 | We round up to an even number of pages. 97 | Note that page size must be a power of two. 98 | */ 99 | 100 | int bytesToCommit = (size - remainingCommitted + pageSize - 1) & ~(pageSize - 1); 101 | int * result; 102 | 103 | result = VirtualAlloc((LPVOID) nextPage, bytesToCommit, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 104 | 105 | if (result == NULL ) 106 | exit (1); /* VirtualAlloc commit failed */ 107 | 108 | nextPage += bytesToCommit; 109 | remainingCommitted += bytesToCommit; 110 | } 111 | 112 | p = currentPosition; 113 | currentPosition += size; 114 | remainingCommitted -= size; 115 | remainingReserved -= size; 116 | return p; 117 | } 118 | 119 | assert (size == 0); 120 | return currentPosition; 121 | 122 | } 123 | -------------------------------------------------------------------------------- /heaplayers/sbrkheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _SBRKHEAP_H_ 4 | #define _SBRKHEAP_H_ 5 | 6 | #ifdef WIN32 7 | 8 | // If we're using Windows, we'll need to link in sbrk.c, 9 | // a replacement for sbrk(). 10 | 11 | extern "C" void * sbrk (size_t sz); 12 | 13 | #endif 14 | 15 | /* 16 | * @class SbrkHeap 17 | * @brief A source heap that is a thin wrapper over sbrk. 18 | * 19 | * As it stands, memory cannot be returned to sbrk(). 20 | * This is not a significant limitation, since only memory 21 | * at the end of the break point can ever be returned anyway. 22 | */ 23 | 24 | namespace HL { 25 | 26 | class SbrkHeap { 27 | public: 28 | SbrkHeap (void) 29 | {} 30 | 31 | inline void * malloc (size_t sz) { 32 | return sbrk(sz); 33 | } 34 | 35 | inline void free (void *) { } 36 | inline int remove (void *) { return 0; } 37 | }; 38 | 39 | } 40 | 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /heaplayers/sizeheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2007 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _SIZEHEAP_H_ 28 | #define _SIZEHEAP_H_ 29 | 30 | /** 31 | * @file sizeheap.h 32 | * @brief Contains UseSizeHeap and SizeHeap. 33 | */ 34 | 35 | #include 36 | #include 37 | 38 | #include "addheap.h" 39 | 40 | /** 41 | * @class UseSizeHeap 42 | * @brief Adds a getSize method to access the size of an allocated object. 43 | * @see SizeHeap 44 | */ 45 | 46 | namespace HL { 47 | 48 | template 49 | class UseSizeHeap : public Super { 50 | public: 51 | 52 | inline static size_t getSize (const void * ptr) { 53 | return ((freeObject *) ptr - 1)->getSize(); 54 | } 55 | 56 | protected: 57 | class freeObject { 58 | public: 59 | freeObject (size_t sz) 60 | : _size (sz) 61 | {} 62 | size_t getSize (void) const { 63 | return _size; 64 | } 65 | private: 66 | union { 67 | size_t _size; 68 | double _dummy; // for alignment. 69 | }; 70 | }; 71 | }; 72 | 73 | /** 74 | * @class SizeHeap 75 | * @brief Allocates extra room for the size of an object. 76 | */ 77 | 78 | template 79 | class SizeHeap : public UseSizeHeap { 80 | typedef typename UseSizeHeap::freeObject freeObject; 81 | public: 82 | inline void * malloc (const size_t sz) { 83 | freeObject * ptr = new (SuperHeap::malloc (sz + sizeof(freeObject))) 84 | freeObject (sz); 85 | void * obj = (void *) (ptr + 1); 86 | size_t size = UseSizeHeap::getSize(obj); 87 | assert (size >= sz); 88 | return obj; 89 | } 90 | inline void free (void * ptr) { 91 | SuperHeap::free (((freeObject *) ptr) - 1); 92 | } 93 | }; 94 | 95 | }; 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /heaplayers/sizeownerheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _SIZEOWNERHEAP_H_ 28 | #define _SIZEOWNERHEAP_H_ 29 | 30 | #include 31 | 32 | #include "addheap.h" 33 | 34 | /** 35 | * @class SizeOwnerHeap 36 | * @brief Adds object size and owner heap information. 37 | */ 38 | 39 | namespace HL { 40 | 41 | template 42 | class SizeOwner { 43 | public: 44 | union { 45 | struct { 46 | size_t size; 47 | Heap * owner; 48 | } s; 49 | double dummy; 50 | }; 51 | }; 52 | 53 | template 54 | class SizeOwnerHeap : public AddHeap, Super> { 55 | private: 56 | 57 | typedef AddHeap, Super> SuperHeap; 58 | 59 | public: 60 | 61 | inline void * malloc (size_t sz) { 62 | void * ptr = SuperHeap::malloc (sz); 63 | // Store the requested size. 64 | SizeOwner * so = (SizeOwner *) ptr; 65 | so->s.size = sz; 66 | so->s.owner = this; 67 | // Store the owner. 68 | return (void *) (so + 1); 69 | } 70 | 71 | inline void free (void * ptr) { 72 | void * origPtr = (void *) ((SizeOwner *) ptr - 1); 73 | SuperHeap::free (origPtr); 74 | } 75 | 76 | static inline Super * owner (void * ptr) { 77 | SizeOwner * so = (SizeOwner *) ptr - 1; 78 | return so->s.owner; 79 | } 80 | 81 | static inline size_t size (void * ptr) { 82 | SizeOwner * so = (SizeOwner *) ptr - 1; 83 | return so->s.size; 84 | } 85 | }; 86 | 87 | }; 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /heaplayers/sizethreadheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _SIZETHREADHEAP_H_ 4 | #define _SIZETHREADHEAP_H_ 5 | 6 | #include 7 | 8 | template 9 | class SizeThreadHeap : public Super { 10 | public: 11 | 12 | inline void * malloc (size_t sz) { 13 | // Add room for a size field & a thread field. 14 | // Both of these must fit in a double. 15 | assert (sizeof(st) <= sizeof(double)); 16 | st * ptr = (st *) Super::malloc (sz + sizeof(double)); 17 | // Store the requested size. 18 | ptr->size = sz; 19 | assert (getOrigPtr(ptr + 1) == ptr); 20 | return (void *) (ptr + 1); 21 | } 22 | 23 | inline void free (void * ptr) { 24 | void * origPtr = (void *) getOrigPtr(ptr); 25 | Super::free (origPtr); 26 | } 27 | 28 | static inline volatile int getThreadId (void); 29 | 30 | static inline size_t& size (void * ptr) { 31 | return getOrigPtr(ptr)->size; 32 | } 33 | 34 | static inline int& thread (void * ptr) { 35 | return getOrigPtr(ptr)->tid; 36 | } 37 | 38 | private: 39 | 40 | typedef struct _st { 41 | size_t size; 42 | int tid; 43 | } st; 44 | 45 | static inline st * getOrigPtr (void * ptr) { 46 | return (st *) ((double *) ptr - 1); 47 | } 48 | 49 | }; 50 | 51 | 52 | 53 | // A platform-dependent way to get a thread id. 54 | 55 | // Include the necessary platform-dependent crud. 56 | #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) 57 | #ifndef WIN32 58 | #define WIN32 1 59 | #endif 60 | #include 61 | #include 62 | #endif 63 | 64 | template 65 | inline volatile int 66 | SizeThreadHeap::getThreadId (void) { 67 | #if defined(WIN32) 68 | return GetCurrentThreadId(); 69 | #endif 70 | #if defined(__BEOS__) 71 | return find_thread(0); 72 | #endif 73 | #if defined(__linux) 74 | // Consecutive thread id's in Linux are 1024 apart; 75 | // dividing off the 1024 gives us an appropriate thread id. 76 | return (int) pthread_self() >> 10; // (>> 10 = / 1024) 77 | #endif 78 | #if defined(__SVR4) 79 | return (int) lwp_self(); 80 | #endif 81 | #if defined(POSIX) 82 | return (int) pthread_self(); 83 | #endif 84 | #if USE_SPROC 85 | // This hairiness has the same effect as calling getpid(), 86 | // but it's MUCH faster since it avoids making a system call 87 | // and just accesses the sproc-local data directly. 88 | int pid = (int) PRDA->sys_prda.prda_sys.t_pid; 89 | return pid; 90 | #endif 91 | } 92 | 93 | 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /heaplayers/slopheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | 28 | #ifndef _SLOPHEAP_H_ 29 | #define _SLOPHEAP_H_ 30 | 31 | /** 32 | * @class SlopHeap 33 | * 34 | * SlopHeap is designed to guarantee that you always have an extra N bytes 35 | * available after the most recent malloc. This is necessary for the current 36 | * coalescing support, which can look past the last allocated object. 37 | * 38 | * @param SuperHeap The parent heap. 39 | * @param SLOP The amount of extra memory required, in bytes. 40 | */ 41 | 42 | namespace HL { 43 | 44 | template 45 | class SlopHeap : public SuperHeap { 46 | public: 47 | SlopHeap (void) 48 | : remaining (0), 49 | ptr (NULL) 50 | {} 51 | 52 | inline void * malloc (const size_t nbytes) { 53 | 54 | // Put the usual case up front. 55 | if (nbytes <= remaining) { 56 | remaining -= nbytes; 57 | char * p = ptr; 58 | ptr += nbytes; 59 | return (void *) p; 60 | } 61 | 62 | // 63 | // We don't have enough space to satisfy the current 64 | // request, so get more memory. 65 | // 66 | 67 | return getMoreMemory(nbytes); 68 | } 69 | 70 | inline void clear (void) { 71 | ptr = NULL; 72 | remaining = 0; 73 | SuperHeap::clear (); 74 | } 75 | 76 | inline void free (void *) {} 77 | 78 | private: 79 | 80 | // Disabled. 81 | inline int remove (void *); 82 | 83 | void * getMoreMemory (size_t nbytes) { 84 | char * newptr = (char *) SuperHeap::malloc (nbytes + SLOP); 85 | 86 | if (newptr == NULL) { 87 | return NULL; 88 | } 89 | 90 | // 91 | // If this new memory is contiguous with the previous one, 92 | // reclaim the "slop". 93 | // 94 | 95 | if ((ptr != NULL) && (ptr + remaining + SLOP == newptr)) { 96 | remaining += SLOP; 97 | } else { 98 | ptr = newptr; 99 | remaining = 0; 100 | } 101 | char * p = ptr; 102 | ptr += nbytes; 103 | 104 | return (void *) p; 105 | } 106 | 107 | char * ptr; 108 | size_t remaining; 109 | 110 | }; 111 | 112 | } 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /heaplayers/staticheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | /* 28 | 29 | StaticHeap: manage a fixed range of memory. 30 | 31 | */ 32 | 33 | #ifndef _STATICHEAP_H_ 34 | #define _STATICHEAP_H_ 35 | 36 | namespace HL { 37 | 38 | template 39 | class StaticHeap { 40 | public: 41 | 42 | StaticHeap (void) 43 | : ptr (&buf[0]), 44 | remaining (MemorySize) 45 | {} 46 | 47 | enum { Alignment = 1 }; 48 | 49 | inline void * malloc (size_t sz) { 50 | if (remaining < sz) { 51 | return NULL; 52 | } 53 | void * p = ptr; 54 | ptr += sz; 55 | remaining -= sz; 56 | return p; 57 | } 58 | 59 | void free (void *) {} 60 | int remove (void *) { return 0; } 61 | 62 | int isValid (void * ptr) { 63 | return (((size_t) ptr >= (size_t) buf) && 64 | ((size_t) ptr < (size_t) buf)); 65 | } 66 | 67 | private: 68 | 69 | #if 1 70 | // Disable copying and assignment. 71 | StaticHeap (const StaticHeap&); 72 | StaticHeap& operator= (const StaticHeap&); 73 | #endif 74 | 75 | char buf[MemorySize]; 76 | char * ptr; 77 | size_t remaining; 78 | }; 79 | 80 | }; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /heaplayers/stats.cpp: -------------------------------------------------------------------------------- 1 | // Report stats. 2 | 3 | #include 4 | 5 | #include "timer.h" 6 | 7 | struct mallinfo { 8 | int arena; /* non-mmapped space allocated from system */ 9 | int ordblks; /* number of free chunks */ 10 | int smblks; /* number of fastbin blocks */ 11 | int hblks; /* number of mmapped regions */ 12 | int hblkhd; /* space in mmapped regions */ 13 | int usmblks; /* maximum total allocated space */ 14 | int fsmblks; /* space available in freed fastbin blocks */ 15 | int uordblks; /* total allocated space */ 16 | int fordblks; /* total free space */ 17 | int keepcost; /* top-most, releasable (via malloc_trim) space */ 18 | }; 19 | 20 | #if 1 21 | extern "C" struct mallinfo dlmallinfo (void); 22 | #endif 23 | extern "C" void mstats (void); // for Kingsley malloc. 24 | extern "C" void dlmalloc_stats (void); // for Doug Lea malloc. 25 | extern "C" void * sbrk (long); 26 | extern "C" void malloc_stats (void); // for Doug Lea malloc. 27 | 28 | int masMem;// FIX ME 29 | 30 | 31 | int totalAllocated; 32 | int maxAllocated; 33 | int totalRequested; 34 | int maxRequested; 35 | 36 | class TimeItAll { 37 | public: 38 | TimeItAll (void) { 39 | totalAllocated = 0; 40 | maxAllocated = 0; 41 | t.start(); 42 | // FIX ME 43 | masMem = 0; 44 | #ifdef WIN32 45 | initSpace = (long) sbrk(0); 46 | //initSpace = CommittedSpace(); 47 | #endif 48 | } 49 | 50 | ~TimeItAll (void) { 51 | t.stop(); 52 | #if 0 53 | struct mallinfo mi = dlmallinfo(); 54 | printf ("Doug Lea Memory allocated = {total} %d, {non-mmapped} %d\n", mi.usmblks, mi.arena); 55 | #endif 56 | double elapsed = (double) t; 57 | printf ("Time elapsed = %f\n", elapsed); 58 | printf ("Max allocated = %d\n", maxAllocated); 59 | printf ("Max requested = %d\n", maxRequested); 60 | printf ("Frag = %lf\n", (double) maxAllocated / (double) maxRequested); 61 | #ifdef WIN32 62 | printf ("init space = %ld\n", initSpace); 63 | printf ("Sbrk report: %ld\n", (long) sbrk(0)); 64 | #if 0 65 | size_t diff = (size_t) wsbrk(8); 66 | cout << "diff1 = " << diff << endl; 67 | diff -= initSpace - 8; 68 | cout << "diff = " << diff << endl; 69 | #endif 70 | #endif 71 | malloc_stats(); 72 | fflush (stdout); 73 | // dlmalloc_stats(); 74 | } 75 | private: 76 | Timer t; 77 | #ifdef WIN32 78 | long initSpace; 79 | #endif 80 | }; 81 | 82 | TimeItAll timer; 83 | -------------------------------------------------------------------------------- /heaplayers/stats.h: -------------------------------------------------------------------------------- 1 | #ifndef _HLSTATS_H_ 2 | #define _HLSTATS_H_ 3 | 4 | #include 5 | 6 | template 7 | class InUseHeap : public SuperHeap { 8 | private: 9 | typedef std::map mapType; 10 | public: 11 | InUseHeap (void) 12 | : inUse (0), 13 | maxInUse (0) 14 | {} 15 | void * malloc (size_t sz) { 16 | void * ptr = SuperHeap::malloc (sz); 17 | if (ptr != NULL) { 18 | inUse += sz; 19 | if (maxInUse < inUse) { 20 | maxInUse = inUse; 21 | } 22 | allocatedObjects.insert (std::pair(ptr, sz)); 23 | } 24 | return ptr; 25 | } 26 | void free (void * ptr) { 27 | mapType::iterator i; 28 | i = allocatedObjects.find (ptr); 29 | if (i == allocatedObjects.end()) { 30 | // oops -- called free on object i didn't allocate. 31 | assert (0); 32 | } 33 | inUse -= (*i).second; 34 | allocatedObjects.erase (i); 35 | SuperHeap::free (ptr); 36 | } 37 | 38 | int getInUse (void) const { 39 | return inUse; 40 | } 41 | int getMaxInUse (void) const { 42 | return maxInUse; 43 | } 44 | private: 45 | int inUse; 46 | int maxInUse; 47 | mapType allocatedObjects; 48 | }; 49 | 50 | 51 | template 52 | class AllocatedHeap : public SuperHeap { 53 | public: 54 | AllocatedHeap (void) 55 | : allocated (0), 56 | maxAllocated (0) 57 | {} 58 | void * malloc (size_t sz) { 59 | void * ptr = SuperHeap::malloc (sz); 60 | if (ptr != NULL) { 61 | allocated += getSize(ptr); 62 | if (maxAllocated < allocated) { 63 | maxAllocated = allocated; 64 | } 65 | } 66 | return ptr; 67 | } 68 | void free (void * ptr) { 69 | allocated -= getSize(ptr); 70 | SuperHeap::free (ptr); 71 | } 72 | 73 | int getAllocated (void) const { 74 | return allocated; 75 | } 76 | int getMaxAllocated (void) const { 77 | return maxAllocated; 78 | } 79 | private: 80 | int allocated; 81 | int maxAllocated; 82 | }; 83 | 84 | 85 | template 86 | class StatsHeap : public SuperHeap { 87 | public: 88 | ~StatsHeap (void) { 89 | printf ("In use = %d, allocated = %d\n", getInUse(), getAllocated()); 90 | printf ("Max in use = %d, max allocated = %d\n", getMaxInUse(), getMaxAllocated()); 91 | } 92 | }; 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /heaplayers/threadheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _THREADHEAP_H_ 4 | #define _THREADHEAP_H_ 5 | 6 | #include 7 | #include 8 | 9 | #if !defined(_WIN32) 10 | #include 11 | #endif 12 | 13 | #if defined(__SVR4) // Solaris 14 | extern "C" unsigned int lwp_self(void); 15 | #endif 16 | 17 | /* 18 | 19 | A ThreadHeap comprises NumHeaps "per-thread" heaps. 20 | 21 | To pick a per-thread heap, the current thread id is hashed (mod NumHeaps). 22 | 23 | malloc gets memory from its hashed per-thread heap. 24 | free returns memory to its hashed per-thread heap. 25 | 26 | (This allows the per-thread heap to determine the return 27 | policy -- 'pure private heaps', 'private heaps with ownership', 28 | etc.) 29 | 30 | NB: We assume that the thread heaps are 'locked' as needed. */ 31 | 32 | namespace HL { 33 | 34 | template 35 | class ThreadHeap : public PerThreadHeap { 36 | public: 37 | 38 | inline void * malloc (size_t sz) { 39 | int tid = getThreadId() % NumHeaps; 40 | assert (tid >= 0); 41 | assert (tid < NumHeaps); 42 | return getHeap(tid)->malloc (sz); 43 | } 44 | 45 | inline void free (void * ptr) { 46 | int tid = getThreadId() % NumHeaps; 47 | assert (tid >= 0); 48 | assert (tid < NumHeaps); 49 | getHeap(tid)->free (ptr); 50 | } 51 | 52 | inline size_t getSize (void * ptr) { 53 | int tid = getThreadId() % NumHeaps; 54 | assert (tid >= 0); 55 | assert (tid < NumHeaps); 56 | return getHeap(tid)->getSize (ptr); 57 | } 58 | 59 | 60 | private: 61 | 62 | // Access the given heap within the buffer. 63 | inline PerThreadHeap * getHeap (int index) { 64 | assert (index >= 0); 65 | assert (index < NumHeaps); 66 | return &ptHeaps[index]; 67 | } 68 | 69 | // Get a suitable thread id number. 70 | inline static volatile int getThreadId (void); 71 | 72 | PerThreadHeap ptHeaps[NumHeaps]; 73 | 74 | }; 75 | 76 | } 77 | 78 | 79 | // A platform-dependent way to get a thread id. 80 | 81 | // Include the necessary platform-dependent crud. 82 | #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) 83 | #ifndef WIN32 84 | #define WIN32 1 85 | #endif 86 | #include 87 | #include 88 | #endif 89 | 90 | template 91 | inline volatile int 92 | HL::ThreadHeap::getThreadId (void) { 93 | #if defined(WIN32) 94 | // It looks like thread id's are always multiples of 4, so... 95 | int tid = GetCurrentThreadId() >> 2; 96 | // Now hash in some of the first bits. 97 | // return (tid & ~(1024-1)) ^ tid; 98 | return tid; 99 | #endif 100 | #if defined(__BEOS__) 101 | return find_thread(0); 102 | #endif 103 | #if defined(__linux) 104 | // Consecutive thread id's in Linux are 1024 apart; 105 | // dividing off the 1024 gives us an appropriate thread id. 106 | return (int) pthread_self() >> 10; // (>> 10 = / 1024) 107 | #endif 108 | #if defined(__SVR4) 109 | // printf ("lwp_self = %d\n", (int) lwp_self()); 110 | return (int) lwp_self(); 111 | #endif 112 | #if defined(__APPLE__) 113 | return (int) pthread_self(); 114 | #endif 115 | #if defined(POSIX) 116 | return (int) pthread_self(); 117 | #endif 118 | #if USE_SPROC 119 | // This hairiness has the same effect as calling getpid(), 120 | // but it's MUCH faster since it avoids making a system call 121 | // and just accesses the sproc-local data directly. 122 | int pid = (int) PRDA->sys_prda.prda_sys.t_pid; 123 | return pid; 124 | #endif 125 | } 126 | 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /heaplayers/threadspecificheap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _THREADHEAP_H_ 4 | #define _THREADHEAP_H_ 5 | 6 | #include 7 | #include 8 | 9 | /* 10 | 11 | A ThreadHeap comprises NumHeaps "per-thread" heaps. 12 | 13 | To pick a per-thread heap, the current thread id is hashed (mod NumHeaps). 14 | 15 | malloc gets memory from its hashed per-thread heap. 16 | free returns memory to its hashed per-thread heap. 17 | 18 | (This allows the per-thread heap to determine the return 19 | policy -- 'pure private heaps', 'private heaps with ownership', 20 | etc.) 21 | 22 | NB: We assume that the thread heaps are 'locked' as needed. */ 23 | 24 | 25 | template 26 | class ThreadHeap : public PerThreadHeap { 27 | public: 28 | 29 | ThreadHeap (void) 30 | { 31 | } 32 | 33 | inline void * malloc (size_t sz) { 34 | int tid = getThreadId() % NumHeaps; 35 | return getHeap(tid)->malloc (sz); 36 | } 37 | 38 | inline void free (void * ptr) { 39 | int tid = getThreadId() % NumHeaps; 40 | getHeap(tid)->free (ptr); 41 | } 42 | 43 | 44 | private: 45 | 46 | // Access the given heap within the buffer. 47 | PerThreadHeap * getHeap (int index) { 48 | assert (index >= 0); 49 | assert (index < NumHeaps); 50 | return &ptHeaps[index]; 51 | } 52 | 53 | // Get a suitable thread id number. 54 | inline static volatile int getThreadId (void); 55 | 56 | PerThreadHeap ptHeaps[NumHeaps]; 57 | 58 | }; 59 | 60 | 61 | // A platform-dependent way to get a thread id. 62 | 63 | // Include the necessary platform-dependent crud. 64 | #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) 65 | #ifndef WIN32 66 | #define WIN32 1 67 | #endif 68 | #include 69 | #include 70 | #endif 71 | 72 | template 73 | inline volatile int 74 | ThreadHeap::getThreadId (void) { 75 | #if WIN32 76 | return GetCurrentThreadId(); 77 | #endif 78 | #if defined(__BEOS__) 79 | return find_thread(0); 80 | #endif 81 | #if defined(__linux) 82 | // Consecutive thread id's in Linux are 1024 apart; 83 | // dividing off the 1024 gives us an appropriate thread id. 84 | return (int) pthread_self() >> 10; // (>> 10 = / 1024) 85 | #endif 86 | #if defined(__SVR4) 87 | return (int) lwp_self(); 88 | #endif 89 | #if defined(POSIX) 90 | return (int) pthread_self(); 91 | #endif 92 | #if USE_SPROC 93 | // This hairiness has the same effect as calling getpid(), 94 | // but it's MUCH faster since it avoids making a system call 95 | // and just accesses the sproc-local data directly. 96 | int pid = (int) PRDA->sys_prda.prda_sys.t_pid; 97 | return pid; 98 | #endif 99 | } 100 | 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /heaplayers/tryheap.h: -------------------------------------------------------------------------------- 1 | #ifndef _TRYHEAP_H_ 2 | #define _TRYHEAP_H_ 3 | 4 | template 5 | class TryHeap : public Heap2 { 6 | public: 7 | TryHeap (void) 8 | {} 9 | 10 | inline void * malloc (size_t sz) { 11 | void * ptr = heap1.malloc (sz); 12 | if (ptr == NULL) 13 | ptr = Heap2::malloc (sz); 14 | return ptr; 15 | } 16 | 17 | inline void free (void * ptr) { 18 | heap1.free (ptr); 19 | } 20 | 21 | private: 22 | Heap1 heap1; 23 | }; 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /heaplayers/unique.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _UNIQUEHEAP_H_ 4 | #define _UNIQUEHEAP_H_ 5 | 6 | #include 7 | #include 8 | 9 | /** 10 | * 11 | * @class UniqueHeap 12 | * @brief Instantiates one instance of a class used for every malloc & free. 13 | * @author Emery Berger 14 | * 15 | */ 16 | 17 | template 18 | class UniqueHeap { 19 | public: 20 | 21 | /** 22 | * Ensure that the super heap gets created, 23 | * and add a reference for every instance of unique heap. 24 | */ 25 | UniqueHeap (void) 26 | { 27 | volatile SuperHeap * forceCreationOfSuperHeap = getSuperHeap(); 28 | addRef(); 29 | } 30 | 31 | /** 32 | * @brief Delete one reference to the unique heap. 33 | * When the number of references goes to zero, 34 | * delete the super heap. 35 | */ 36 | ~UniqueHeap (void) { 37 | int r = delRef(); 38 | if (r <= 0) { 39 | getSuperHeap()->SuperHeap::~SuperHeap(); 40 | } 41 | } 42 | 43 | // The remaining public methods are just 44 | // thin wrappers that route calls to the static object. 45 | 46 | inline void * malloc (size_t sz) { 47 | return getSuperHeap()->malloc (sz); 48 | } 49 | 50 | inline void free (void * ptr) { 51 | getSuperHeap()->free (ptr); 52 | } 53 | 54 | inline size_t getSize (void * ptr) { 55 | return getSuperHeap()->getSize (ptr); 56 | } 57 | 58 | inline int remove (void * ptr) { 59 | return getSuperHeap()->remove (ptr); 60 | } 61 | 62 | inline void clear (void) { 63 | getSuperHeap()->clear(); 64 | } 65 | 66 | #if 0 67 | inline int getAllocated (void) { 68 | return getSuperHeap()->getAllocated(); 69 | } 70 | 71 | inline int getMaxAllocated (void) { 72 | return getSuperHeap()->getMaxAllocated(); 73 | } 74 | 75 | inline int getMaxInUse (void) { 76 | return getSuperHeap()->getMaxInUse(); 77 | } 78 | #endif 79 | 80 | private: 81 | 82 | /// Add one reference. 83 | void addRef (void) { 84 | getRefs() += 1; 85 | } 86 | 87 | /// Delete one reference count. 88 | int delRef (void) { 89 | getRefs() -= 1; 90 | return getRefs(); 91 | } 92 | 93 | /// Internal accessor for reference count. 94 | int& getRefs (void) { 95 | static int numRefs = 0; 96 | return numRefs; 97 | } 98 | 99 | SuperHeap * getSuperHeap (void) { 100 | static char superHeapBuffer[sizeof(SuperHeap)]; 101 | static SuperHeap * aSuperHeap = (SuperHeap *) (new ((char *) &superHeapBuffer) SuperHeap); 102 | return aSuperHeap; 103 | } 104 | 105 | void doNothing (Child *) {} 106 | }; 107 | 108 | 109 | #endif // _UNIQUE_H_ 110 | -------------------------------------------------------------------------------- /heaplayers/util/bitindex.cpp: -------------------------------------------------------------------------------- 1 | #include "bitindex.h" 2 | 3 | // Definitions of static members of BitIndex. 4 | 5 | int BitIndex::index32[32]; 6 | unsigned long BitIndex::on[32]; 7 | unsigned long BitIndex::off[32]; 8 | unsigned long BitIndex::lgtable[16]; 9 | 10 | // Implementations. 11 | 12 | BitIndex::BitIndex (void) 13 | { 14 | setup(); 15 | } 16 | 17 | 18 | void BitIndex::setup (void) 19 | { 20 | int t[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3}; 21 | int i; 22 | for (i = 0; i < 32; i++) { 23 | index32[ (debruijn32 << i) >> 27 ] = i; 24 | } 25 | for (i = 0; i < 16; i++) { 26 | lgtable[i] = t[i]; 27 | } 28 | for (i = 0; i < 32; i++) { 29 | on[i] = 1 << i; 30 | off[i] = ~on[i]; 31 | } 32 | } 33 | 34 | 35 | 36 | // One instance of BitIndex so everything will work. 37 | 38 | static BitIndex _hiddenBitIndex; 39 | -------------------------------------------------------------------------------- /heaplayers/util/bitindex.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | /** 4 | * @file bitindex.h 5 | * 6 | * Bit-access operations, including msb and lsb. 7 | * @author Emery Berger (emery@cs.umass.edu) 8 | */ 9 | 10 | // lsb is due to Leiserson, Prokop, Randall (MIT). 11 | // msb is also a fast implementation of floor(lg_2). 12 | 13 | #ifndef _BITINDEX_H_ 14 | #define _BITINDEX_H_ 15 | 16 | #include 17 | 18 | namespace HL { 19 | 20 | class BitIndex { 21 | private: 22 | 23 | enum { debruijn32 = 0x077CB531UL }; 24 | static int index32[32]; 25 | static unsigned long lgtable[16]; 26 | static unsigned long on[32]; 27 | static unsigned long off[32]; 28 | 29 | void setup (void); 30 | 31 | public: 32 | 33 | BitIndex (void); 34 | ~BitIndex (void) {} 35 | 36 | // Set bit_index in b (to 1). 37 | static void set (unsigned long &b, int index) 38 | { 39 | assert (index >= 0); 40 | assert (index < 32); 41 | b |= on[index]; 42 | } 43 | 44 | // Reset bit_index in b (set it to 0). 45 | static void reset (unsigned long &b, int index) 46 | { 47 | assert (index >= 0); 48 | assert (index < 32); 49 | b &= off[index]; 50 | } 51 | 52 | // Find the least-significant bit. 53 | static int lsb (unsigned long b) 54 | { 55 | //#if 0 56 | #if 0 // i386 57 | // Intel x86 code. 58 | register unsigned long index = 0; 59 | if (b > 0) { 60 | asm ("bsfl %1, %0" : "=r" (index) : "r" (b)); 61 | } 62 | return index; 63 | #else 64 | b &= (unsigned long) -((signed long) b); 65 | b *= debruijn32; 66 | b >>= 27; 67 | return index32[b]; 68 | #endif 69 | } 70 | 71 | // Find the most-significant bit. 72 | static int msb (unsigned long b) 73 | { 74 | #if 0 // i386 75 | // Intel x86 code. 76 | register unsigned long index = 0; 77 | if (b > 0) { 78 | asm ("bsrl %1, %0" : "=r" (index) : "r" (b)); 79 | } 80 | return index; 81 | #else 82 | int l = 0; 83 | // b < 2^32 84 | if (b >= 65536) { 85 | l += 16; 86 | b >>= 16; 87 | } 88 | // b < 2^16 89 | if (b >= 256) { 90 | l += 8; 91 | b >>= 8; 92 | } 93 | // b < 2^8 94 | if (b >= 16) { 95 | l += 4; 96 | b >>= 4; 97 | } 98 | return l + lgtable[b]; 99 | #endif 100 | } 101 | 102 | 103 | }; 104 | 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /heaplayers/util/blockinglock.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #ifndef _BLOCKINGLOCK_H_ 4 | #define _BLOCKINGLOCK_H_ 5 | 6 | #if defined(_WIN32) 7 | #include "winlock.h" 8 | #else 9 | #include "posixlock.h" 10 | #endif 11 | 12 | namespace HL { 13 | 14 | class BlockingLock : 15 | #if defined(_WIN32) 16 | public WinLockType {}; 17 | #else 18 | public PosixLockType {}; 19 | #endif 20 | 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /heaplayers/util/fred.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #ifndef _FRED_H_ 4 | #define _FRED_H_ 5 | 6 | /// A thread-wrapper of childlike simplicity :). 7 | 8 | #if defined(_WIN32) 9 | 10 | #include 11 | #include 12 | 13 | #elif defined(__SVR4) 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #else 20 | 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | namespace HL { 27 | 28 | extern "C" typedef void * (*ThreadFunctionType) (void *); 29 | 30 | class Fred { 31 | public: 32 | 33 | Fred (void) { 34 | #if !defined(_WIN32) 35 | pthread_attr_init (&attr); 36 | #endif 37 | } 38 | 39 | ~Fred (void) { 40 | #if !defined(_WIN32) 41 | pthread_attr_destroy (&attr); 42 | #endif 43 | } 44 | 45 | void create (ThreadFunctionType function, void * arg) { 46 | #if defined(_WIN32) 47 | t = CreateThread (0, 0, (LPTHREAD_START_ROUTINE) *function, (LPVOID) arg, 0, 0); 48 | #else 49 | pthread_create (&t, &attr, function, arg); 50 | #endif 51 | } 52 | 53 | void join (void) { 54 | #if defined(_WIN32) 55 | WaitForSingleObject (t, INFINITE); 56 | #else 57 | pthread_join (t, NULL); 58 | #endif 59 | } 60 | 61 | static void yield (void) { 62 | #if defined(_WIN32) 63 | Sleep (0); 64 | #elif defined(__SVR4) 65 | thr_yield(); 66 | #else 67 | sched_yield(); 68 | #endif 69 | } 70 | 71 | 72 | static void setConcurrency (int n) { 73 | #if defined(_WIN32) 74 | #elif defined(__SVR4) 75 | thr_setconcurrency (n); 76 | #else 77 | pthread_setconcurrency (n); 78 | #endif 79 | } 80 | 81 | 82 | private: 83 | #if defined(_WIN32) 84 | typedef HANDLE FredType; 85 | #else 86 | typedef pthread_t FredType; 87 | pthread_attr_t attr; 88 | #endif 89 | 90 | FredType t; 91 | }; 92 | 93 | } 94 | 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /heaplayers/util/guard.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #ifndef _GUARD_H_ 4 | #define _GUARD_H_ 5 | 6 | namespace HL { 7 | 8 | template 9 | class Guard { 10 | public: 11 | inline Guard (LockType& l) 12 | : _lock (l) 13 | { 14 | _lock.lock(); 15 | } 16 | 17 | inline ~Guard (void) { 18 | _lock.unlock(); 19 | } 20 | private: 21 | LockType& _lock; 22 | }; 23 | 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /heaplayers/util/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef _HL_HASH_H_ 2 | #define _HL_HASH_H_ 3 | 4 | #include 5 | 6 | namespace HL { 7 | template 8 | extern size_t hash (Key k); 9 | 10 | template <> 11 | inline size_t hash (void * v) { 12 | return (size_t) v; 13 | } 14 | 15 | template <> 16 | inline size_t hash (const void * v) { 17 | return (size_t) ((size_t) v); 18 | } 19 | 20 | template <> 21 | inline size_t hash (int v) { 22 | return (size_t) v; 23 | } 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /heaplayers/util/posixlock.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _POSIXLOCK_H_ 28 | #define _POSIXLOCK_H_ 29 | 30 | #if !defined(_WIN32) 31 | 32 | #include 33 | 34 | /** 35 | * @class PosixLockType 36 | * @brief Locking using POSIX mutex objects. 37 | */ 38 | 39 | namespace HL { 40 | 41 | class PosixLockType { 42 | public: 43 | 44 | PosixLockType (void) 45 | { 46 | int r = pthread_mutex_init (&mutex, NULL); 47 | if (r) { 48 | throw 0; 49 | } 50 | } 51 | 52 | ~PosixLockType (void) 53 | { 54 | pthread_mutex_destroy (&mutex); 55 | } 56 | 57 | void lock (void) { 58 | pthread_mutex_lock (&mutex); 59 | } 60 | 61 | void unlock (void) { 62 | pthread_mutex_unlock (&mutex); 63 | } 64 | 65 | private: 66 | union { 67 | pthread_mutex_t mutex; 68 | double _dummy[sizeof(pthread_mutex_t)/sizeof(double) + 1]; 69 | }; 70 | }; 71 | 72 | } 73 | 74 | #endif 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /heaplayers/util/recursivelock.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _RECURSIVELOCK_H_ 4 | #define _RECURSIVELOCK_H_ 5 | 6 | /** 7 | * @class RecursiveLockType 8 | * @brief Implements a recursive lock using some base lock representation. 9 | * @param BaseLock The base lock representation. 10 | */ 11 | 12 | #include "cpuinfo.h" 13 | 14 | namespace HL { 15 | 16 | template 17 | class RecursiveLockType : public BaseLock { 18 | public: 19 | 20 | inline RecursiveLockType (void); 21 | 22 | inline void lock (void); 23 | inline void unlock (void); 24 | 25 | private: 26 | int tid; /// The lock owner's thread id. -1 if unlocked. 27 | int count; /// The recursion depth of the lock. 28 | }; 29 | 30 | 31 | }; 32 | 33 | template 34 | HL::RecursiveLockType::RecursiveLockType (void) 35 | : tid (-1), 36 | count (0) 37 | {} 38 | 39 | template 40 | void HL::RecursiveLockType::lock (void) { 41 | int currthread = CPUInfo::getThreadId(); 42 | if (tid == currthread) { 43 | count++; 44 | } else { 45 | BaseLock::lock(); 46 | tid = currthread; 47 | count++; 48 | } 49 | } 50 | 51 | template 52 | void HL::RecursiveLockType::unlock (void) { 53 | int currthread = CPUInfo::getThreadId(); 54 | if (tid == currthread) { 55 | count--; 56 | if (count == 0) { 57 | tid = -1; 58 | BaseLock::unlock(); 59 | } 60 | } else { 61 | // We tried to unlock it but we didn't lock it! 62 | // This should never happen. 63 | assert (0); 64 | abort(); 65 | } 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /heaplayers/util/sassert.h: -------------------------------------------------------------------------------- 1 | #ifndef _SASSERT_H_ 2 | #define _SASSERT_H_ 3 | 4 | /** 5 | * @class sassert 6 | * @brief Implements compile-time assertion checking. 7 | * @author Emery Berger 8 | * 9 | * @code 10 | * sassert<(1+1 == 2)> CheckOnePlusOneIsTwo; 11 | * @endcode 12 | * 13 | * This code is part of the Hoard distribution and is governed by its license. 14 | * 15 | * 16 | */ 17 | 18 | namespace HL { 19 | 20 | template 21 | class sassert; 22 | 23 | template<> class sassert<1> { 24 | public: 25 | enum { VALUE = 1 }; 26 | }; 27 | 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /heaplayers/util/sllist.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2003 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _SLLIST_H_ 28 | #define _SLLIST_H_ 29 | 30 | #include 31 | 32 | /** 33 | * @class SLList 34 | * @brief A "memory neutral" singly-linked list. 35 | * @author Emery Berger 36 | */ 37 | 38 | namespace HL { 39 | 40 | class SLList { 41 | public: 42 | 43 | inline SLList (void) { 44 | clear(); 45 | } 46 | 47 | class Entry; 48 | 49 | /// Clear the list. 50 | inline void clear (void) { 51 | head.next = NULL; 52 | } 53 | 54 | /// Get the head of the list. 55 | inline Entry * get (void) { 56 | const Entry * e = head.next; 57 | if (e == NULL) { 58 | return NULL; 59 | } 60 | head.next = e->next; 61 | return (Entry *) e; 62 | } 63 | 64 | private: 65 | 66 | /** 67 | * @brief Remove one item from the list. 68 | * @warning This method aborts the program if called. 69 | */ 70 | inline void remove (Entry *) { 71 | abort(); 72 | } 73 | 74 | public: 75 | 76 | /// Inserts an entry into the head of the list. 77 | inline void insert (Entry * e) { 78 | e->next = head.next; 79 | head.next = e; 80 | } 81 | 82 | /// An entry in the list. 83 | class Entry { 84 | public: 85 | inline Entry (void) 86 | : next (NULL) 87 | {} 88 | // private: 89 | // Entry * prev; 90 | public: 91 | Entry * next; 92 | }; 93 | 94 | private: 95 | 96 | /// The head of the list. 97 | Entry head; 98 | 99 | }; 100 | 101 | } 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /heaplayers/util/sparc-interchange.il: -------------------------------------------------------------------------------- 1 | .inline MyInterlockedExchange,8 2 | 3 | mov %o0,%o2 4 | mov %o1,%o0 5 | swap [%o2],%o0 6 | 7 | .end 8 | -------------------------------------------------------------------------------- /heaplayers/util/winlock.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _WINLOCK_H_ 4 | #define _WINLOCK_H_ 5 | 6 | #if defined(_WIN32) 7 | 8 | #include 9 | 10 | /** 11 | * @class WinLockType 12 | * @brief Locking using Win32 mutexes. 13 | * 14 | * Note that this lock type detects whether we are running on a 15 | * multiprocessor. If not, then we do not use atomic operations. 16 | */ 17 | 18 | #if 1 19 | 20 | namespace HL { 21 | 22 | class WinLockType { 23 | public: 24 | 25 | WinLockType (void) 26 | : mutex (0) 27 | {} 28 | 29 | ~WinLockType (void) 30 | { 31 | mutex = 0; 32 | } 33 | 34 | inline void lock (void) { 35 | #if 1 36 | // We're on a multiprocessor - use atomic operations. 37 | while (InterlockedExchange ((long *) &mutex, 1) != 0) 38 | Sleep (0); 39 | #endif 40 | } 41 | 42 | inline void unlock (void) { 43 | mutex = 0; 44 | // InterlockedExchange (&mutex, 0); 45 | } 46 | 47 | private: 48 | unsigned int mutex; 49 | bool onMultiprocessor (void) { 50 | SYSTEM_INFO infoReturn[1]; 51 | GetSystemInfo (infoReturn); 52 | if (infoReturn->dwNumberOfProcessors == 1) { 53 | return FALSE; 54 | } else { 55 | return TRUE; 56 | } 57 | } 58 | }; 59 | 60 | }; 61 | 62 | #else 63 | 64 | #include 65 | 66 | class WinLockType { 67 | public: 68 | 69 | WinLockType (void) 70 | { 71 | InitializeCriticalSection(&mutex); 72 | } 73 | 74 | ~WinLockType (void) 75 | { 76 | DeleteCriticalSection(&mutex); 77 | } 78 | 79 | inline void lock (void) { 80 | EnterCriticalSection(&mutex); 81 | } 82 | 83 | inline void unlock (void) { 84 | LeaveCriticalSection(&mutex); 85 | } 86 | 87 | private: 88 | CRITICAL_SECTION mutex; 89 | }; 90 | 91 | #endif 92 | 93 | #endif 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /heaplayers/util/x86-interchange.il: -------------------------------------------------------------------------------- 1 | .inline MyInterlockedExchange,0 2 | 3 | movl (%esp),%ecx 4 | movl 4(%esp),%eax 5 | lock 6 | xchgl %eax,(%ecx) 7 | 8 | .end 9 | -------------------------------------------------------------------------------- /heaplayers/util/x86_64-interchange.il: -------------------------------------------------------------------------------- 1 | .inline MyInterlockedExchange,0 2 | 3 | movq %rsi,%rax 4 | lock 5 | xchgq %rax,(%rdi) 6 | 7 | .end 8 | -------------------------------------------------------------------------------- /heaplayers/utility.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | #ifndef _UTILITY_H_ 4 | #define _UTILITY_H_ 5 | 6 | /** 7 | * @file utility.h 8 | * @brief Convenient wrappers that let us new up & delete objects from heaps. 9 | * 10 | * 11 | * Example:
12 | * 13 | * 14 | * Heap h;
15 | *
16 | * Foo * foo;
17 | * newObject (foo,h); // instead of: foo = new Foo;
18 | * deleteObject (foo,h); // instead of: delete foo;
19 | *
20 | * Foo * foo2;
21 | * newArray (foo2, 10, h); // instead of: foo2 = new Foo[10];
22 | * deleteArray (foo2, h); // instead of: delete [] foo2;
23 | * 24 | */ 25 | 26 | #include 27 | 28 | 29 | // Construct an object on a given heap. 30 | class newObject { 31 | public: 32 | template 33 | inline void operator() (Object*& o, Heap& h) const { 34 | o = new (h.malloc (sizeof(Object))) Object; 35 | } 36 | 37 | template 38 | inline void operator() (Object*& o, const A1& a1, Heap& h) const { 39 | o = new (h.malloc (sizeof(Object))) Object (a1); 40 | } 41 | 42 | template 43 | inline void operator() (Object*& o, const A1& a1, const A2& a2, Heap& h) const { 44 | o = new (h.malloc (sizeof(Object))) Object (a1, a2); 45 | } 46 | 47 | template 48 | inline void operator() (Object*& o, const A1& a1, const A2& a2, const A3& a3, Heap& h) const { 49 | o = new (h.malloc (sizeof(Object))) Object (a1, a2, a3); 50 | } 51 | }; 52 | 53 | 54 | // Delete an object to a given heap. 55 | class deleteObject { 56 | public: 57 | template 58 | inline void operator()(Object*& o, Heap& h) { 59 | o->~Object(); 60 | h.free (o); 61 | } 62 | }; 63 | 64 | 65 | class newArray { 66 | public: 67 | template 68 | inline void operator() (Object*& o, unsigned int n, Heap& h) const { 69 | // Store the number of array elements in the beginning of the space. 70 | double * ptr = (double *) h.malloc (sizeof(Object) * n + sizeof(double)); 71 | *((unsigned int *) ptr) = n; 72 | // Initialize every element. 73 | ptr++; 74 | Object * ptr2 = (Object *) ptr; 75 | // Save the pointer to the start of the array. 76 | o = ptr2; 77 | // Now iterate and construct every object in place. 78 | for (unsigned int i = 0; i < n; i++) { 79 | new ((void *) ptr2) Object; 80 | ptr2++; 81 | } 82 | } 83 | }; 84 | 85 | 86 | class deleteArray { 87 | public: 88 | template 89 | inline void operator()(Object*& o, Heap& h) const { 90 | unsigned int n = *((unsigned int *) ((double *) o - 1)); 91 | Object * optr = o; 92 | // Call the destructor on every element in the array. 93 | for (unsigned int i = 0; i < n; i++) { 94 | optr->~Object(); 95 | optr++; 96 | } 97 | // Free the array. 98 | h.free ((void *) ((double *) o - 1)); 99 | } 100 | }; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /heaplayers/xallocHeap.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- */ 2 | 3 | /* 4 | 5 | Heap Layers: An Extensible Memory Allocation Infrastructure 6 | 7 | Copyright (C) 2000-2005 by Emery Berger 8 | http://www.cs.umass.edu/~emery 9 | emery@cs.umass.edu 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | 25 | */ 26 | 27 | #ifndef _XALLOCHEAP_H_ 28 | #define _XALLOCHEAP_H_ 29 | 30 | namespace HL { 31 | 32 | template 33 | class XallocHeap : public SuperHeap { 34 | 35 | public: 36 | 37 | inline XallocHeap (void) { 38 | start_of_array = (char *) SuperHeap::malloc (ArenaSize); 39 | end_of_array = start_of_array + align(sizeof(Nuggie)); 40 | size_lval(end_of_array) = 0; 41 | last_block = NULL; 42 | } 43 | 44 | inline ~XallocHeap (void) { 45 | SuperHeap::free (start_of_array); 46 | } 47 | 48 | inline void * malloc (size_t size) { 49 | char * old_end_of_array = end_of_array; 50 | end_of_array += align(size + sizeof(Nuggie)); 51 | if (old_end_of_array + size >= start_of_array + ArenaSize) { 52 | // We're out of memory. 53 | return NULL; 54 | } 55 | size_lval(end_of_array) = end_of_array - old_end_of_array; 56 | clear_use(end_of_array); /* this is not necessary, cause it will be zero */ 57 | set_use(old_end_of_array); 58 | last_block = old_end_of_array; 59 | return old_end_of_array; 60 | } 61 | 62 | inline void free (void * ptr) { 63 | char * p = (char *) ptr; 64 | char * q; 65 | /* At this point we could check that the in_use bit for this block 66 | is set, and also check that the size is right */ 67 | clear_use(p); /* mark this block as unused */ 68 | if (p == last_block) { 69 | while (1) { 70 | q = prev_block(p); 71 | if (q == p) { 72 | last_block = NULL; 73 | end_of_array = p; 74 | break; /* only happens when we get to the beginning */ 75 | } 76 | if (in_use(q)) { 77 | last_block = q; 78 | end_of_array = p; 79 | break; 80 | } 81 | p = q; 82 | } 83 | } 84 | } 85 | 86 | private: 87 | 88 | static inline size_t& size_lval (char * x) { 89 | return (((Nuggie *)(((char *)x) - sizeof(Nuggie)))->size); 90 | } 91 | 92 | static inline char * prev_block (char * x) { 93 | return (((char *) x) - (size_lval(x) & (~1))); 94 | } 95 | 96 | static inline int in_use (char * x) { 97 | return (size_lval(x) & (1)); 98 | } 99 | 100 | static inline void set_use (char * x) { 101 | (size_lval(x) |= (1)); 102 | } 103 | 104 | static inline void clear_use (char * x) { 105 | (size_lval(x) &= (~1)); 106 | } 107 | 108 | class Nuggie { 109 | public: 110 | size_t size; 111 | }; 112 | 113 | inline static size_t align (int sz) { 114 | return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1); 115 | } 116 | 117 | char * end_of_array; 118 | char * start_of_array; 119 | char * last_block; 120 | }; 121 | 122 | }; 123 | 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /include/detect/objectinfo.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #ifndef SHERIFF_OBJECTINFO_H 4 | #define SHERIFF_OBJECTINFO_H 5 | 6 | #include "wordchangeinfo.h" 7 | 8 | class ObjectInfo { 9 | public: 10 | bool is_heap_object; 11 | int access_threads; // False sharing type, inter-objects or inner-object 12 | int times; 13 | unsigned long interwrites; 14 | unsigned long totalwrites; 15 | unsigned long unitlength; 16 | unsigned long totallength; 17 | unsigned long lines; 18 | unsigned long actuallines; 19 | unsigned long * start; 20 | unsigned long * stop; 21 | void * symbol; // Used for globals only. 22 | wordchangeinfo* wordchange_start; 23 | wordchangeinfo* wordchange_stop; 24 | unsigned long callsite[CALL_SITE_DEPTH]; 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/detect/wordchangeinfo.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | #ifndef SHERIFF_WORDCHANGEINFO_H 4 | #define SHERIFF_WORDCHANGEINFO_H 5 | 6 | class wordchangeinfo { 7 | public: 8 | unsigned short tid; 9 | unsigned short version; 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /include/heap/privateheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | Copyright (c) 2011, University of Massachusetts Amherst. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | 20 | */ 21 | 22 | #ifndef _PRIVATEHEAP_H_ 23 | #define _PRIVATEHEAP_H_ 24 | #include "stdio.h" 25 | #include "string.h" 26 | /** 27 | * @file privateheap.h 28 | * @brief A private heap for internal allocation needs. Basically, those memory won't be seen by others. 29 | * @author Emery Berger 30 | * @author Tongping Liu 31 | * 32 | */ 33 | 34 | extern "C" { 35 | void * dlmalloc (size_t sz); 36 | void dlfree (void *); 37 | size_t dlmalloc_usable_size (void *); 38 | void * dlrealloc(void * ptr, size_t sz); 39 | } 40 | 41 | class privateheap { 42 | public: 43 | 44 | virtual ~privateheap (void) {} 45 | 46 | static void * malloc (size_t sz) { 47 | return dlmalloc (sz); 48 | } 49 | 50 | static void free (void * ptr) { 51 | dlfree (ptr); 52 | } 53 | 54 | static size_t getSize (void * ptr) { 55 | return dlmalloc_usable_size (ptr); 56 | } 57 | 58 | static void * realloc(void * ptr, size_t sz) { 59 | return dlrealloc(ptr, sz); 60 | } 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /include/heap/xadaptheap.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | 3 | /* 4 | Copyright (c) 2011, University of Massachusetts Amherst. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | 20 | */ 21 | 22 | #ifndef _XADAPTHEAP_H_ 23 | #define _XADAPTHEAP_H_ 24 | 25 | /** 26 | * @class xadaptheap 27 | * @brief Manages a heap whose metadata is allocated from a given source. 28 | * 29 | * @author Emery Berger 30 | * @author Tongping Liu 31 | */ 32 | 33 | template