Skip to content

Commit 95ecff4

Browse files
committed
Merge branch 'master' of github.com:dsm9000/sdc into slab_alloc_threadcache
2 parents 54c3968 + 45559e2 commit 95ecff4

File tree

5 files changed

+311
-121
lines changed

5 files changed

+311
-121
lines changed

sdlib/d/gc/arena.d

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,13 @@ public:
112112
/**
113113
* Small allocation facilities.
114114
*/
115-
void* allocSmall(shared(ExtentMap)* emap, size_t size) shared {
115+
uint allocSmall(shared(ExtentMap)* emap, size_t size,
116+
void*[] allocs) shared {
116117
// TODO: in contracts
117118
assert(isSmallSize(size));
118119

119120
auto sizeClass = getSizeClass(size);
120-
return bins[sizeClass].alloc(&this, emap, sizeClass);
121+
return bins[sizeClass].alloc(&this, emap, sizeClass, allocs);
121122
}
122123

123124
/**

sdlib/d/gc/bin.d

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ struct Bin {
2020
import d.gc.heap;
2121
Heap!(Extent, addrExtentCmp) slabs;
2222

23-
void* alloc(shared(Arena)* arena, shared(ExtentMap)* emap,
24-
ubyte sizeClass) shared {
23+
uint alloc(shared(Arena)* arena, shared(ExtentMap)* emap, ubyte sizeClass,
24+
void*[] allocs) shared {
2525
import d.gc.sizeclass;
2626
assert(sizeClass < ClassCount.Small);
2727
assert(&arena.bins[sizeClass] == &this, "Invalid arena or sizeClass!");
@@ -31,21 +31,27 @@ struct Bin {
3131
auto size = binInfos[sizeClass].itemSize;
3232

3333
Extent* slab;
34-
uint index;
34+
uint gotAllocs;
3535

3636
{
3737
mutex.lock();
3838
scope(exit) mutex.unlock();
3939

4040
slab = (cast(Bin*) &this).getSlab(arena, emap, sizeClass);
4141
if (slab is null) {
42-
return null;
42+
return 0;
4343
}
4444

45-
index = slab.allocate();
45+
// Get as many of the requested slots as we can from the current slab:
46+
import d.gc.util;
47+
gotAllocs = min(cast(uint) allocs.length, slab.freeSlots);
48+
foreach (i; 0 .. gotAllocs) {
49+
auto index = slab.allocate();
50+
allocs[i] = slab.address + index * size;
51+
}
4652
}
4753

48-
return slab.address + index * size;
54+
return gotAllocs;
4955
}
5056

5157
bool free(shared(Arena)* arena, void* ptr, PageDescriptor pd) shared {

sdlib/d/gc/dequeue.d

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
module d.gc.dequeue;
2+
3+
template DEQueue(T, uint Entries) {
4+
struct DEQueue {
5+
private:
6+
uint _front = 0;
7+
uint _back = 0;
8+
uint _count = 0;
9+
T[Entries] _buffer;
10+
11+
public:
12+
enum Size = Entries;
13+
14+
@property
15+
auto buffer() {
16+
assert(empty, "Buffer is not empty!");
17+
18+
return _buffer.ptr;
19+
}
20+
21+
void clear() {
22+
_front = 0;
23+
_back = 0;
24+
_count = 0;
25+
}
26+
27+
void pushBackAdvance(uint delta) {
28+
assert(empty, "Cannot pushBackAdvance: not empty!");
29+
assert(delta <= Entries,
30+
"Cannot pushBackAdvance: delta exceeds Entries!");
31+
32+
_front = 0;
33+
_back = delta % Entries;
34+
_count = delta;
35+
}
36+
37+
void pushBack(T item) {
38+
assert(!full, "Cannot pushBack: full!");
39+
40+
_buffer[_back] = item;
41+
_back = (_back + 1) % Entries;
42+
_count++;
43+
}
44+
45+
T popFront() {
46+
assert(!empty, "Cannot popFront: empty!");
47+
48+
auto item = _buffer[_front];
49+
_front = (_front + 1) % Entries;
50+
_count--;
51+
52+
return item;
53+
}
54+
55+
void pushFront(T item) {
56+
assert(!full, "Cannot pushFront: full!");
57+
58+
_front = (_front > 0 ? _front : Entries) - 1;
59+
_buffer[_front] = item;
60+
_count++;
61+
}
62+
63+
T popBack() {
64+
assert(!empty, "Cannot popBack: empty!");
65+
66+
_back = (_back > 0 ? _back : Entries) - 1;
67+
auto item = _buffer[_back];
68+
_count--;
69+
70+
return item;
71+
}
72+
73+
@property
74+
auto length() {
75+
return _count;
76+
}
77+
78+
@property
79+
bool empty() {
80+
return _count == 0;
81+
}
82+
83+
@property
84+
bool full() {
85+
return _count == Entries;
86+
}
87+
}
88+
}
89+
90+
unittest DEQueue {
91+
static DEQueue!(uint, 3) q;
92+
assert(q.empty);
93+
94+
q.pushBack(1);
95+
q.pushBack(2);
96+
q.pushBack(3);
97+
assert(q.full);
98+
assert(q.popFront() == 1);
99+
assert(q.popFront() == 2);
100+
assert(q.popFront() == 3);
101+
assert(q.empty);
102+
103+
q.pushBack(1);
104+
q.pushBack(2);
105+
q.pushBack(3);
106+
assert(q.full);
107+
assert(q.popBack() == 3);
108+
assert(q.popBack() == 2);
109+
assert(q.popBack() == 1);
110+
assert(q.empty);
111+
112+
q.pushFront(1);
113+
q.pushFront(2);
114+
q.pushFront(3);
115+
assert(q.full);
116+
assert(q.popFront() == 3);
117+
assert(q.popFront() == 2);
118+
assert(q.popFront() == 1);
119+
assert(q.empty);
120+
121+
q.pushFront(1);
122+
q.pushFront(2);
123+
q.pushFront(3);
124+
assert(q.full);
125+
assert(q.popBack() == 1);
126+
assert(q.popBack() == 2);
127+
assert(q.popBack() == 3);
128+
assert(q.empty);
129+
130+
q.pushBack(1);
131+
q.pushFront(2);
132+
q.pushBack(3);
133+
assert(q.full);
134+
assert(q.popFront() == 2);
135+
assert(q.popBack() == 3);
136+
assert(q.popFront() == 1);
137+
assert(q.empty);
138+
139+
q.pushBack(1);
140+
q.pushFront(2);
141+
q.pushBack(3);
142+
assert(q.full);
143+
assert(q.popBack() == 3);
144+
assert(q.popFront() == 2);
145+
assert(q.popBack() == 1);
146+
assert(q.empty);
147+
}

sdlib/d/gc/slab.d

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ public:
7676
return true;
7777
}
7878

79+
void clearMetadata() {
80+
setFreeSpace(0);
81+
}
82+
7983
@property
8084
Finalizer finalizer() {
8185
if (!finalizerEnabled) {

0 commit comments

Comments
 (0)