Beispiel #1
0
static error_t 
stream_read (struct packet *packet, int *dequeue, unsigned *flags,
	     char **data, size_t *data_len, size_t amount)
{
  error_t err = packet_read (packet, data, data_len, amount);
  *dequeue = (packet_readable (packet) == 0);
  return err;
}
Beispiel #2
0
void * get_receive_packet(int queue_index, int * index)
{
	__u64 zkb_index = 0;
	__u64 * index_ptr = NULL;
	__u64 out = 0;
	pthread_mutex_t * lock = &rlock[queue_index];
	struct sk_zcopy * zkb = NULL;
	struct shared_hash_table * rh = rhash.ht;
	struct zcopy_buckets * buckets = rhash.zb;

	if(queue_index > rh->hash_count)
	{
		E("queue index %d > max %d.\n", queue_index, rh->hash_count);
		return NULL;
	}

	pthread_mutex_lock(lock);
	if(!packet_readable(queue_index))
		goto out;

	index_ptr = (__u64 *)rhash.queue_ptr[queue_index];
	out = buckets[queue_index].zkb_out % rh->zkb_count_per_queue;

	zkb_index = index_ptr[out];

#ifdef DEBUG
	if((zkb_index == 0) || (whash.ht && (zkb_index > whash.ht->start_index)))
	{
		E("skb index = %llu > %u, queue %d out %llu, in %u.\n", \
				zkb_index, whash.ht->start_index, queue_index, out, buckets[queue_index].zkb_in);
		goto err;
	}
#endif
	zkb = get_zkb_by_index(zkb_index);
	if(zkb == NULL)
		goto err;

	if((zkb->magic != FROMKERNEL) || (zkb->queue_index != queue_index))
	{
		D("skb magic %x error or queue index %d != skb->queue_index %d\n", zkb->magic, queue_index, zkb->queue_index);
		zkb = NULL;
		goto err;
	}

	zkb->usage = 1;
	*index = zkb_index;
err:
	++buckets[queue_index].zkb_out;
out:
	pthread_mutex_unlock(lock);
	return zkb ? zkb->virt_data : NULL;
}
Beispiel #3
0
static error_t 
stream_write (struct pq *pq, void *source,
	      char *data, size_t data_len, size_t *amount)
{
  struct packet *packet = pq_tail (pq, PACKET_TYPE_DATA, source);

  if (packet_readable (packet) > 0
      && data_len > PACKET_SIZE_LARGE
      && (! page_aligned (data - packet->buf_end)
	  || ! packet_ensure_efficiently (packet, data_len)))
    /* Put a large page-aligned transfer in its own packet, if it's
       page-aligned `differently' than the end of the current packet, or if
       the current packet can't be extended in place.  */
    packet = pq_queue (pq, PACKET_TYPE_DATA, source);

  if (!packet)
    return ENOBUFS;
  else
    return packet_write (packet, data, data_len, amount);
}