Beispiel #1
0
 //push a single packet onto the ring
 void IAdapter.PopulateTxRing(Bytes header, Bytes data)
 {
     try {
         PacketFifo txFree     = this.txFreeFifo.Acquire();
         PacketFifo txToDevice = this.txFifo.Acquire();
         DebugPrint("populate tx ring\n");
         try {
             Packet packet = txFree.Pop();
             packet.SetFragment(0, header);
             packet.SetFragment(1, data);
             txToDevice.Push(packet);
         }
         finally {
             this.txFreeFifo.Release(txFree);
             this.txFifo.Release(txToDevice);
         }
     }
     catch (Exception e) {
         DebugStub.Print("Populate tx ring failed?? {0}\n", DebugStub.ArgList(e));
         DebugStub.Break();
     }
     //When to exchange?
     //how do we best manage the tradeoff of throughput and latency?
     //to begin let's just send one at a time.
     //I think i'd rather have another thread....
     using (thisLock.Lock()) {
         TxExchange();
     }
 }
Beispiel #2
0
        private void TxExchange()
        {
            int toCount   = 0;
            int fromCount = 0;

            NicDeviceContract /*.Imp*/ imp = (NicDeviceContract)nicChannel.Acquire();

            try {
                PacketFifo src  = this.txFifo.Acquire();
                PacketFifo free = this.txFreeFifo.Acquire();

                toCount = src.Count;
                try {
                    src = imp.GiveTxPacketsToDevice(src);

                    fromCount = src.Count;
                    free.Push(src);
                }
                finally {
                    this.txFreeFifo.Release(free);
                    this.txFifo.Release(src);
                }
            }
            catch (Exception e) {
                DebugStub.Print("TxExchange FAILED arg {0}\n", DebugStub.ArgList(e.ToString()));
                DebugStub.Break();
            }
            finally {
                nicChannel.Release(imp);
            }
            DebugPrint("TxExchange out: {0} in: {1}\n",
                       toCount, fromCount);
        }
Beispiel #3
0
        // Get the received packets from the adapter
        void DeMuxReceivedPackets()
        {
            //Grab the latest set of packets
            RxExchange();

            PacketFifo newPackets = this.rxFifo.Acquire();

            try {
                int count = newPackets.Count;
                for (int i = 0; i < count; i++)
                {
                    Packet packet = newPackets.Pop();

                    // If packet from device has an error
                    // recycle it right away.
                    FromDeviceFlags fromFlags = packet.FromDeviceFlags;
                    if ((fromFlags & FromDeviceFlags.ReceiveError) != 0)
                    {
                        DebugStub.Print("Packet had error???\n");
                        newPackets.Push(packet);
                        continue;
                    }
                    Bytes data = packet.ReleaseFragment(0);
                    Ethernet.ProcessIncomingPacket(data, this);
#if  false
                    if (filterAdapter == null ||
                        filterAdapter.ProcessIncomingPacket(data))
                    {
                        Ethernet.ProcessIncomingPacket(data, this);
                    }
                    else
                    {
                        //delete data;
                    }
#endif
                    //XXX Totally inefficient first try immediately replaces
                    //the lost data.
                    Bytes nxtPacket = new Bytes(new byte[this.mtu]);
                    packet.SetFragment(0, nxtPacket);
                    newPackets.Push(packet);
                }
            }
            finally {
                this.rxFifo.Release(newPackets);
            }
        }
Beispiel #4
0
 private void RxProvisionInternal(PacketFifo toDevice)
 {
     for (int i = 0; i < toDevice.Capacity; i++)
     {
         toDevice.Push(
             new Packet(
                 new Bytes(new byte[this.mtu])
                 )
             );
     }
 }
        internal void LockedDrainRecvBuffer(PacketFifo toUser)
        {
            DmaMemory mem;
            ulong     controlBits;

            while (rxRingBuffer.Peek(out mem, out controlBits))
            {
                Packet packet = MakePacketFromDescriptor(mem, controlBits);
                toUser.Push(packet);
                rxRingBuffer.Pop();
            }
        }
