Mercurial > projects > hoofbaby
annotate src/impl/hoofbaby/util/memory.d @ 0:3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
author | fraserofthenight |
---|---|
date | Mon, 06 Jul 2009 08:06:28 -0700 |
parents | |
children |
rev | line source |
---|---|
0
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
1 /** |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
2 * Hoofbaby -- http://www.dsource.org/projects/hoofbaby |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
3 * Copyright (C) 2009 Robert Fraser |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
4 * |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
5 * This program is free software; you can redistribute it andor |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
6 * modify it under the terms of the GNU General Public License |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
7 * as published by the Free Software Foundation; either version 2 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
8 * of the License, or (at your option) any later version. |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
9 * |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
10 * This program is distributed in the hope that it will be useful, |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
13 * GNU General Public License for more details. |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
14 */ |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
15 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
16 module hoofbaby.util.memory; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
17 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
18 import tango.core.Memory : GC; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
19 import candy.util.array; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
20 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
21 /** |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
22 * Provides a pool of GCed memory to allocate things from a block. |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
23 * This maintains cache coherency for related types (i.e. tree nodes). |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
24 * It doesn't garuntee any ordering, though, the array struct should be |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
25 * used for that. Also, everything has to be freed at once, freeing one |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
26 * portion of this has no effect. |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
27 * |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
28 * Based on a similar concept posted by bearophile at: |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
29 * http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=88227 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
30 */ |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
31 public struct MemPool(size_t BLOCK_SIZE = 1 << 14) |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
32 { |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
33 private void* next; // Next available block |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
34 private void* end; // End of the current block |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
35 private void*[] blocks; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
36 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
37 public void* alloc(size_t sz) |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
38 { |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
39 sz = ((sz + 7) & ~7); // Next multiple of 8 if this isn't a multiple of 8 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
40 if (this.next + sz >= this.end) |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
41 { |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
42 void* blk = GC.calloc(BLOCK_SIZE); |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
43 this.blocks.length = this.blocks.length + 1; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
44 this.blocks[$ - 1] = blk; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
45 this.next = blk; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
46 this.end = blk + BLOCK_SIZE; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
47 } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
48 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
49 void* ret = this.next; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
50 this.next += sz; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
51 return ret; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
52 } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
53 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
54 public void free() |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
55 { |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
56 foreach(blk; this.blocks) |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
57 GC.free(blk); |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
58 this.blocks = null; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
59 this.blocks.length = 0; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
60 this.next = null; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
61 this.end = null; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
62 } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
63 } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
64 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
65 /** |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
66 * Wrapper for MemPool that allocates the given struct |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
67 */ |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
68 public struct StructPool(T) |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
69 { |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
70 private MemPool!() pool; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
71 public T* alloc() { return cast(T*) pool.alloc(T.sizeof); } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
72 } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
73 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
74 public struct MemStack(size_t BLOCK_SIZE = 1 << 14) |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
75 { |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
76 private Stack!(MemPool!(BLOCK_SIZE)*, 16, true, true) stack; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
77 public static const size_t MAX_ALLOC = BLOCK_SIZE; |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
78 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
79 public void* alloc(size_t sz) { return stack.peek().alloc(sz); } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
80 public void push() { stack.push(new MemPool!(BLOCK_SIZE)); } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
81 public void pop() { stack.pop().free(); } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
82 } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
83 |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
84 /** |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
85 * Placement new mixin for allocating from a memory pool. Benchmarks show this |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
86 * as faster than the D new in real usage (i.e. the parser runs about 1.2x |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
87 * faster using this). |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
88 */ |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
89 public template MemPoolNew(alias Pool) |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
90 { |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
91 version(NoMemPool) { } else |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
92 { |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
93 public final new(uint sz) { return Pool.alloc(sz); } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
94 public final delete(void *p) { } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
95 } |
3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
fraserofthenight
parents:
diff
changeset
|
96 } |