/* Initializes a ucq. You pass in addresses of mmaped pages for the main page * (prod_idx) and the spare page. I recommend mmaping a big chunk and breaking * it up over a bunch of ucqs, instead of doing a lot of little mmap() calls. */ void ucq_init_raw(struct ucq *ucq, uintptr_t pg1, uintptr_t pg2) { printd("[user] initializing ucq %08p for proc %d\n", ucq, getpid()); assert(!PGOFF(pg1)); assert(!PGOFF(pg2)); /* Prod and cons both start on the first page, slot 0. When they are * equal, the ucq is empty. */ atomic_set(&ucq->prod_idx, pg1); atomic_set(&ucq->cons_idx, pg1); ucq->prod_overflow = FALSE; atomic_set(&ucq->nr_extra_pgs, 0); atomic_set(&ucq->spare_pg, pg2); parlib_static_assert(sizeof(struct spin_pdr_lock) <= sizeof(ucq->u_lock)); spin_pdr_init((struct spin_pdr_lock*)(&ucq->u_lock)); ucq->ucq_ready = TRUE; }
void ceq_init(struct ceq *ceq, uint8_t op, size_t nr_events, size_t ring_sz) { /* In case they already had an mbox initialized, cleanup whatever was there * so we don't leak memory. They better not have asked for events before * doing this init call... */ ceq_cleanup(ceq); ceq->events = malloc(sizeof(struct ceq_event) * nr_events); memset(ceq->events, 0, sizeof(struct ceq_event) * nr_events); ceq->nr_events = nr_events; assert(IS_PWR2(ring_sz)); ceq->ring = malloc(sizeof(int32_t) * ring_sz); memset(ceq->ring, 0xff, sizeof(int32_t) * ring_sz); ceq->ring_sz = ring_sz; ceq->operation = op; ceq->ring_overflowed = FALSE; atomic_init(&ceq->prod_idx, 0); atomic_init(&ceq->cons_pub_idx, 0); atomic_init(&ceq->cons_pvt_idx, 0); parlib_static_assert(sizeof(struct spin_pdr_lock) <= sizeof(ceq->u_lock)); spin_pdr_init((struct spin_pdr_lock*)&ceq->u_lock); }