internal unsafe int Read(Thread current, out timespec val) { timespec v; var r = Read(current, &v, sizeof(timespec)); val = v; return(r); }
private static timespec GetTime(timespec start) { var now = Arch.NativeMethods.l4api_get_system_clock(); var diff = now - Epoch; start.tv_sec += (uint)diff / 1000000; start.tv_nsec += (uint)((diff % 1000000) * 1000); return(start); }
public static int Gettimeofday(Thread current, UserPtr timeval) { timespec res = GetTime(UptimeTimeSpec); timeval r; r.tv_sec = res.tv_sec; r.tv_usec = res.tv_nsec / 1000; if (timeval.Write(current, ref r) != 0) { return(-ErrorCode.EFAULT); } return(0); }
public static void Initialize() { UTSNameInfo = new byte[UTSStructLength]; AssignUTSName(UTSSysnameOffset, "Linux"); AssignUTSName(UTSNodenameOffset, "(none)"); AssignUTSName(UTSReleaseOffset, "3.0.0-l4-g8732b51-dirty"); AssignUTSName(UTSVersionOffset, "#11 Thu Apr 5 23:45:03 CDT 2012"); AssignUTSName(UTSMachineOffset, "i686"); AssignUTSName(UTSDomainNameOffset, "(none)"); Epoch = Arch.NativeMethods.l4api_get_system_clock(); Arch.IPCStubs.linux_sys_clock_gettime(CLOCK_REALTIME); UptimeTimeSpec = GetTimeSpec(Globals.LinuxIPCBuffer); Arch.IPCStubs.linux_sys_clock_gettime(CLOCK_MONOTONIC); MonotonicTimeSpec = GetTimeSpec(Globals.LinuxIPCBuffer); }
private static timespec GetTimeSpec(ByteBufferRef buf) { Contract.Requires(buf.Length >= timespec.Size); var r = new timespec(); r.tv_sec = 0; r.tv_nsec = 0; for (var i = 0; i < sizeof(uint); ++i) { Contract.Assume(buf.Length >= timespec.Size); Contract.Assert(i < buf.Length); r.tv_sec += (uint)buf.Get(i) << (8 * i); } for (var i = 0; i < sizeof(uint); ++i) { Contract.Assume(buf.Length >= timespec.Size); Contract.Assert(i + sizeof(uint) < buf.Length); r.tv_nsec += (uint)buf.Get(i + sizeof(uint)) << (8 * i); } return(r); }
// Forward the futex request to Linux helper private static int DoFutexShared(Thread current, ref Arch.ExceptionRegisters regs, UserPtr uaddr, int op, int val, UserPtr timeoutPtr, UserPtr uaddr2, uint val3) { // Some local test var cmd = op & FUTEX_CMD_MASK; timespec ts = new timespec(); bool hasTimeout = timeoutPtr != UserPtr.Zero; if (hasTimeout && timeoutPtr.Read(current, out ts) != 0) { return(-ErrorCode.EFAULT); } if (cmd == FUTEX_WAIT || cmd == FUTEX_WAIT_BITSET) { int old_val; if (uaddr.Read(current, out old_val) != 0) { return(-ErrorCode.EFAULT); } if (old_val != val) { return(-ErrorCode.EWOULDBLOCK); } var bitset = cmd == FUTEX_WAIT ? FUTEX_BITSET_MATCH_ANY : val3; var shadowAddr = FindShadowAddr(current, uaddr); if (shadowAddr == Pointer.Zero) { Arch.Console.WriteLine("FutexShared: Don't know how to deal with shared_wait"); return(0); } var futex_entry = new FutexCompletionEntry(current, uaddr, bitset); Arch.IPCStubs.linux_sys_futex_wait(current.Parent.helperPid, current.impl._value.thread._value, op, shadowAddr, val, ts, bitset); Globals.CompletionQueue.Enqueue(futex_entry); current.SaveState(ref regs); current.AsyncReturn = true; return(0); } else if (cmd == FUTEX_WAKE || cmd == FUTEX_WAKE_BITSET) { var bitset = cmd == FUTEX_WAKE ? FUTEX_BITSET_MATCH_ANY : val3; if (bitset == 0) { return(-ErrorCode.EINVAL); } var shadowAddr = FindShadowAddr(current, uaddr); if (shadowAddr == Pointer.Zero) { Arch.Console.WriteLine("FutexShared: Don't know how to deal with shared_wake"); return(0); } var c = new BridgeCompletion(current, new ByteBufferRef()); Arch.IPCStubs.linux_sys_futex_wake(current.Parent.helperPid, current.impl._value.thread._value, op, shadowAddr, bitset); Globals.CompletionQueue.Enqueue(c); current.SaveState(ref regs); current.AsyncReturn = true; return(0); } return(0); }
private static int Wait(Thread current, ref Arch.ExceptionRegisters regs, UserPtr uaddr, int flags, int val, bool hasTimeout, timespec ts, uint bitset) { int old_val; if (uaddr.Read(current, out old_val) != 0) { return(-ErrorCode.EFAULT); } if (old_val != val) { return(-ErrorCode.EWOULDBLOCK); } //Arch.Console.Write("wait: addr="); //Arch.Console.Write(uaddr.Value.ToUInt32()); //Arch.Console.Write(" thr="); //Arch.Console.Write(current.Tid); //Arch.Console.WriteLine(); TimerQueueNode node; var futex_entry = new FutexCompletionEntry(current, uaddr, bitset); Globals.FutexLists.InsertAtTail(futex_entry); if (hasTimeout) { node = Globals.TimeoutQueue.Enqueue(ts.ToMilliseconds(), current); futex_entry.timeoutNode = node; } Globals.CompletionQueue.Enqueue(futex_entry); current.SaveState(ref regs); current.AsyncReturn = true; return(0); }
internal unsafe int Write(Thread current, ref timespec res) { fixed (timespec* p = &res) { return Write(current, new Pointer(p), sizeof(timespec)); } }
internal unsafe int Read(Thread current, out timespec val) { timespec v; var r = Read(current, &v, sizeof(timespec)); val = v; return r; }
// Forward the futex request to Linux helper private static int DoFutexShared(Thread current, ref Arch.ExceptionRegisters regs, UserPtr uaddr, int op, int val, UserPtr timeoutPtr, UserPtr uaddr2, uint val3) { // Some local test var cmd = op & FUTEX_CMD_MASK; timespec ts = new timespec(); bool hasTimeout = timeoutPtr != UserPtr.Zero; if (hasTimeout && timeoutPtr.Read(current, out ts) != 0) return -ErrorCode.EFAULT; if (cmd == FUTEX_WAIT || cmd == FUTEX_WAIT_BITSET) { int old_val; if (uaddr.Read(current, out old_val) != 0) return -ErrorCode.EFAULT; if (old_val != val) return -ErrorCode.EWOULDBLOCK; var bitset = cmd == FUTEX_WAIT ? FUTEX_BITSET_MATCH_ANY : val3; var shadowAddr = FindShadowAddr(current, uaddr); if (shadowAddr == Pointer.Zero) { Arch.Console.WriteLine("FutexShared: Don't know how to deal with shared_wait"); return 0; } var futex_entry = new FutexCompletionEntry(current, uaddr, bitset); Arch.IPCStubs.linux_sys_futex_wait(current.Parent.helperPid, current.impl._value.thread._value, op, shadowAddr, val, ts, bitset); Globals.CompletionQueue.Enqueue(futex_entry); current.SaveState(ref regs); current.AsyncReturn = true; return 0; } else if (cmd == FUTEX_WAKE || cmd == FUTEX_WAKE_BITSET) { var bitset = cmd == FUTEX_WAKE ? FUTEX_BITSET_MATCH_ANY : val3; if (bitset == 0) return -ErrorCode.EINVAL; var shadowAddr = FindShadowAddr(current, uaddr); if (shadowAddr == Pointer.Zero) { Arch.Console.WriteLine("FutexShared: Don't know how to deal with shared_wake"); return 0; } var c = new BridgeCompletion(current, new ByteBufferRef()); Arch.IPCStubs.linux_sys_futex_wake(current.Parent.helperPid, current.impl._value.thread._value, op, shadowAddr, bitset); Globals.CompletionQueue.Enqueue(c); current.SaveState(ref regs); current.AsyncReturn = true; return 0; } return 0; }
private static int Wait(Thread current, ref Arch.ExceptionRegisters regs, UserPtr uaddr, int flags, int val, bool hasTimeout, timespec ts, uint bitset) { int old_val; if (uaddr.Read(current, out old_val) != 0) return -ErrorCode.EFAULT; if (old_val != val) return -ErrorCode.EWOULDBLOCK; //Arch.Console.Write("wait: addr="); //Arch.Console.Write(uaddr.Value.ToUInt32()); //Arch.Console.Write(" thr="); //Arch.Console.Write(current.Tid); //Arch.Console.WriteLine(); TimerQueueNode node; var futex_entry = new FutexCompletionEntry(current, uaddr, bitset); Globals.FutexLists.InsertAtTail(futex_entry); if (hasTimeout) { node = Globals.TimeoutQueue.Enqueue(ts.ToMilliseconds(), current); futex_entry.timeoutNode = node; } Globals.CompletionQueue.Enqueue(futex_entry); current.SaveState(ref regs); current.AsyncReturn = true; return 0; }
private static timespec GetTimeSpec(ByteBufferRef buf) { Contract.Requires(buf.Length >= timespec.Size); var r = new timespec(); r.tv_sec = 0; r.tv_nsec = 0; for (var i = 0; i < sizeof(uint); ++i) { Contract.Assume(buf.Length >= timespec.Size); Contract.Assert(i < buf.Length); r.tv_sec += (uint)buf.Get(i) << (8 * i); } for (var i = 0; i < sizeof(uint); ++i) { Contract.Assume(buf.Length >= timespec.Size); Contract.Assert(i + sizeof(uint) < buf.Length); r.tv_nsec += (uint)buf.Get(i + sizeof(uint)) << (8 * i); } return r; }
private static timespec GetTime(timespec start) { var now = Arch.NativeMethods.l4api_get_system_clock(); var diff = now - Epoch; start.tv_sec += (uint)diff / 1000000; start.tv_nsec += (uint)((diff % 1000000) * 1000); return start; }