예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
        }
예제 #4
0
        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;
        }
예제 #5
0
        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);
        }
예제 #6
0
 public void Enqueue(VBinderMessage msg)
 {
     Contract.Requires(msg != null && msg.GhostTarget == Owner);
     MessageQueue.Enqueue(msg);
 }
예제 #7
0
        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;
        }
예제 #8
0
 public void Enqueue(VBinderMessage msg)
 {
     Contract.Requires(msg != null && msg.GhostTarget == Owner);
     MessageQueue.Enqueue(msg);
 }