Beispiel #1
0
/**
 * returns -1 on error, or size on success
 */
static int do_send(struct libvchan *ctrl, const void *data, size_t size)
{
    int real_idx = wr_prod(ctrl) & (wr_ring_size(ctrl) - 1);
    int avail_contig = wr_ring_size(ctrl) - real_idx;
    if (VCHAN_DEBUG) {
        char metainfo[32];
        struct iovec iov[2];
        iov[0].iov_base = metainfo;
        iov[0].iov_len = snprintf(metainfo, 32, "vchan wr %d/%d", ctrl->other_domain_id, ctrl->device_number);
        iov[1].iov_base = (void *)data;
        iov[1].iov_len = size;
        writev(-1, iov, 2);
    }
    if (avail_contig > size)
        avail_contig = size;
    memcpy(wr_ring(ctrl) + real_idx, data, avail_contig);
    if (avail_contig < size)
    {
        // we rolled across the end of the ring
        memcpy(wr_ring(ctrl), data + avail_contig, size - avail_contig);
    }
    barrier(); // data must be in the ring prior to increment
    wr_prod(ctrl) += size;
    barrier(); // increment must happen prior to notify
    if (do_notify(ctrl) < 0)
        return -1;
    return size;
}
Beispiel #2
0
Datei: io.c Projekt: CPFL/gxen
/**
 * returns -1 on error, or size on success
 */
static int do_send(struct libxenvchan *ctrl, const void *data, size_t size)
{
	int real_idx = wr_prod(ctrl) & (wr_ring_size(ctrl) - 1);
	int avail_contig = wr_ring_size(ctrl) - real_idx;
	if (avail_contig > size)
		avail_contig = size;
	xen_mb(); /* read indexes /then/ write data */
	memcpy(wr_ring(ctrl) + real_idx, data, avail_contig);
	if (avail_contig < size)
	{
		// we rolled across the end of the ring
		memcpy(wr_ring(ctrl), data + avail_contig, size - avail_contig);
	}
	xen_wmb(); /* write data /then/ notify */
	wr_prod(ctrl) += size;
	if (send_notify(ctrl, VCHAN_NOTIFY_WRITE))
		return -1;
	return size;
}