struct host { /* we do not need to track last avail index *unlesswehavemorethanoneinflight.
*/ unsigned used_idx; unsigned called_used_idx; unsignedchar reserved[HOST_GUEST_PADDING - 4];
} host;
/* implemented by ring */ void alloc_ring(void)
{ int ret; int i;
ret = posix_memalign((void **)&ring, 0x1000, ring_size * sizeof *ring); if (ret) {
perror("Unable to allocate ring buffer.\n"); exit(3);
}
event = calloc(1, sizeof(*event)); if (!event) {
perror("Unable to allocate event buffer.\n"); exit(3);
}
guest.avail_idx = 0;
guest.kicked_avail_idx = -1;
guest.last_used_idx = 0;
host.used_idx = 0;
host.called_used_idx = -1; for (i = 0; i < ring_size; ++i) { struct desc desc = {
.index = i,
};
ring[i] = desc;
}
guest.num_free = ring_size;
data = calloc(ring_size, sizeof(*data)); if (!data) {
perror("Unable to allocate data buffer.\n"); exit(3);
}
}
/* guest side */ int add_inbuf(unsigned len, void *buf, void *datap)
{ unsigned head, index;
if (!guest.num_free) return -1;
guest.num_free--;
head = (ring_size - 1) & (guest.avail_idx++);
/* Start with a write. On MESI architectures this helps *avoidasharedstatewithconsumerthatispollingthisdescriptor.
*/
ring[head].addr = (unsignedlong)(void*)buf;
ring[head].len = len; /* read below might bypass write above. That is OK because it's just an *optimization.Ifthishappens,wewillgetthecachelineina *sharedstatewhichisunfortunate,butprobablynotworthitto *addanexplicitfullbarriertoavoidthis.
*/
barrier();
index = ring[head].index;
data[index].buf = buf;
data[index].data = datap; /* Barrier A (for pairing) */
smp_release();
ring[head].flags = DESC_HW;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.