public static void HandleFutexAsync(FutexCompletionEntry c, int ret) { var current = c.thr; c.Unlink(); current.ReturnFromCompletion(ret); }
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); }
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(); }
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); }
// 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); }
// 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 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); }
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; }