Exemple #1
0
static int do_recv(struct libvchan *ctrl, void *data, size_t size)
{
    int real_idx = rd_cons(ctrl) & (rd_ring_size(ctrl) - 1);
    int avail_contig = rd_ring_size(ctrl) - real_idx;
    if (avail_contig > size)
        avail_contig = size;
    barrier(); // data read must happen after rd_cons read
    memcpy(data, rd_ring(ctrl) + real_idx, avail_contig);
    if (avail_contig < size)
    {
        // we rolled across the end of the ring
        memcpy(data + avail_contig, rd_ring(ctrl), size - avail_contig);
    }
    rd_cons(ctrl) += size;
    if (VCHAN_DEBUG) {
        char metainfo[32];
        struct iovec iov[2];
        iov[0].iov_base = metainfo;
        iov[0].iov_len = snprintf(metainfo, 32, "vchan rd %d/%d", ctrl->other_domain_id, ctrl->device_number);
        iov[1].iov_base = data;
        iov[1].iov_len = size;
        writev(-1, iov, 2);
    }
    barrier(); // consumption must happen prior to notify of newly freed space
    if (do_notify(ctrl) < 0)
        return -1;
    return size;
}
Exemple #2
0
Fichier : io.c Projet : CPFL/gxen
static int do_recv(struct libxenvchan *ctrl, void *data, size_t size)
{
	int real_idx = rd_cons(ctrl) & (rd_ring_size(ctrl) - 1);
	int avail_contig = rd_ring_size(ctrl) - real_idx;
	if (avail_contig > size)
		avail_contig = size;
	xen_rmb(); /* data read must happen /after/ rd_cons read */
	memcpy(data, rd_ring(ctrl) + real_idx, avail_contig);
	if (avail_contig < size)
	{
		// we rolled across the end of the ring
		memcpy(data + avail_contig, rd_ring(ctrl), size - avail_contig);
	}
	xen_mb(); /* consume /then/ notify */
	rd_cons(ctrl) += size;
	if (send_notify(ctrl, VCHAN_NOTIFY_READ))
		return -1;
	return size;
}