Skip to content

Commit 2525710

Browse files
committed
Make the exclusivity-set tracking a singly-linked list.
We'll use this space for something else in a follow-up.
1 parent f9861fe commit 2525710

File tree

1 file changed

+31
-22
lines changed

1 file changed

+31
-22
lines changed

stdlib/public/runtime/Exclusivity.cpp

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,31 +58,29 @@ namespace {
5858
/// A single access that we're tracking.
5959
struct Access {
6060
void *Pointer;
61-
uintptr_t HereAndAction;
62-
Access *Next;
61+
uintptr_t NextAndAction;
6362

6463
enum : uintptr_t {
6564
ActionMask = (uintptr_t)ExclusivityFlags::ActionMask,
66-
HereMask = ~ActionMask
65+
NextMask = ~ActionMask
6766
};
6867

69-
Access **getHere() const {
70-
return reinterpret_cast<Access**>(HereAndAction & HereMask);
68+
Access *getNext() const {
69+
return reinterpret_cast<Access*>(NextAndAction & NextMask);
7170
}
7271

73-
void setHere(Access **newHere) {
74-
HereAndAction = reinterpret_cast<uintptr_t>(newHere) | uintptr_t(getAccessAction());
72+
void setNext(Access *next) {
73+
NextAndAction =
74+
reinterpret_cast<uintptr_t>(next) | (NextAndAction & NextMask);
7575
}
7676

7777
ExclusivityFlags getAccessAction() const {
78-
return ExclusivityFlags(HereAndAction & ActionMask);
78+
return ExclusivityFlags(NextAndAction & ActionMask);
7979
}
8080

81-
void initialize(void *pointer, Access **here, ExclusivityFlags action) {
82-
assert(*here == nullptr && "not inserting to end of list");
81+
void initialize(void *pointer, Access *next, ExclusivityFlags action) {
8382
Pointer = pointer;
84-
HereAndAction = reinterpret_cast<uintptr_t>(here) | uintptr_t(action);
85-
Next = nullptr;
83+
NextAndAction = reinterpret_cast<uintptr_t>(next) | uintptr_t(action);
8684
}
8785
};
8886

@@ -99,8 +97,7 @@ class AccessSet {
9997
void insert(Access *access, void *pointer, ExclusivityFlags flags) {
10098
auto action = getAccessAction(flags);
10199

102-
Access **curP = &Head;
103-
for (Access *cur = *curP; cur != nullptr; curP = &cur->Next, cur = *curP) {
100+
for (Access *cur = Head; cur != nullptr; cur = cur->getNext()) {
104101
// Ignore accesses to different values.
105102
if (cur->Pointer != pointer)
106103
continue;
@@ -118,15 +115,27 @@ class AccessSet {
118115
pointer);
119116
}
120117

121-
access->initialize(pointer, curP, action);
122-
*curP = access;
118+
// Insert to the front of the array so that remove tends to find it faster.
119+
access->initialize(pointer, Head, action);
120+
Head = access;
123121
}
124122

125-
static void remove(Access *access) {
126-
Access **here = access->getHere();
127-
*here = access->Next;
128-
if (access->Next != nullptr)
129-
access->Next->setHere(here);
123+
void remove(Access *access) {
124+
auto cur = Head;
125+
// Fast path: stack discipline.
126+
if (cur == access) {
127+
Head = cur->getNext();
128+
return;
129+
}
130+
131+
for (Access *last = cur; cur != nullptr; last = cur, cur = cur->getNext()) {
132+
if (last == access) {
133+
last->setNext(cur->getNext());
134+
return;
135+
}
136+
}
137+
138+
swift_runtime_unreachable("access not found in set");
130139
}
131140
};
132141

@@ -231,5 +240,5 @@ void swift::swift_endAccess(ValueBuffer *buffer) {
231240
return;
232241
}
233242

234-
AccessSet::remove(access);
243+
getAccessSet(pointer).remove(access);
235244
}

0 commit comments

Comments
 (0)