Beispiel #6
0
        //since data comes from the user, the packets are empty shells
        //with a default of two fragments; one for the header and one for
        //the packet body
        private void TxProvision()
        {
            PacketFifo txFree = this.txFreeFifo.Acquire();

            for (int i = 0; i < txFree.Capacity; i++)
            {
                txFree.Push(
                    new Packet(2)
                    );
            }
            this.txFreeFifo.Release(txFree);
        }
        internal void LockedPushTsmtBuffer(Packet packet)
        {
            DebugStub.Assert(packet.FragmentCount == 1);
            DebugStub.Assert(!txRingBuffer.IsFull);

            this._LockedPushTsmtBuffer(packet);

            PacketFifo liveFifo = this.txPacketsInDevice.Acquire();

            liveFifo.Push(packet);
            txPacketsInDevice.Release(liveFifo);
        }
Beispiel #8
0
 //push a single packet onto the ring
 void IAdapter.PopulateTxRing(Bytes header, Bytes data)
 {
     try {
         PacketFifo txFree     = this.txFreeFifo.Acquire();
         PacketFifo txCoalesce = this.txCoalesceFifo.Acquire();
         try {
             DebugStub.Assert(txFree.Count > 0);
             int cnt = 0;
             while (txFree.Count <= 0)
             {
                 //try again...
                 //this happens when we're hammering the outgoing connection
                 this.txCoalesceFifo.Release(txCoalesce);
                 this.txFreeFifo.Release(txFree);
                 this.muxEvent.Set();
                 Thread.Yield();
                 txFree     = this.txFreeFifo.Acquire();
                 txCoalesce = this.txCoalesceFifo.Acquire();
                 if (cnt > 100)
                 {
                     DebugStub.Print("txFree empty???\n");
                     //DebugStub.Break();
                 }
                 cnt++;
             }
             Packet packet = txFree.Pop();
             packet.SetFragment(0, header);
             packet.SetFragment(1, data);
             if ((txCoalesce.Count + 1) > txCoalesce.Capacity)
             {
                 DebugStub.Break();
             }
             DebugStub.Assert((txCoalesce.Count + 1) <= txCoalesce.Capacity);
             txCoalesce.Push(packet);
         }
         catch {
             DebugStub.Print("failure in populate tx ring\n");
             DebugStub.Break();
             DebugStub.Assert(false);
         }
         finally {
             this.txCoalesceFifo.Release(txCoalesce);
             this.txFreeFifo.Release(txFree);
             //notify the mux that there are waiting packets
             this.muxEvent.Set();
         }
     }
     catch (Exception e) {
         DebugStub.Print("Populate tx ring failed?? {0}\n", DebugStub.ArgList(e));
         DebugStub.Break();
     }
 }
        internal void LockedPushRecvBuffer(Packet packet)
        {
            DebugStub.Assert(packet.FragmentCount == 1);
            DebugStub.Assert(!rxRingBuffer.IsFull);

            int length = packet.GetFragmentLength(0);

            this.LockedPushRecvBuffer(length);
            PacketFifo liveFifo = this.rxPacketsInDevice.Acquire();

            liveFifo.Push(packet);
            rxPacketsInDevice.Release(liveFifo);
        }
Beispiel #10
0
        public void Run()
        {
            System.DebugStub.Print("Nic@" + Kernel.CurrentThread + ". ");
            while (true)
            {
                this.muxEvent.WaitOne();
                PacketFifo txCoalesce = this.txCoalesceFifo.Acquire();
                PacketFifo txToDevice = this.txFifo.Acquire();

                try {
                    DebugPrint("coalescing {0} packets\n", txCoalesce.Count);
                    txToDevice.Push(txCoalesce);
                }
                catch (Exception e) {
                    DebugStub.Print("Mux FAILED! arg {0}\n", DebugStub.ArgList(e.ToString()));
                    DebugStub.Break();
                }
                finally {
                    this.txCoalesceFifo.Release(txCoalesce);
                    this.txFifo.Release(txToDevice);
                    TxExchange();
                }
            }
        }