Beispiel #1
0
        public static void HandleFutexAsync(FutexCompletionEntry c, int ret)
        {
            var current = c.thr;

            c.Unlink();
            current.ReturnFromCompletion(ret);
        }
Beispiel #2
0
        private static void WakeUp(FutexCompletionEntry entry, bool cancelTimeout, int ret)
        {
            if (cancelTimeout)
            {
                var p = entry.timeoutNode;
                if (p != null)
                {
                    p.Cancel();
                }
            }

            /* Dequeue the futex in the completion queue */
            Globals.CompletionQueue.Take(entry.thr.impl._value.thread._value);
            entry.Unlink();
            entry.thr.ReturnFromCompletion(ret);
        }
Beispiel #3
0
        public static void Initialize(ref Arch.BootParam param)
        {
            BootParam = param;

            PageAllocator = new FreeListPageAllocator();
            PageAllocator.Initialize(param.MainMemoryStart, param.MainMemorySize >> Arch.ArchDefinition.PageShift);

            CompletionQueueAllocator = new FreeListPageAllocator();
            CompletionQueueAllocator.Initialize(param.CompletionQueueBase, param.CompletionQueueSize >> Arch.ArchDefinition.PageShift);

            Threads              = ThreadList.CreateSentinal();
            FutexLists           = FutexCompletionEntry.CreateSentinal();
            TimeoutQueue         = new TimerQueue();
            SecurityManager      = new SecurityManager();
            LinuxMemoryAllocator = new LinuxMemoryAllocator();
            CapabilityManager    = new CapabilityManager();
            CompletionQueue      = new CompletionQueue();

            SecureFS.Initialize(Util.StringToByteArray("ExpressOS-security", false));
            ReadBufferUnmarshaler.Initialize();
        }
Beispiel #4
0
        public static void Initialize(ref Arch.BootParam param)
        {
            BootParam = param;

            PageAllocator = new FreeListPageAllocator();
            PageAllocator.Initialize(param.MainMemoryStart, param.MainMemorySize >> Arch.ArchDefinition.PageShift);

            CompletionQueueAllocator = new FreeListPageAllocator();
            CompletionQueueAllocator.Initialize(param.CompletionQueueBase, param.CompletionQueueSize >> Arch.ArchDefinition.PageShift);

            Threads = ThreadList.CreateSentinal();
            FutexLists = FutexCompletionEntry.CreateSentinal();
            TimeoutQueue = new TimerQueue();
            SecurityManager = new SecurityManager();
            LinuxMemoryAllocator = new LinuxMemoryAllocator();
            CapabilityManager = new CapabilityManager();
            CompletionQueue = new CompletionQueue();

            SecureFS.Initialize(Util.StringToByteArray("ExpressOS-security", false));
            ReadBufferUnmarshaler.Initialize();
        }
Beispiel #5
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);
        }
Beispiel #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);
        }
Beispiel #7
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;
        }
Beispiel #8
0
 public static void HandleFutexAsync(FutexCompletionEntry c, int ret)
 {
     var current = c.thr;
     c.Unlink();
     current.ReturnFromCompletion(ret);
 }
Beispiel #9
0
        private static void WakeUp(FutexCompletionEntry entry, bool cancelTimeout, int ret)
        {
            if (cancelTimeout)
            {
                var p = entry.timeoutNode;
                if (p != null)
                    p.Cancel();
            }

            /* Dequeue the futex in the completion queue */
            Globals.CompletionQueue.Take(entry.thr.impl._value.thread._value);
            entry.Unlink();
            entry.thr.ReturnFromCompletion(ret);
        }
Beispiel #10
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;
        }