Skip to content

Commit d4cf839

Browse files
committed
Make AffixAllocator take into account RCISharedAllocator
1 parent ec862ff commit d4cf839

File tree

1 file changed

+72
-25
lines changed

1 file changed

+72
-25
lines changed

std/experimental/allocator/building_blocks/affix_allocator.d

Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ Suffixes are slower to get at because of alignment rounding, so prefixes should
1818
be preferred. However, small prefixes blunt the alignment so if a large
1919
alignment with a small affix is needed, suffixes should be chosen.
2020
21-
The following methods are defined if $(D Allocator) defines them, and forward to it: $(D deallocateAll), $(D empty), $(D owns).
21+
The following methods are defined if $(D Allocator) defines them,
22+
and forwards to it: $(D deallocateAll), $(D empty), $(D owns).
2223
*/
2324
struct AffixAllocator(Allocator, Prefix, Suffix = void)
2425
{
2526
import std.algorithm.comparison : min;
2627
import std.conv : emplace;
27-
import std.experimental.allocator : RCIAllocator, theAllocator;
28+
import std.experimental.allocator : RCIAllocator, RCISharedAllocator,
29+
theAllocator, processAllocator;
2830
import std.experimental.allocator.common : stateSize, forwardToMember,
2931
roundUpToMultipleOf, alignedAt, alignDownTo, roundUpToMultipleOf,
3032
hasStaticallyKnownAlignment;
@@ -43,7 +45,8 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
4345
"This restriction could be relaxed in the future.");
4446

4547
/**
46-
If $(D Prefix) is $(D void), the alignment is that of the parent. Otherwise, the alignment is the same as the $(D Prefix)'s alignment.
48+
If $(D Prefix) is $(D void), the alignment is that of the parent.
49+
Otherwise, the alignment is the same as the $(D Prefix)'s alignment.
4750
*/
4851
static if (hasStaticallyKnownAlignment!Allocator)
4952
{
@@ -60,36 +63,39 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
6063
enum uint alignment = Prefix.alignof;
6164
}
6265

63-
/**
64-
If the parent allocator $(D Allocator) is stateful, an instance of it is
65-
stored as a member. Otherwise, $(D AffixAllocator) uses
66-
`Allocator.instance`. In either case, the name $(D _parent) is uniformly
67-
used for accessing the parent allocator.
68-
*/
69-
static if (stateSize!Allocator)
66+
private template Impl()
7067
{
71-
Allocator _parent;
72-
static if (is(Allocator == RCIAllocator))
68+
static if (stateSize!Allocator)
7369
{
74-
Allocator parent()
70+
Allocator _parent;
71+
static if (is(Allocator == RCIAllocator) || is(Allocator == RCISharedAllocator))
7572
{
76-
if (_parent.isNull) _parent = theAllocator;
77-
assert(alignment <= _parent.alignment);
78-
return _parent;
73+
Allocator parent()
74+
{
75+
if (_parent.isNull)
76+
{
77+
static if (is(Allocator == RCIAllocator))
78+
{
79+
_parent = theAllocator;
80+
}
81+
else
82+
{
83+
_parent = processAllocator;
84+
}
85+
}
86+
assert(alignment <= _parent.alignment);
87+
return _parent;
88+
}
89+
}
90+
else
91+
{
92+
alias parent = _parent;
7993
}
8094
}
8195
else
8296
{
83-
alias parent = _parent;
97+
alias parent = Allocator.instance;
8498
}
85-
}
86-
else
87-
{
88-
alias parent = Allocator.instance;
89-
}
90-
91-
private template Impl()
92-
{
9399

94100
size_t goodAllocSize(size_t s)
95101
{
@@ -298,6 +304,20 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
298304
*/
299305
static AffixAllocator instance;
300306

307+
/**
308+
If the parent allocator `Allocator` is stateful, an instance of it is
309+
stored as a member. If the parent allocator is null instance of
310+
$(REF RCIAllocator, std,experimental,allocator) or
311+
$(REF RCISharedAllocator, std,experimental,allocator) then `AffixAllocator`
312+
will use $(REF theAllocator, std,experimental,allocator) or
313+
$(REF processAllocator, std,experimental,allocator) respectively.
314+
If the parent allocator `Allocator` is stateless, `AffixAllocator` uses
315+
`Allocator.instance`.
316+
In either case, the name `_parent` is uniformly used for accessing the
317+
parent allocator.
318+
*/
319+
Allocator parent();
320+
301321
/**
302322
Affix access functions offering references to the affixes of a
303323
block `b` previously allocated with this allocator. `b` may not be null.
@@ -520,3 +540,30 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
520540
static assert(is(typeof(a.allocate) == shared));
521541
assert(buf.length == 10);
522542
}
543+
544+
@system unittest
545+
{
546+
import std.experimental.allocator : RCISharedAllocator;
547+
548+
shared AffixAllocator!(RCISharedAllocator, uint) a;
549+
auto buf = a.allocate(42);
550+
assert(buf.length == 42);
551+
}
552+
553+
@system unittest
554+
{
555+
import std.experimental.allocator.mallocator : Mallocator;
556+
import std.experimental.allocator.building_blocks.stats_collector;
557+
558+
alias SCAlloc = StatsCollector!(Mallocator, Options.bytesUsed);
559+
alias AffixAl = AffixAllocator!(SCAlloc, uint);
560+
561+
AffixAl a;
562+
auto b = a.allocate(42);
563+
assert(b.length == 42);
564+
assert(a.parent.bytesUsed == 42 + uint.sizeof);
565+
assert((() nothrow @nogc => a.reallocate(b, 100))());
566+
assert(b.length == 100);
567+
assert(a.parent.bytesUsed == 100 + uint.sizeof);
568+
assert((() nothrow @nogc => a.deallocate(b))());
569+
}

0 commit comments

Comments
 (0)