int fbfront_receive(struct fbfront_dev *dev, union xenfb_in_event *buf, int n) { struct xenfb_page *page = dev->page; uint32_t prod, cons; int i; #ifdef HAVE_LIBC if (dev->fd != -1) { files[dev->fd].read = 0; mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ } #endif prod = page->in_prod; if (prod == page->in_cons) return 0; rmb(); /* ensure we see ring contents up to prod */ for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++) memcpy(buf + i, &XENFB_IN_RING_REF(page, cons), sizeof(*buf)); mb(); /* ensure we got ring contents */ page->in_cons = cons; notify_remote_via_evtchn(dev->evtchn); #ifdef HAVE_LIBC if (cons != prod && dev->fd != -1) /* still some events to read */ files[dev->fd].read = 1; #endif return i; }
static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event) { uint32_t prod; struct xenfb_page *page = xenfb->c.page; prod = page->in_prod; /* caller ensures !xenfb_queue_full() */ xen_mb(); /* ensure ring space available */ XENFB_IN_RING_REF(page, prod) = *event; xen_wmb(); /* ensure ring contents visible */ page->in_prod = prod + 1; xen_be_send_notify(&xenfb->c.xendev); }
static void xenfb_send_event(struct xenfb *xenfb, union xenfb_in_event *event) { uint32_t prod; struct xenfb_page *page = xenfb->fb.page; prod = page->in_prod; /* caller ensures !xenfb_queue_full() */ xen_mb(); /* ensure ring space available */ XENFB_IN_RING_REF(page, prod) = *event; xen_wmb(); /* ensure ring contents visible */ page->in_prod = prod + 1; xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port); }