private static void HandleAsyncCall(Thread target, VBinderMessage msg) { var entry = target.VBinderState.Completion; var length = msg.Length; entry.ptr_label.Write(target.Parent, msg.label); entry.userBuf.Write(target, new Pointer(msg.payload.Location), length); msg.Recycle(); target.VBinderState.Completion = null; target.ReturnFromCompletion(length); }
public void Enqueue(VBinderMessage x) { Contract.Requires(x != null && x.GhostTarget == GhostOwner); if (len == data.Length) { Arch.Console.WriteLine("VBinderMessage overflow"); Utils.Panic(); return; } var nextEmpty = first + len < data.Length ? first + len : first + len - data.Length; data[nextEmpty] = x; ++len; }
private static int Send(Thread current, int cap_idx, UserPtr userBuf, uint size) { if (!current.Parent.Space.VerifyRead(userBuf, size)) { return(-ErrorCode.EFAULT); } var cap_ref = current.VBinderState.Find(current, cap_idx); if (cap_ref == null) { return(-ErrorCode.EINVAL); } var blob = Globals.AllocateAlignedCompletionBuffer((int)size); if (!blob.isValid) { return(-ErrorCode.ENOMEM); } if (userBuf.Read(current, blob, (int)size) != 0) { return(-ErrorCode.EFAULT); } var targetThread = cap_ref.def.parent; // Object invariant of thread Contract.Assume(targetThread.VBinderState.Owner == targetThread); var msg = new VBinderMessage(current, targetThread, cap_ref.def.label, blob, (int)size); if (targetThread.VBinderState.Completion != null) { HandleAsyncCall(targetThread, msg); } else { Contract.Assert(msg.GhostTarget == targetThread); targetThread.VBinderState.Enqueue(msg); } return((int)size); }
public void Enqueue(VBinderMessage msg) { Contract.Requires(msg != null && msg.GhostTarget == Owner); MessageQueue.Enqueue(msg); }
private static int Send(Thread current, int cap_idx, UserPtr userBuf, uint size) { if (!current.Parent.Space.VerifyRead(userBuf, size)) return -ErrorCode.EFAULT; var cap_ref = current.VBinderState.Find(current, cap_idx); if (cap_ref == null) return -ErrorCode.EINVAL; var blob = Globals.AllocateAlignedCompletionBuffer((int)size); if (!blob.isValid) return -ErrorCode.ENOMEM; if (userBuf.Read(current, blob, (int)size) != 0) return -ErrorCode.EFAULT; var targetThread = cap_ref.def.parent; // Object invariant of thread Contract.Assume(targetThread.VBinderState.Owner == targetThread); var msg = new VBinderMessage(current, targetThread, cap_ref.def.label, blob, (int)size); if (targetThread.VBinderState.Completion != null) { HandleAsyncCall(targetThread, msg); } else { Contract.Assert(msg.GhostTarget == targetThread); targetThread.VBinderState.Enqueue(msg); } return (int)size; }