diff -r b28e7286990c -r 743456d6c6c3 src/arch/alpha/linux/linux.hh --- a/src/arch/alpha/linux/linux.hh Tue Jul 27 20:00:38 2010 -0700 +++ b/src/arch/alpha/linux/linux.hh Thu Jul 29 19:56:45 2010 +0100 @@ -141,6 +141,11 @@ uint64_t freehigh; /* Available high memory size */ uint64_t mem_unit; /* Memory unit size in bytes */ } tgt_sysinfo; + + struct tgt_timespec { + int64_t tv_sec; + int64_t tv_nsec; + }; }; #endif // __ALPHA_ALPHA_LINUX_LINUX_HH__ diff -r b28e7286990c -r 743456d6c6c3 src/arch/alpha/linux/process.cc --- a/src/arch/alpha/linux/process.cc Tue Jul 27 20:00:38 2010 -0700 +++ b/src/arch/alpha/linux/process.cc Thu Jul 29 19:56:45 2010 +0100 @@ -467,7 +467,7 @@ /* 337 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), /* 338 */ SyscallDesc("afs_syscall", unimplementedFunc), /* 339 */ SyscallDesc("uname", unameFunc), - /* 340 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 340 */ SyscallDesc("nanosleep", nanosleepFunc), /* 341 */ SyscallDesc("mremap", mremapFunc), /* 342 */ SyscallDesc("nfsservctl", unimplementedFunc), /* 343 */ SyscallDesc("setresuid", unimplementedFunc), diff -r b28e7286990c -r 743456d6c6c3 src/cpu/o3/cpu.cc --- a/src/cpu/o3/cpu.cc Tue Jul 27 20:00:38 2010 -0700 +++ b/src/cpu/o3/cpu.cc Thu Jul 29 19:56:45 2010 +0100 @@ -600,6 +600,19 @@ activeThreads.push_back(tid); } + + if (lastActivatedCycle < curTick) { + scheduleTickEvent(0); + + // Be sure to signal that there's some activity so the CPU doesn't + // deschedule itself. + activityRec.activity(); + fetch.wakeFromQuiesce(); + + lastActivatedCycle = curTick; + + _status = Running; + } } template @@ -644,19 +657,6 @@ } else { activateThread(tid); } - - if (lastActivatedCycle < curTick) { - scheduleTickEvent(delay); - - // Be sure to signal that there's some activity so the CPU doesn't - // deschedule itself. - activityRec.activity(); - fetch.wakeFromQuiesce(); - - lastActivatedCycle = curTick; - - _status = Running; - } } template @@ -685,9 +685,10 @@ bool deallocated = deallocateContext(tid, false, 1); // If this was the last thread then unschedule the tick event. if ((activeThreads.size() == 1 && !deallocated) || - activeThreads.size() == 0) + activeThreads.size() == 0) { unscheduleTickEvent(); - _status = Idle; + _status = Idle; + } } template @@ -697,6 +698,10 @@ //For now, this is the same as deallocate DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid); deallocateContext(tid, true, 1); + // deallocateContext will remove the thread from activeThreads + // on the next cycle + if(activeThreads.size() == 1 || activeThreads.size() == 0) + _status = Idle; } template diff -r b28e7286990c -r 743456d6c6c3 src/sim/syscall_emul.hh --- a/src/sim/syscall_emul.hh Tue Jul 27 20:00:38 2010 -0700 +++ b/src/sim/syscall_emul.hh Thu Jul 29 19:56:45 2010 +0100 @@ -1226,5 +1226,35 @@ return sec; } +template +SyscallReturn +nanosleepFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + int index = 0; + TypedBufferArg bufp(process->getSyscallArg(tc, + index)); + bufp.copyIn(tc->getMemPort()); + + int sleepCycles = tc->getCpuPtr()->tickToCycles( + bufp->tv_sec * SimClock::Int::s + + bufp->tv_nsec * SimClock::Int::ns); + if(sleepCycles < 0) { + sleepCycles = INT_MAX; + } + + index = 1; + TypedBufferArg bufr(process->getSyscallArg(tc, + index)); + bufr->tv_sec = 0; + bufr->tv_nsec = 0; + bufr.copyOut(tc->getMemPort()); + + tc->suspend(); + tc->activate(sleepCycles); + + return 0; +} + #endif // __SIM_SYSCALL_EMUL_HH__