[flang-commits] [PATCH] D139477: [flang] Restore old unit locking behavior
Peter Klausler via Phabricator via flang-commits
flang-commits at lists.llvm.org
Tue Dec 6 15:48:46 PST 2022
klausler created this revision.
klausler added reviewers: peixin, kiranchandramohan.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
Herald added a project: All.
klausler requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added a subscriber: sstefan1.
Rework the recursive I/O error check on I/O units so that
threads again hold a lock on a unit throughout an I/O statement.
Add an API to the runtime's Lock class implementation for pthreads
to allow detection of solf-deadlock without depending on EDEADLK
or recursive mutexes.
This should fix I/O from OpenMP threads.
https://reviews.llvm.org/D139477
Files:
flang/runtime/lock.h
flang/runtime/unit.cpp
flang/runtime/unit.h
Index: flang/runtime/unit.h
===================================================================
--- flang/runtime/unit.h
+++ flang/runtime/unit.h
@@ -71,17 +71,14 @@
template <typename A, typename... X>
IoStatementState &BeginIoStatement(const Terminator &terminator, X &&...xs) {
- bool alreadyBusy{false};
- {
- CriticalSection critical{lock_};
- alreadyBusy = isBusy_;
- isBusy_ = true; // cleared in EndIoStatement()
- }
- if (alreadyBusy) {
- terminator.Crash("Could not acquire exclusive lock on unit %d, perhaps "
- "due to an attempt to perform recursive I/O",
- unitNumber_);
+ // Take lock_ and hold it until EndIoStatement().
+#if USE_PTHREADS
+ if (!lock_.TakeIfNoDeadlock()) {
+ terminator.Crash("Recursive I/O attempted on unit %d", unitNumber_);
}
+#else
+ lock_.Take();
+#endif
A &state{u_.emplace<A>(std::forward<X>(xs)...)};
if constexpr (!std::is_same_v<A, OpenStatementState>) {
state.mutableModes() = ConnectionState::modes;
@@ -137,8 +134,6 @@
std::int32_t ReadHeaderOrFooter(std::int64_t frameOffset);
Lock lock_;
- // TODO: replace with a thread ID
- bool isBusy_{false}; // under lock_
int unitNumber_{-1};
Direction direction_{Direction::Output};
Index: flang/runtime/unit.cpp
===================================================================
--- flang/runtime/unit.cpp
+++ flang/runtime/unit.cpp
@@ -714,8 +714,7 @@
void ExternalFileUnit::EndIoStatement() {
io_.reset();
u_.emplace<std::monostate>();
- CriticalSection critical{lock_};
- isBusy_ = false;
+ lock_.Drop();
}
void ExternalFileUnit::BeginSequentialVariableUnformattedInputRecord(
Index: flang/runtime/lock.h
===================================================================
--- flang/runtime/lock.h
+++ flang/runtime/lock.h
@@ -41,9 +41,22 @@
void Take() {
while (pthread_mutex_lock(&mutex_)) {
}
+ holder_ = pthread_self();
+ }
+ bool TakeIfNoDeadlock() {
+ auto thisThread{pthread_self()};
+ if (pthread_equal(thisThread, holder_)) {
+ return false;
+ } else {
+ Take();
+ return true;
+ }
}
bool Try() { return pthread_mutex_trylock(&mutex_) == 0; }
- void Drop() { pthread_mutex_unlock(&mutex_); }
+ void Drop() {
+ holder_ = 0;
+ pthread_mutex_unlock(&mutex_);
+ }
#elif defined(_WIN32)
Lock() { InitializeCriticalSection(&cs_); }
~Lock() { DeleteCriticalSection(&cs_); }
@@ -66,6 +79,7 @@
private:
#if USE_PTHREADS
pthread_mutex_t mutex_{};
+ volatile pthread_t holder_{0};
#elif defined(_WIN32)
CRITICAL_SECTION cs_;
#else
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D139477.480658.patch
Type: text/x-patch
Size: 2641 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20221206/aadac77d/attachment.bin>
More information about the flang-commits
mailing list