syscall_emul: add retry flag to SyscallReturn

This hook allows blocking emulated system calls to indicate
that they would block, but return control to the simulator
so that the simulation does not hang.  The actual retry
functionality requires additional support, to be provided
in a future changeset.
This commit is contained in:
Steve Reinhardt
2014-09-02 16:07:50 -05:00
parent 9ac7f14fc0
commit 6ab4eddb9f
2 changed files with 22 additions and 4 deletions

View File

@@ -71,10 +71,15 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n",
curTick(), tc->getCpuPtr()->name(), name, retval.encodedValue());
if (retval.needsRetry()) {
DPRINTFS(SyscallVerbose, tc->getCpuPtr(), "syscall %s needs retry\n",
name);
} else {
DPRINTFS(SyscallVerbose, tc->getCpuPtr(), "syscall %s returns %d\n",
name, retval.encodedValue());
}
if (!(flags & SyscallDesc::SuppressReturnValue))
if (!(flags & SyscallDesc::SuppressReturnValue) && !retval.needsRetry())
process->setSyscallReturn(tc, retval);
}

View File

@@ -64,9 +64,17 @@ class SyscallReturn
/// value is expected, e.g., as the return value from a system
/// call emulation function ('return 0;' or 'return -EFAULT;').
SyscallReturn(int64_t v)
: value(v)
: value(v), retryFlag(false)
{}
/// Pseudo-constructor to create an instance with the retry flag set.
static SyscallReturn retry()
{
SyscallReturn s(0);
s.retryFlag = true;
return s;
}
~SyscallReturn() {}
/// Was the system call successful?
@@ -75,6 +83,9 @@ class SyscallReturn
return (value >= 0 || value <= -4096);
}
/// Does the syscall need to be retried?
bool needsRetry() const { return retryFlag; }
/// The return value
int64_t returnValue() const
{
@@ -98,6 +109,8 @@ class SyscallReturn
private:
int64_t value;
bool retryFlag;
};
#endif