Skip to content

Commit bddb8f1

Browse files
authored
SWDEV-345024 - Retain the program on Fini kernel execution (#307)
Fini kernel is executed during the invocation of amd::Program destructor, but the dispatch logic can retain/release the reference counter and cause double free. Avoid double free with an extra retain() call
1 parent 0457b63 commit bddb8f1

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

rocclr/platform/runtime.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,20 @@ void RuntimeTearDown::RegisterObject(ReferenceCountedObject* obj) {
127127
class RuntimeTearDown runtime_tear_down;
128128

129129
uint ReferenceCountedObject::retain() {
130-
return referenceCount_.fetch_add(1, std::memory_order_relaxed) + 1;
130+
uint prev = referenceCount_.fetch_add(1, std::memory_order_relaxed);
131+
assert(prev != 0 && "An object with count==0 is invalid");
132+
return prev + 1;
131133
}
132134

133135
uint ReferenceCountedObject::release() {
134136
uint newCount = referenceCount_.fetch_sub(1, std::memory_order_relaxed) - 1;
135137
if (newCount == 0) {
136138
if (terminate()) {
139+
// The destructor should be called with a count==1 for the last thread
140+
// releasing the reference. Since an atomic load before the decrement
141+
// would add more atomic operations, simply bump the count to 1 here
142+
// before destructing the object.
143+
referenceCount_.store(1, std::memory_order_relaxed);
137144
delete this;
138145
}
139146
}

0 commit comments

Comments
 (0)