mirror of
https://github.com/dlang/phobos.git
synced 2025-04-30 15:10:46 +03:00
Make bitmapped_block allocate @safe
This commit is contained in:
parent
0d45880abe
commit
e100cde76f
1 changed files with 37 additions and 28 deletions
|
@ -303,7 +303,8 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
Allocations greater than 64 blocks require a multiword search through the
|
Allocations greater than 64 blocks require a multiword search through the
|
||||||
metadata.
|
metadata.
|
||||||
*/
|
*/
|
||||||
@trusted void[] allocate(const size_t s)
|
pure nothrow @trusted @nogc
|
||||||
|
void[] allocate(const size_t s)
|
||||||
{
|
{
|
||||||
const blocks = s.divideRoundUp(blockSize);
|
const blocks = s.divideRoundUp(blockSize);
|
||||||
void[] result = void;
|
void[] result = void;
|
||||||
|
@ -509,9 +510,10 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
return available;
|
return available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pure nothrow @safe @nogc
|
||||||
private void[] smallAlloc(uint blocks)
|
private void[] smallAlloc(uint blocks)
|
||||||
{
|
{
|
||||||
assert(blocks >= 2 && blocks <= 64, text(blocks));
|
assert(blocks >= 2 && blocks <= 64);
|
||||||
void[] result;
|
void[] result;
|
||||||
foreach (i; _startIdx .. _control.rep.length)
|
foreach (i; _startIdx .. _control.rep.length)
|
||||||
{
|
{
|
||||||
|
@ -544,6 +546,7 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pure nothrow @safe @nogc
|
||||||
private void[] hugeAlloc(size_t blocks)
|
private void[] hugeAlloc(size_t blocks)
|
||||||
{
|
{
|
||||||
assert(blocks > 64);
|
assert(blocks > 64);
|
||||||
|
@ -806,19 +809,21 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
uint blockSize = 64;
|
uint blockSize = 64;
|
||||||
auto a = BitmappedBlock!(chooseAtRuntime, 64)(cast(ubyte[])(r.allocateAll()), blockSize);
|
auto a = BitmappedBlock!(chooseAtRuntime, 64)(cast(ubyte[])(r.allocateAll()), blockSize);
|
||||||
static assert(hasMember!(InSituRegion!(10_240, 64), "allocateAll"));
|
static assert(hasMember!(InSituRegion!(10_240, 64), "allocateAll"));
|
||||||
const b = a.allocate(100);
|
const b = (() pure nothrow @safe @nogc => a.allocate(100))();
|
||||||
assert(b.length == 100);
|
assert(b.length == 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@system unittest
|
pure @safe unittest
|
||||||
{
|
{
|
||||||
import std.typecons : Ternary;
|
import std.typecons : Ternary;
|
||||||
|
|
||||||
auto a = BitmappedBlock!(64, 64)(new ubyte[10_240]);
|
auto a = (() @trusted => BitmappedBlock!(64, 64)(new ubyte[10_240]))();
|
||||||
assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);
|
() nothrow @nogc {
|
||||||
|
assert(a.empty == Ternary.yes);
|
||||||
const b = a.allocate(100);
|
const b = a.allocate(100);
|
||||||
assert(b.length == 100);
|
assert(b.length == 100);
|
||||||
assert((() nothrow @safe @nogc => a.empty)() == Ternary.no);
|
assert(a.empty == Ternary.no);
|
||||||
|
}();
|
||||||
}
|
}
|
||||||
|
|
||||||
@system unittest
|
@system unittest
|
||||||
|
@ -851,10 +856,10 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
blocks = a._blocks;
|
blocks = a._blocks;
|
||||||
|
|
||||||
// test allocation of 0 bytes
|
// test allocation of 0 bytes
|
||||||
auto x = a.allocate(0);
|
auto x = (() pure nothrow @safe @nogc => a.allocate(0))();
|
||||||
assert(x is null);
|
assert(x is null);
|
||||||
// test allocation of 1 byte
|
// test allocation of 1 byte
|
||||||
x = a.allocate(1);
|
x = (() pure nothrow @safe @nogc => a.allocate(1))();
|
||||||
assert(x.length == 1 || blocks == 0,
|
assert(x.length == 1 || blocks == 0,
|
||||||
text(x.ptr, " ", x.length, " ", a));
|
text(x.ptr, " ", x.length, " ", a));
|
||||||
assert((() nothrow @nogc => a.deallocateAll())());
|
assert((() nothrow @nogc => a.deallocateAll())());
|
||||||
|
@ -864,12 +869,14 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
begin:
|
begin:
|
||||||
foreach (i; 0 .. blocks / blocksAtATime)
|
foreach (i; 0 .. blocks / blocksAtATime)
|
||||||
{
|
{
|
||||||
auto b = a.allocate(bs * blocksAtATime);
|
auto b = (() pure nothrow @safe @nogc => a.allocate(bs * blocksAtATime))();
|
||||||
assert(b.length == bs * blocksAtATime, text(i, ": ", b.length));
|
assert(b.length == bs * blocksAtATime, text(i, ": ", b.length));
|
||||||
}
|
}
|
||||||
assert(a.allocate(bs * blocksAtATime) is null);
|
assert((() pure nothrow @safe @nogc => a.allocate(bs * blocksAtATime))() is null);
|
||||||
if (a._blocks % blocksAtATime == 0)
|
if (a._blocks % blocksAtATime == 0)
|
||||||
assert(a.allocate(1) is null);
|
{
|
||||||
|
assert((() pure nothrow @safe @nogc => a.allocate(1))() is null);
|
||||||
|
}
|
||||||
|
|
||||||
// Now deallocate all and do it again!
|
// Now deallocate all and do it again!
|
||||||
assert((() nothrow @nogc => a.deallocateAll())());
|
assert((() nothrow @nogc => a.deallocateAll())());
|
||||||
|
@ -879,13 +886,15 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
auto v = new void[][blocks / blocksAtATime];
|
auto v = new void[][blocks / blocksAtATime];
|
||||||
foreach (i; 0 .. blocks / blocksAtATime)
|
foreach (i; 0 .. blocks / blocksAtATime)
|
||||||
{
|
{
|
||||||
auto b = a.allocate(bs * blocksAtATime);
|
auto b = (() pure nothrow @safe @nogc => a.allocate(bs * blocksAtATime))();
|
||||||
assert(b.length == bs * blocksAtATime, text(i, ": ", b.length));
|
assert(b.length == bs * blocksAtATime, text(i, ": ", b.length));
|
||||||
v[i] = b;
|
v[i] = b;
|
||||||
}
|
}
|
||||||
assert(a.allocate(bs * blocksAtATime) is null);
|
assert((() pure nothrow @safe @nogc => a.allocate(bs * blocksAtATime))() is null);
|
||||||
if (a._blocks % blocksAtATime == 0)
|
if (a._blocks % blocksAtATime == 0)
|
||||||
assert(a.allocate(1) is null);
|
{
|
||||||
|
assert((() pure nothrow @safe @nogc => a.allocate(1))() is null);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (i; 0 .. blocks / blocksAtATime)
|
foreach (i; 0 .. blocks / blocksAtATime)
|
||||||
{
|
{
|
||||||
|
@ -894,7 +903,7 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
|
|
||||||
foreach (i; 0 .. blocks / blocksAtATime)
|
foreach (i; 0 .. blocks / blocksAtATime)
|
||||||
{
|
{
|
||||||
auto b = a.allocate(bs * blocksAtATime);
|
auto b = (() pure nothrow @safe @nogc => a.allocate(bs * blocksAtATime))();
|
||||||
assert(b.length == bs * blocksAtATime, text(i, ": ", b.length));
|
assert(b.length == bs * blocksAtATime, text(i, ": ", b.length));
|
||||||
v[i] = b;
|
v[i] = b;
|
||||||
}
|
}
|
||||||
|
@ -917,7 +926,7 @@ struct BitmappedBlock(size_t theBlockSize, uint theAlignment = platformAlignment
|
||||||
{
|
{
|
||||||
foreach (i; 0 .. blocks / blocksAtATime - 1)
|
foreach (i; 0 .. blocks / blocksAtATime - 1)
|
||||||
{
|
{
|
||||||
auto b = a.allocate(bs * blocksAtATime);
|
auto b = (() pure nothrow @safe @nogc => a.allocate(bs * blocksAtATime))();
|
||||||
assert(b.length == bs * blocksAtATime, text(i, ": ", b.length));
|
assert(b.length == bs * blocksAtATime, text(i, ": ", b.length));
|
||||||
(cast(ubyte[]) b)[] = 0xff;
|
(cast(ubyte[]) b)[] = 0xff;
|
||||||
assert((() pure nothrow @safe @nogc => a.expand(b, blocksAtATime * bs))()
|
assert((() pure nothrow @safe @nogc => a.expand(b, blocksAtATime * bs))()
|
||||||
|
@ -1126,7 +1135,7 @@ nothrow @safe @nogc unittest
|
||||||
import std.typecons : Ternary;
|
import std.typecons : Ternary;
|
||||||
|
|
||||||
auto a = BitmappedBlock!(64, 8, GCAllocator)(1024 * 64);
|
auto a = BitmappedBlock!(64, 8, GCAllocator)(1024 * 64);
|
||||||
const void[] buff = a.allocate(42);
|
const void[] buff = (() pure nothrow @safe @nogc => a.allocate(42))();
|
||||||
|
|
||||||
assert((() nothrow @safe @nogc => a.owns(buff))() == Ternary.yes);
|
assert((() nothrow @safe @nogc => a.owns(buff))() == Ternary.yes);
|
||||||
assert((() nothrow @safe @nogc => a.owns(null))() == Ternary.no);
|
assert((() nothrow @safe @nogc => a.owns(null))() == Ternary.no);
|
||||||
|
@ -1216,13 +1225,13 @@ struct BitmappedBlockWithInternalPointers(
|
||||||
{
|
{
|
||||||
auto r = _heap.allocate(bytes);
|
auto r = _heap.allocate(bytes);
|
||||||
if (!r.ptr) return r;
|
if (!r.ptr) return r;
|
||||||
immutable block = (r.ptr - _heap._payload.ptr) / _heap.blockSize;
|
immutable block = (() @trusted => (r.ptr - _heap._payload.ptr) / _heap.blockSize)();
|
||||||
immutable blocks =
|
immutable blocks =
|
||||||
(r.length + _heap.blockSize - 1) / _heap.blockSize;
|
(r.length + _heap.blockSize - 1) / _heap.blockSize;
|
||||||
if (!ensureRoomForAllocStart(block + blocks))
|
if (!ensureRoomForAllocStart(block + blocks))
|
||||||
{
|
{
|
||||||
// Failed, free r and bailout
|
// Failed, free r and bailout
|
||||||
_heap.deallocate(r);
|
() @trusted { _heap.deallocate(r); r = null; }();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
assert(block < _allocStart.length);
|
assert(block < _allocStart.length);
|
||||||
|
@ -1360,7 +1369,7 @@ struct BitmappedBlockWithInternalPointers(
|
||||||
|
|
||||||
auto h = BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024]);
|
auto h = BitmappedBlockWithInternalPointers!(4096)(new ubyte[4096 * 1024]);
|
||||||
assert((() nothrow @safe @nogc => h.empty)() == Ternary.yes);
|
assert((() nothrow @safe @nogc => h.empty)() == Ternary.yes);
|
||||||
auto b = h.allocate(123);
|
auto b = (() pure nothrow @safe @nogc => h.allocate(123))();
|
||||||
assert(b.length == 123);
|
assert(b.length == 123);
|
||||||
assert((() nothrow @safe @nogc => h.empty)() == Ternary.no);
|
assert((() nothrow @safe @nogc => h.empty)() == Ternary.no);
|
||||||
|
|
||||||
|
@ -1369,7 +1378,7 @@ struct BitmappedBlockWithInternalPointers(
|
||||||
assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.yes);
|
assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.yes);
|
||||||
assert(p.ptr is b.ptr);
|
assert(p.ptr is b.ptr);
|
||||||
assert(p.length >= b.length);
|
assert(p.length >= b.length);
|
||||||
b = h.allocate(4096);
|
b = (() pure nothrow @safe @nogc => h.allocate(4096))();
|
||||||
|
|
||||||
offset = &b[0];
|
offset = &b[0];
|
||||||
assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.yes);
|
assert((() nothrow @safe @nogc => h.resolveInternalPointer(offset, p))() == Ternary.yes);
|
||||||
|
@ -1572,7 +1581,7 @@ private struct BitVector
|
||||||
/* Returns the index of the first 1 to the right of i (including i itself),
|
/* Returns the index of the first 1 to the right of i (including i itself),
|
||||||
or length if not found.
|
or length if not found.
|
||||||
*/
|
*/
|
||||||
nothrow @safe @nogc
|
pure nothrow @safe @nogc
|
||||||
ulong find1(ulong i)
|
ulong find1(ulong i)
|
||||||
{
|
{
|
||||||
assert(i < length);
|
assert(i < length);
|
||||||
|
@ -1600,7 +1609,7 @@ private struct BitVector
|
||||||
/* Returns the index of the first 1 to the left of i (including i itself),
|
/* Returns the index of the first 1 to the left of i (including i itself),
|
||||||
or ulong.max if not found.
|
or ulong.max if not found.
|
||||||
*/
|
*/
|
||||||
nothrow @safe @nogc
|
pure nothrow @safe @nogc
|
||||||
ulong find1Backward(ulong i)
|
ulong find1Backward(ulong i)
|
||||||
{
|
{
|
||||||
assert(i < length);
|
assert(i < length);
|
||||||
|
@ -1634,14 +1643,14 @@ private struct BitVector
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Are all bits one?
|
/// Are all bits one?
|
||||||
nothrow @safe @nogc
|
pure nothrow @safe @nogc
|
||||||
bool allAre1() const
|
bool allAre1() const
|
||||||
{
|
{
|
||||||
foreach (w; _rep) if (w != ulong.max) return false;
|
foreach (w; _rep) if (w != ulong.max) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nothrow @safe @nogc
|
pure nothrow @safe @nogc
|
||||||
ulong findZeros(immutable size_t howMany, ulong start)
|
ulong findZeros(immutable size_t howMany, ulong start)
|
||||||
{
|
{
|
||||||
assert(start < length);
|
assert(start < length);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue