Beispiel #1
0
void radixsort(int* nums, int count)
{
    int digit, max;
    Queue buckets[NDIGITS]; // One index per digit, including negatives

    // Don't bother working on one-element and empty array
    if (count < 2)
        return;

    for (int i = 0; i < NDIGITS; i++) { // Nullify each queue
        buckets[i].head = NULL;
        buckets[i].tail = NULL;
    }

    // Find the biggest number width
    max = radix_len(nums[0]);
    for (int i = 1; i < count; i++)
        if (radix_len(nums[i]) > max)
            max = radix_len(nums[i]);

    // Go through each column
    for (int i = 1; i <= max; i++) {
        // of each element
        for (int j = 0; j < count; j++) {

            // to get the i-th digit from j-th nums[] element,
            digit = radix_digit(nums[j], i) + BASE - 1; // compensate for negative digits

            // and enqueue it to the corresponding digit-th bucket.
            q_enq(buckets + digit, nums[j]);
        }

        // Take each element of nums[],
        for (int j = 0; j < count; j++)
            for (int k = 0; k < NDIGITS; k++)   // and fill it with whatever
                while (buckets[k].head != NULL) // we find in each non-empty bucket.
                    nums[j++] = q_deq(buckets + k);
    }
}
Beispiel #2
0
void
pktdemux()
{
   PACKET   pkt;
   NET      ifc;                /* interface packet came from */
   IFMIB    mib;
   int      pkts;
   char *   eth;

   pkts = 0;   /* packets per loop */

   while (rcvdq.q_len)
   {
      /* If we are low on free packets, don't hog CPU cycles */
      if (pkts++ > bigfreeq.q_len)
      {
#ifdef SUPERLOOP
         return;        /* don't hog stack on superloop */
#else    /* SUPERLOOP */
         tk_yield(); /* let application tasks process received packets */
         pkts = 0;   /* reset counter */
#endif   /* SUPERLOOP else */
      }

      /* If we get receive interupt from the net during this
      lock, the MAC driver needs to wait or reschedule */
      LOCK_NET_RESOURCE(RXQ_RESID);
      pkt = (PACKET)q_deq(&rcvdq);
      UNLOCK_NET_RESOURCE(RXQ_RESID);
      if (!pkt) panic("pktdemux: got null pkt");
      ifc = pkt->net;

      mib = ifc->n_mib;
      /* maintain mib stats for unicast and broadcast */
      if (isbcast(ifc, (u_char*)pkt->nb_buff + ETHHDR_BIAS))
         mib->ifInNUcastPkts++;
      else
         mib->ifInUcastPkts++;

      if(mib->ifAdminStatus == NI_DOWN)
      {
         LOCK_NET_RESOURCE(FREEQ_RESID);
         pk_free(pkt);  /* dump packet from downed interface */
         UNLOCK_NET_RESOURCE(FREEQ_RESID);
         mib->ifInDiscards++;
         continue;      /* next packet */
      }

#ifdef NPDEBUG
      if (*(pkt->nb_buff - ALIGN_TYPE) != 'M' ||
          *(pkt->nb_buff + pkt->nb_blen) != 'M')
      {
         dtrap();
         panic("pktdemux: corrupt pkt");
      }
#endif   /* NPDEBUG */

#ifdef  LOSSY_IO
      if(NDEBUG & LOSSY_RX)
      {
         if(myloss())  
         {
            LOCK_NET_RESOURCE(FREEQ_RESID);
            pk_free(pkt);        /* punt packet */
            UNLOCK_NET_RESOURCE(FREEQ_RESID);
            in_lastloss = (int)(cticks & 0x07) - 4;  /* pseudo random reset */
            continue;            /* act as if we sent OK */
         }
      }
#endif   /* LOSSY_IO */

      /* see if driver set pkt->nb_prot and pkt->type */
      if((ifc->n_flags & NF_NBPROT) == 0)
      {
         /* Set pkt->type and pkt->nb_prot based based on media type.
          * Some device drivers pass nb_plen as the total length of the
          * packet, while others subtract the MAC header. The latter is
          * probably the right thing to do, but because of this historic
          * inconsistency we don't try to fix it here - the longer size
          * turns out to be harmless since the IP layer fixes the size
          * based on the IP header length field.
          */
         switch(ifc->n_mib->ifType)
         {
         case ETHERNET:
            /* get pointer to ethernet header */
            eth = (pkt->nb_buff + ETHHDR_BIAS);
#ifdef IEEE_802_3
            /* see if it's got snap baggage */
            if (ET_TYPE_GET(eth) <= 0x0600)
            {
               struct snap_hdr *snap;
               snap = (struct snap_hdr *)(pkt->nb_buff + ETHHDR_SIZE);
               pkt->type = (unshort)(snap->type);
               pkt->nb_prot = pkt->nb_buff + pkt->net->n_lnh;
            }
            else
            {
               pkt->type = htons((unshort)ET_TYPE_GET(eth));
               pkt->nb_prot = pkt->nb_buff + ETHHDR_SIZE;
            }
#else
            pkt->type = htons((unshort)ET_TYPE_GET(eth));
            pkt->nb_prot = pkt->nb_buff + pkt->net->n_lnh;
#endif   /* IEEE_802_3 */
            break;
#if defined(USE_PPP) || defined(USE_SLIP) || defined(PROTOCOL_LIBS)
         case PPP:   /* PPP or SLIP over a UART */
         case SLIP:
            pkt->nb_prot = pkt->nb_buff + MaxLnh;
            pkt->type = IPTP;    /* only type our PPP supports */
            break;
#endif  /* USE_PPP || USE_SLIP */
#ifdef USE_PPPOE
         case PPPOE:
            /* do not change type yet, for PPPoE */
            break;
#endif   /* USE_PPPOE */
         default:    /* driver bug? */
            dprintf("pktdemux: bad Iface type %ld\n",ifc->n_mib->ifType);
            LOCK_NET_RESOURCE(FREEQ_RESID);
            pk_free(pkt);
            UNLOCK_NET_RESOURCE(FREEQ_RESID);
            continue;
         }
      }

      /* pkt->nb_prot and pkt->type are now set. pass pkt to upper layer */
      switch(pkt->type)
      {
      case IPTP:     /* IP type */
         LOCK_NET_RESOURCE(NET_RESID);
#ifdef SHARED_IPADDRS
         add_share_route(pkt);
#endif /* SHARED_IPADDRS */
#ifdef IP_V4
         ip_rcv(pkt);
#else
            /* don't care, it's IPv4 */
            LOCK_NET_RESOURCE(FREEQ_RESID);
            pk_free(pkt);
            UNLOCK_NET_RESOURCE(FREEQ_RESID);
#endif
		UNLOCK_NET_RESOURCE(NET_RESID);
         break;
#ifdef INCLUDE_ARP
      case ARPTP:       /* ARP type */
         LOCK_NET_RESOURCE(NET_RESID);
         arprcv(pkt);
         UNLOCK_NET_RESOURCE(NET_RESID);
         break;
#endif   /* INCLUDE_ARP */
#ifdef USE_PPPOE
      case  htons(0x8863):
      case  htons(0x8864):
         LOCK_NET_RESOURCE(NET_RESID);
         poe_rcv(pkt);
         UNLOCK_NET_RESOURCE(NET_RESID);
         break;
#endif   /* USE_PPPOE */
#ifdef IP_V6
      case  htons(0x86DD):
         /* Each received v6 pkt goes thru here exactly once, so set the
          * outer (first, and usually only) ipv6 header pointer. Tunneled headers
          * may exist further into the packet.
          */
         pkt->ip6_hdr = (struct ipv6 *)pkt->nb_prot;
         LOCK_NET_RESOURCE(NET_RESID);
         ip6_rcv(pkt);
         UNLOCK_NET_RESOURCE(NET_RESID);
         break;
#endif
      default:
#ifdef NPDEBUG
         if (NDEBUG & UPCTRACE)
            dprintf("pktdemux: bad pkt type 0x%04x\n", ntohs(pkt->type));
#endif   /* NPDEBUG */
         ifc->n_mib->ifInUnknownProtos++;
         LOCK_NET_RESOURCE(FREEQ_RESID);
         pk_free(pkt);           /* return to free buffer */
         UNLOCK_NET_RESOURCE(FREEQ_RESID);
         break;
      }
      continue;
   }
}