Commit f22fe2a0 authored by Martin Karsten's avatar Martin Karsten

- further streamline I/O blocking

parent 55ea14e9
...@@ -43,7 +43,7 @@ class EventScope { ...@@ -43,7 +43,7 @@ class EventScope {
SyncSem RD; SyncSem RD;
SyncSem WR; SyncSem WR;
#if TESTING_LAZY_FD_REGISTRATION #if TESTING_LAZY_FD_REGISTRATION
FibreMutex regLock; FibreMutex lock;
size_t status; size_t status;
SyncFD() : status(0) {} SyncFD() : status(0) {}
#endif #endif
...@@ -142,7 +142,7 @@ public: ...@@ -142,7 +142,7 @@ public:
RASSERT0(fd >= 0 && fd < fdCount); RASSERT0(fd >= 0 && fd < fdCount);
SyncFD& fdsync = fdSyncVector[fd]; SyncFD& fdsync = fdSyncVector[fd];
if ((fdsync.status & target) == target) return; // outside of lock: faster, but double regs possible... if ((fdsync.status & target) == target) return; // outside of lock: faster, but double regs possible...
ScopedLock<FibreMutex> sl(fdsync.regLock); ScopedLock<FibreMutex> sl(fdsync.lock);
bool change = fdsync.status; // already registered for polling? bool change = fdsync.status; // already registered for polling?
fdsync.status |= target; fdsync.status |= target;
#endif #endif
...@@ -167,7 +167,7 @@ public: ...@@ -167,7 +167,7 @@ public:
RASSERT0(fdsync.RD.empty()); RASSERT0(fdsync.RD.empty());
RASSERT0(fdsync.WR.empty()); RASSERT0(fdsync.WR.empty());
#if TESTING_LAZY_FD_REGISTRATION #if TESTING_LAZY_FD_REGISTRATION
ScopedLock<FibreMutex> sl(fdsync.regLock); ScopedLock<FibreMutex> sl(fdsync.lock);
fdsync.status = 0; fdsync.status = 0;
#endif #endif
if (RemoveFromPollSet) { // only called from lfConnect if (RemoveFromPollSet) { // only called from lfConnect
...@@ -259,14 +259,14 @@ public: ...@@ -259,14 +259,14 @@ public:
#if TESTING_LAZY_FD_REGISTRATION #if TESTING_LAZY_FD_REGISTRATION
registerFD<Input,!Input,false,false>(fd); registerFD<Input,!Input,false,false>(fd);
#endif #endif
Fibre::yield();
SyncSem& sem = Input ? fdSyncVector[fd].RD : fdSyncVector[fd].WR; SyncSem& sem = Input ? fdSyncVector[fd].RD : fdSyncVector[fd].WR;
sem.P_yield();
for (;;) { for (;;) {
sem.P();
ret = iofunc(fd, a...); ret = iofunc(fd, a...);
if (ret >= 0 || !TestEAGAIN<Input>()) break; if (ret >= 0) { sem.V(); break; }
if (!TestEAGAIN<Input>()) break;
sem.P();
} }
sem.V();
return ret; return ret;
} }
}; };
......
...@@ -224,7 +224,7 @@ public: ...@@ -224,7 +224,7 @@ public:
while (!empty()) Pause(); // wait for timed out events to disappear while (!empty()) Pause(); // wait for timed out events to disappear
} }
template<typename Lock> template<typename Lock>
bool block(Lock& lock, bool wait) { bool block(Lock& lock, bool wait = true) {
if (wait) { if (wait) {
BlockingInfo<Lock> bi(lock); BlockingInfo<Lock> bi(lock);
DBG::outl(DBG::Level::Blocking, "Stack ", FmtHex(Context::CurrStack()), " blocking on ", FmtHex(&queue)); DBG::outl(DBG::Level::Blocking, "Stack ", FmtHex(Context::CurrStack()), " blocking on ", FmtHex(&queue));
...@@ -250,9 +250,6 @@ public: ...@@ -250,9 +250,6 @@ public:
return false; return false;
} }
template<typename Lock>
bool block(Lock& lock) { return block(lock, true); }
template<bool Enqueue = true> template<bool Enqueue = true>
StackContext* unblock() { // not concurrency-safe; better hold lock StackContext* unblock() { // not concurrency-safe; better hold lock
for (StackContext* s = queue.front(); s != queue.edge(); s = BlockedStackList::next(*s)) { for (StackContext* s = queue.front(); s != queue.edge(); s = BlockedStackList::next(*s)) {
...@@ -276,12 +273,13 @@ protected: ...@@ -276,12 +273,13 @@ protected:
ssize_t counter; ssize_t counter;
BQ bq; BQ bq;
template<typename... Args> template<bool Yield = false, typename... Args>
bool internalP(const Args&... args) { bool internalP(const Args&... args) {
// need baton passing: counter unchanged, if blocking fails (timeout) // need baton passing: counter unchanged, if blocking fails (timeout)
if (counter < 1) return bq.block(lock, args...); if (counter < 1) return bq.block(lock, args...);
counter -= 1; counter -= 1;
lock.release(); lock.release();
if (Yield) StackContext::yield();
return true; return true;
} }
...@@ -307,7 +305,12 @@ public: ...@@ -307,7 +305,12 @@ public:
bool P_unlock(Lock2& l) { bool P_unlock(Lock2& l) {
lock.acquire(); lock.acquire();
l.release(); l.release();
return internalP(true); return internalP();
}
bool P_yield() {
lock.acquire();
return internalP<true>();
} }
void P_fake(size_t c = 1) { void P_fake(size_t c = 1) {
...@@ -561,7 +564,7 @@ public: ...@@ -561,7 +564,7 @@ public:
lock.release(); lock.release();
return true; return true;
} else { } else {
bq.block(lock, true); bq.block(lock);
return false; return false;
} }
} }
...@@ -574,7 +577,7 @@ class Condition { ...@@ -574,7 +577,7 @@ class Condition {
public: public:
bool empty() { return bq.empty(); } bool empty() { return bq.empty(); }
void reset(Lock& lock) { bq.reset(lock); } void reset(Lock& lock) { bq.reset(lock); }
bool wait(Lock& lock) { return bq.block(lock, true); } bool wait(Lock& lock) { return bq.block(lock); }
bool wait(Lock& lock, const Time& timeout) { return bq.block(lock, timeout); } bool wait(Lock& lock, const Time& timeout) { return bq.block(lock, timeout); }
template<bool Broadcast = false> template<bool Broadcast = false>
void signal() { while (bq.unblock() && Broadcast); } void signal() { while (bq.unblock() && Broadcast); }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment