Skip to content

Commit 72f7b01

Browse files
committed
Remove the current field in bins.
1 parent 8fa7172 commit 72f7b01

File tree

1 file changed

+33
-42
lines changed

1 file changed

+33
-42
lines changed

sdlib/d/gc/bin.d

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@ struct Bin {
1212
import d.sync.mutex;
1313
shared Mutex mutex;
1414

15-
import d.gc.extent;
16-
Extent* current;
17-
1815
// XXX: We might want to consider targeting Extents
1916
// on old huge pages instead of just address.
20-
import d.gc.heap;
17+
import d.gc.extent, d.gc.heap;
2118
Heap!(Extent, addrExtentCmp) slabs;
2219

2320
void* alloc(shared(Arena)* arena, shared(ExtentMap)* emap,
@@ -28,22 +25,12 @@ struct Bin {
2825

2926
// Load eagerly as prefetching.
3027
import d.gc.slab;
31-
auto size = binInfos[sizeClass].itemSize;
28+
auto slotSize = binInfos[sizeClass].itemSize;
3229

3330
mutex.lock();
3431
scope(exit) mutex.unlock();
3532

36-
auto slab = (cast(Bin*) &this).getSlab(arena, emap, sizeClass);
37-
if (slab is null) {
38-
return null;
39-
}
40-
41-
void*[1] buffer = void;
42-
if (slab.batchAllocate(buffer[0 .. 1], size) == 0) {
43-
return null;
44-
}
45-
46-
return buffer[0];
33+
return (cast(Bin*) &this).allocImpl(arena, emap, sizeClass, slotSize);
4734
}
4835

4936
bool free(shared(Arena)* arena, void* ptr, PageDescriptor pd) shared {
@@ -54,18 +41,39 @@ struct Bin {
5441
"Invalid arena or sizeClass!");
5542

5643
import d.gc.slab;
44+
auto slots = binInfos[pd.sizeClass].slots;
5745
auto sg = SlabAllocGeometry(pd, ptr);
5846
assert(ptr is sg.address);
5947

60-
auto slots = binInfos[pd.sizeClass].slots;
61-
6248
mutex.lock();
6349
scope(exit) mutex.unlock();
6450

6551
return (cast(Bin*) &this).freeImpl(pd.extent, sg.index, slots);
6652
}
6753

6854
private:
55+
void* allocImpl(shared(Arena)* arena, shared(ExtentMap)* emap,
56+
ubyte sizeClass, size_t slotSize) {
57+
// FIXME: in contract.
58+
assert(mutex.isHeld(), "Mutex not held!");
59+
60+
auto e = getSlab(arena, emap, sizeClass);
61+
if (e is null) {
62+
return null;
63+
}
64+
65+
void*[1] buffer = void;
66+
auto count = e.batchAllocate(buffer[0 .. 1], slotSize);
67+
assert(count > 0);
68+
69+
// If the slab is full, remove it from the heap.
70+
if (e.freeSlots == 0) {
71+
slabs.remove(e);
72+
}
73+
74+
return buffer[0];
75+
}
76+
6977
bool freeImpl(Extent* e, uint index, uint slots) {
7078
// FIXME: in contract.
7179
assert(mutex.isHeld(), "Mutex not held!");
@@ -74,11 +82,6 @@ private:
7482

7583
auto nfree = e.freeSlots;
7684
if (nfree == slots) {
77-
if (e is current) {
78-
current = null;
79-
return true;
80-
}
81-
8285
// If we only had one slot, we never got added to the heap.
8386
if (slots > 1) {
8487
slabs.remove(e);
@@ -87,7 +90,7 @@ private:
8790
return true;
8891
}
8992

90-
if (nfree == 1 && e !is current) {
93+
if (nfree == 1) {
9194
// Newly non empty.
9295
assert(slots > 1);
9396
slabs.insert(e);
@@ -96,25 +99,12 @@ private:
9699
return false;
97100
}
98101

99-
auto tryGetSlab() {
100-
// FIXME: in contract.
101-
assert(mutex.isHeld(), "Mutex not held!");
102-
103-
// If the current slab still have free slots, go for it.
104-
if (current !is null && current.freeSlots != 0) {
105-
return current;
106-
}
107-
108-
current = slabs.pop();
109-
return current;
110-
}
111-
112102
auto getSlab(shared(Arena)* arena, shared(ExtentMap)* emap,
113103
ubyte sizeClass) {
114104
// FIXME: in contract.
115105
assert(mutex.isHeld(), "Mutex not held!");
116106

117-
auto slab = tryGetSlab();
107+
auto slab = slabs.top;
118108
if (slab !is null) {
119109
return slab;
120110
}
@@ -128,23 +118,24 @@ private:
128118
slab = arena.allocSlab(emap, sizeClass);
129119
}
130120

121+
auto current = slabs.top;
131122
if (slab is null) {
132123
// Another thread might have been successful
133124
// while we did not hold the lock.
134-
return tryGetSlab();
125+
return current;
135126
}
136127

137128
// We may have allocated the slab we need when the lock was released.
138-
if (current is null || current.freeSlots == 0) {
139-
current = slab;
129+
if (current is null) {
130+
slabs.insert(slab);
140131
return slab;
141132
}
142133

143134
// If we have, then free the run we just allocated.
144135
assert(slab !is current);
145136
assert(current.freeSlots > 0);
146137

147-
// In which case we put the free run back in the tree.
138+
// In which case we release the slab we just allocated.
148139
import d.gc.slab;
149140
assert(slab.freeSlots == binInfos[sizeClass].slots);
150141
arena.freeSlab(emap, slab);

0 commit comments

Comments
 (0)