void find_descendants__rx_handler(struct intermon_binding *b, intermon_caprep_t caprep, genvaddr_t st) { errval_t err; struct intermon_state *inter_st = (struct intermon_state*)b->st; coreid_t from = inter_st->core_id; struct capability cap; caprep_to_capability(&caprep, &cap); bool has_descendants; err = monitor_has_descendants(&cap, &has_descendants); assert(err_is_ok(err)); struct find_descendants_result_msg_st *msg_st; msg_st = malloc(sizeof(*msg_st)); if (!msg_st) { err = LIB_ERR_MALLOC_FAIL; USER_PANIC_ERR(err, "could not alloc find_descendants_result_msg_st"); } msg_st->queue_elem.cont = find_descendants_result_send_cont; msg_st->st = st; if (err_is_ok(err)) { err = has_descendants ? SYS_ERR_OK : SYS_ERR_CAP_NOT_FOUND; } msg_st->status = err; err = capsend_target(from, (struct msg_queue_elem*)msg_st); if (err_is_fail(err)) { USER_PANIC_ERR(err, "could not enqueue find_descendants_result msg"); } }
static void capsend_mc_send_cont(struct intermon_binding *b, struct intermon_msg_queue_elem *e) { struct capsend_mc_msg_st *msg_st = (struct capsend_mc_msg_st*)e; struct capsend_mc_st *mc_st = msg_st->mc_st; errval_t err = SYS_ERR_OK; // if do_send is false, an error occured in the multicast setup, so do not // send anything if (mc_st->do_send) { err = mc_st->send_fn(b, &mc_st->caprep, mc_st); } if (err_no(err) == FLOUNDER_ERR_TX_BUSY) { err = capsend_target(msg_st->dest, (struct msg_queue_elem*)msg_st); } if (err_is_fail(err)) { USER_PANIC_ERR(err, "sending dequeued capops message"); } // decrement counter of number of queued messages if (!--mc_st->num_queued) { // if counter is zero, cleanup outgoing memory free(mc_st->msg_st_arr); mc_st->msg_st_arr = NULL; if (!mc_st->do_send || !mc_st->num_pending) { // if the send has been aborted, also cleanup cross-call state free(mc_st); } } }
static void retrieve_result__enq(errval_t status, struct retrieve_response_st *st) { errval_t err; st->status = status; st->iqn.cont = retrieve_result__send; err = capsend_target(st->from, (struct msg_queue_elem*)st); PANIC_IF_ERR(err, "enqueing retrieve result"); }
static void revoke_slave_steps__fin(void *st) { errval_t err; struct revoke_slave_st *rvk_st = (struct revoke_slave_st*)st; rvk_st->im_qn.cont = revoke_done__send; err = capsend_target(rvk_st->from, (struct msg_queue_elem*)rvk_st); PANIC_IF_ERR(err, "enqueueing revoke_done"); }
errval_t capsend_owner(struct domcapref capref, struct msg_queue_elem *queue_elem) { errval_t err; // read cap owner coreid_t owner; err = monitor_get_domcap_owner(capref, &owner); if (err_is_fail(err)) { return err; } // enqueue to owner return capsend_target(owner, queue_elem); }
void revoke_mark__rx(struct intermon_binding *b, intermon_caprep_t caprep, genvaddr_t st) { DEBUG_CAPOPS("%s\n", __FUNCTION__); errval_t err; struct intermon_state *inter_st = (struct intermon_state*)b->st; struct revoke_slave_st *rvk_st; err = calloce(1, sizeof(*rvk_st), &rvk_st); PANIC_IF_ERR(err, "allocating revoke slave state"); rvk_st->from = inter_st->core_id; rvk_st->st = st; caprep_to_capability(&caprep, &rvk_st->rawcap); if (!slaves_head) { assert(!slaves_tail); slaves_head = slaves_tail = rvk_st; } else { assert(slaves_tail); assert(!slaves_tail->next); slaves_tail->next = rvk_st; slaves_tail = rvk_st; } // pause any ongoing "delete stepping" as mark phases on other nodes need // to delete all foreign copies before we can delete locally owned caps delete_steps_pause(); // XXX: this invocation could create a scheduling hole that could be // problematic in RT systems and should probably be done in a loop. err = monitor_revoke_mark_relations(&rvk_st->rawcap); if (err_no(err) == SYS_ERR_CAP_NOT_FOUND) { // found no copies or descendants of capability on this core, // do nothing. -SG DEBUG_CAPOPS("no copies on core %d\n", disp_get_core_id()); } else if (err_is_fail(err)) { USER_PANIC_ERR(err, "marking revoke"); } rvk_st->im_qn.cont = revoke_ready__send; err = capsend_target(rvk_st->from, (struct msg_queue_elem*)rvk_st); PANIC_IF_ERR(err, "enqueing revoke_ready"); }
static errval_t owner_updated(coreid_t owner, genvaddr_t st) { errval_t err; struct owner_updated_msg_st *msg_st = calloc(1, sizeof(struct owner_updated_msg_st)); if (!msg_st) { return LIB_ERR_MALLOC_FAIL; } msg_st->queue_elem.cont = owner_updated_send_cont; msg_st->st = st; err = capsend_target(owner, (struct msg_queue_elem*)msg_st); if (err_is_fail(err)) { free(msg_st); } return err; }
static errval_t find_cap_result(coreid_t dest, errval_t result, genvaddr_t st) { errval_t err; struct find_cap_result_msg_st *msg_st = calloc(1, sizeof(struct find_cap_result_msg_st)); if (!msg_st) { return LIB_ERR_MALLOC_FAIL; } msg_st->queue_elem.cont = find_cap_result_send_cont; msg_st->result = result; msg_st->st = st; err = capsend_target(dest, (struct msg_queue_elem*)msg_st); if (err_is_fail(err)) { free(msg_st); } return err; }
static errval_t capsend_mc_enqueue(struct capsend_mc_st *mc_st, coreid_t dest) { errval_t err; // get next msg_st struct capsend_mc_msg_st *msg_st = &mc_st->msg_st_arr[mc_st->num_queued]; msg_st->queue_elem.cont = capsend_mc_send_cont; msg_st->mc_st = mc_st; msg_st->dest = dest; err = capsend_target(dest, (struct msg_queue_elem*)msg_st); if (err_is_ok(err)) { // count successful enqueue mc_st->num_queued++; if (mc_st->num_pending >= 0) { // also track number of pending exchanges if requested mc_st->num_pending++; } } return err; }