diff options
author | Peter Klausler <35819229+klausler@users.noreply.github.com> | 2024-03-01 14:28:39 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-01 14:28:39 -0800 |
commit | c21ef15ec651b5570a44a63e01ee4afdbabc3623 (patch) | |
tree | 5598098e07e13c0ed145d575d0d7b59204af89e5 | |
parent | 24aec16ddad465cc1c2fce528bb3eca49ac9fcdb (diff) |
[flang][runtime] Allow 1023 active asynchronous IDs (#82446)
The present limit of 63 is too low for some tests; bump it up to 1023 by
using an array of bit-sets.
-rw-r--r-- | flang/runtime/unit.cpp | 21 | ||||
-rw-r--r-- | flang/runtime/unit.h | 10 |
2 files changed, 20 insertions, 11 deletions
diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp index 58ca313d9e44..09782d2f8492 100644 --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -1001,25 +1001,30 @@ int ExternalFileUnit::GetAsynchronousId(IoErrorHandler &handler) { if (!mayAsynchronous()) { handler.SignalError(IostatBadAsynchronous); return -1; - } else if (auto least{asyncIdAvailable_.LeastElement()}) { - asyncIdAvailable_.reset(*least); - return static_cast<int>(*least); } else { + for (int j{0}; 64 * j < maxAsyncIds; ++j) { + if (auto least{asyncIdAvailable_[j].LeastElement()}) { + asyncIdAvailable_[j].reset(*least); + return 64 * j + static_cast<int>(*least); + } + } handler.SignalError(IostatTooManyAsyncOps); return -1; } } bool ExternalFileUnit::Wait(int id) { - if (static_cast<std::size_t>(id) >= asyncIdAvailable_.size() || - asyncIdAvailable_.test(id)) { + if (static_cast<std::size_t>(id) >= maxAsyncIds || + asyncIdAvailable_[id / 64].test(id % 64)) { return false; } else { if (id == 0) { // means "all IDs" - asyncIdAvailable_.set(); - asyncIdAvailable_.reset(0); + for (int j{0}; 64 * j < maxAsyncIds; ++j) { + asyncIdAvailable_[j].set(); + } + asyncIdAvailable_[0].reset(0); } else { - asyncIdAvailable_.set(id); + asyncIdAvailable_[id / 64].set(id % 64); } return true; } diff --git a/flang/runtime/unit.h b/flang/runtime/unit.h index 140fda3c4d2a..e3c8757645bb 100644 --- a/flang/runtime/unit.h +++ b/flang/runtime/unit.h @@ -36,10 +36,14 @@ class ExternalFileUnit : public ConnectionState, public OpenFile, public FileFrame<ExternalFileUnit> { public: + static constexpr int maxAsyncIds{64 * 16}; + explicit ExternalFileUnit(int unitNumber) : unitNumber_{unitNumber} { isUTF8 = executionEnvironment.defaultUTF8; - asyncIdAvailable_.set(); - asyncIdAvailable_.reset(0); + for (int j{0}; 64 * j < maxAsyncIds; ++j) { + asyncIdAvailable_[j].set(); + } + asyncIdAvailable_[0].reset(0); } ~ExternalFileUnit() {} @@ -150,7 +154,7 @@ private: std::size_t recordOffsetInFrame_{0}; // of currentRecordNumber bool swapEndianness_{false}; bool createdForInternalChildIo_{false}; - common::BitSet<64> asyncIdAvailable_; + common::BitSet<64> asyncIdAvailable_[maxAsyncIds / 64]; // When a synchronous I/O statement is in progress on this unit, holds its // state. |