Skip to content

Commit

Permalink
[flang][runtime] Allow 1023 active asynchronous IDs (#82446)
Browse files Browse the repository at this point in the history
The present limit of 63 is too low for some tests; bump it up to 1023 by
using an array of bit-sets.
  • Loading branch information
klausler committed Mar 1, 2024
1 parent 24aec16 commit c21ef15
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 11 deletions.
21 changes: 13 additions & 8 deletions flang/runtime/unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
10 changes: 7 additions & 3 deletions flang/runtime/unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

Expand Down Expand Up @@ -150,7 +154,7 @@ class ExternalFileUnit : public ConnectionState,
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.
Expand Down

0 comments on commit c21ef15

Please sign in to comment.