Skip to content

Commit c21ef15

Browse files
authored
[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.
1 parent 24aec16 commit c21ef15

File tree

2 files changed

+20
-11
lines changed

2 files changed

+20
-11
lines changed

flang/runtime/unit.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,25 +1001,30 @@ int ExternalFileUnit::GetAsynchronousId(IoErrorHandler &handler) {
10011001
if (!mayAsynchronous()) {
10021002
handler.SignalError(IostatBadAsynchronous);
10031003
return -1;
1004-
} else if (auto least{asyncIdAvailable_.LeastElement()}) {
1005-
asyncIdAvailable_.reset(*least);
1006-
return static_cast<int>(*least);
10071004
} else {
1005+
for (int j{0}; 64 * j < maxAsyncIds; ++j) {
1006+
if (auto least{asyncIdAvailable_[j].LeastElement()}) {
1007+
asyncIdAvailable_[j].reset(*least);
1008+
return 64 * j + static_cast<int>(*least);
1009+
}
1010+
}
10081011
handler.SignalError(IostatTooManyAsyncOps);
10091012
return -1;
10101013
}
10111014
}
10121015

10131016
bool ExternalFileUnit::Wait(int id) {
1014-
if (static_cast<std::size_t>(id) >= asyncIdAvailable_.size() ||
1015-
asyncIdAvailable_.test(id)) {
1017+
if (static_cast<std::size_t>(id) >= maxAsyncIds ||
1018+
asyncIdAvailable_[id / 64].test(id % 64)) {
10161019
return false;
10171020
} else {
10181021
if (id == 0) { // means "all IDs"
1019-
asyncIdAvailable_.set();
1020-
asyncIdAvailable_.reset(0);
1022+
for (int j{0}; 64 * j < maxAsyncIds; ++j) {
1023+
asyncIdAvailable_[j].set();
1024+
}
1025+
asyncIdAvailable_[0].reset(0);
10211026
} else {
1022-
asyncIdAvailable_.set(id);
1027+
asyncIdAvailable_[id / 64].set(id % 64);
10231028
}
10241029
return true;
10251030
}

flang/runtime/unit.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,14 @@ class ExternalFileUnit : public ConnectionState,
3636
public OpenFile,
3737
public FileFrame<ExternalFileUnit> {
3838
public:
39+
static constexpr int maxAsyncIds{64 * 16};
40+
3941
explicit ExternalFileUnit(int unitNumber) : unitNumber_{unitNumber} {
4042
isUTF8 = executionEnvironment.defaultUTF8;
41-
asyncIdAvailable_.set();
42-
asyncIdAvailable_.reset(0);
43+
for (int j{0}; 64 * j < maxAsyncIds; ++j) {
44+
asyncIdAvailable_[j].set();
45+
}
46+
asyncIdAvailable_[0].reset(0);
4347
}
4448
~ExternalFileUnit() {}
4549

@@ -150,7 +154,7 @@ class ExternalFileUnit : public ConnectionState,
150154
std::size_t recordOffsetInFrame_{0}; // of currentRecordNumber
151155
bool swapEndianness_{false};
152156
bool createdForInternalChildIo_{false};
153-
common::BitSet<64> asyncIdAvailable_;
157+
common::BitSet<64> asyncIdAvailable_[maxAsyncIds / 64];
154158

155159
// When a synchronous I/O statement is in progress on this unit, holds its
156160
// state.

0 commit comments

Comments
 (0)