comparison tango/lib/gc/basic/gcbits.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children a168a2c3ea48
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
1 /**
2 * This module contains a specialized bitset implementation.
3 *
4 * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com.
5 * All rights reserved.
6 * License:
7 * This software is provided 'as-is', without any express or implied
8 * warranty. In no event will the authors be held liable for any damages
9 * arising from the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, in both source and binary form, subject to the following
14 * restrictions:
15 *
16 * o The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software
18 * in a product, an acknowledgment in the product documentation would be
19 * appreciated but is not required.
20 * o Altered source versions must be plainly marked as such, and must not
21 * be misrepresented as being the original software.
22 * o This notice may not be removed or altered from any source
23 * distribution.
24 * Authors: Walter Bright, David Friedman, Sean Kelly
25 */
26
27
28 private import tango.core.BitManip;
29 private import tango.stdc.string;
30 private import tango.stdc.stdlib;
31 private extern (C) void onOutOfMemoryError();
32
33
34 version (DigitalMars)
35 {
36 version = bitops;
37 }
38 else version (GNU)
39 {
40 // use the unoptimized version
41 }
42 else version (D_InlineAsm_X86)
43 {
44 version = Asm86;
45 }
46
47 struct GCBits
48 {
49 const int BITS_PER_WORD = 32;
50 const int BITS_SHIFT = 5;
51 const int BITS_MASK = 31;
52
53 uint *data = null;
54 uint nwords = 0; // allocated words in data[] excluding sentinals
55 uint nbits = 0; // number of bits in data[] excluding sentinals
56
57 void Dtor()
58 {
59 if (data)
60 {
61 free(data);
62 data = null;
63 }
64 }
65
66 invariant
67 {
68 if (data)
69 {
70 assert(nwords * data[0].sizeof * 8 >= nbits);
71 }
72 }
73
74 void alloc(uint nbits)
75 {
76 this.nbits = nbits;
77 nwords = (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;
78 data = cast(uint *)calloc(nwords + 2, uint.sizeof);
79 if (!data)
80 onOutOfMemoryError();
81 }
82
83 uint test(uint i)
84 in
85 {
86 assert(i < nbits);
87 }
88 body
89 {
90 //return (cast(bit *)(data + 1))[i];
91 return data[1 + (i >> BITS_SHIFT)] & (1 << (i & BITS_MASK));
92 }
93
94 void set(uint i)
95 in
96 {
97 assert(i < nbits);
98 }
99 body
100 {
101 //(cast(bit *)(data + 1))[i] = 1;
102 data[1 + (i >> BITS_SHIFT)] |= (1 << (i & BITS_MASK));
103 }
104
105 void clear(uint i)
106 in
107 {
108 assert(i < nbits);
109 }
110 body
111 {
112 //(cast(bit *)(data + 1))[i] = 0;
113 data[1 + (i >> BITS_SHIFT)] &= ~(1 << (i & BITS_MASK));
114 }
115
116 uint testClear(uint i)
117 {
118 version (bitops)
119 {
120 return std.intrinsic.btr(data + 1, i);
121 }
122 else version (Asm86)
123 {
124 asm
125 {
126 naked ;
127 mov EAX,data[EAX] ;
128 mov ECX,i-4[ESP] ;
129 btr 4[EAX],ECX ;
130 sbb EAX,EAX ;
131 ret 4 ;
132 }
133 }
134 else
135 { uint result;
136
137 //result = (cast(bit *)(data + 1))[i];
138 //(cast(bit *)(data + 1))[i] = 0;
139
140 uint *p = &data[1 + (i >> BITS_SHIFT)];
141 uint mask = (1 << (i & BITS_MASK));
142 result = *p & mask;
143 *p &= ~mask;
144 return result;
145 }
146 }
147
148 void zero()
149 {
150 memset(data + 1, 0, nwords * uint.sizeof);
151 }
152
153 void copy(GCBits *f)
154 in
155 {
156 assert(nwords == f.nwords);
157 }
158 body
159 {
160 memcpy(data + 1, f.data + 1, nwords * uint.sizeof);
161 }
162
163 uint *base()
164 in
165 {
166 assert(data);
167 }
168 body
169 {
170 return data + 1;
171 }
172 }
173
174 unittest
175 {
176 GCBits b;
177
178 b.alloc(786);
179 assert(b.test(123) == 0);
180 assert(b.testClear(123) == 0);
181 b.set(123);
182 assert(b.test(123) != 0);
183 assert(b.testClear(123) != 0);
184 assert(b.test(123) == 0);
185
186 b.set(785);
187 b.set(0);
188 assert(b.test(785) != 0);
189 assert(b.test(0) != 0);
190 b.zero();
191 assert(b.test(785) == 0);
192 assert(b.test(0) == 0);
193
194 GCBits b2;
195 b2.alloc(786);
196 b2.set(38);
197 b.copy(&b2);
198 assert(b.test(38) != 0);
199 b2.Dtor();
200
201 b.Dtor();
202 }