示例#1
0
        internal unsafe int Read(Thread current, out timespec val)
        {
            timespec v;
            var      r = Read(current, &v, sizeof(timespec));

            val = v;
            return(r);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
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);
        }
示例#5
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);
        }
示例#6
0
        // 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);
        }
示例#7
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);
        }
示例#8
0
 internal unsafe int Write(Thread current, ref timespec res)
 {
     fixed (timespec* p = &res)
     {
         return Write(current, new Pointer(p), sizeof(timespec));
     }
 }
示例#9
0
 internal unsafe int Read(Thread current, out timespec val)
 {
     timespec v;
     var r = Read(current, &v, sizeof(timespec));
     val = v;
     return r;
 }
示例#10
0
        // 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;
        }
示例#11
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;
        }
示例#12
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;
        }
示例#13
0
        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;
        }
示例#14
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);
        }