int evt_trigger(spdid_t spdid, long extern_evt) { struct evt *e; int ret = 0; lock_take(&evt_lock); e = mapping_find(extern_evt); if (NULL == e) goto err; ACT_RECORD(ACT_TRIGGER, spdid, e->extern_id, cos_get_thd_id(), 0); /* Trigger an event being waited for? */ if (0 != (ret = __evt_trigger(e))) { lock_release(&evt_lock); ACT_RECORD(ACT_WAKEUP, spdid, e->extern_id, cos_get_thd_id(), ret); if (sched_wakeup(cos_spd_id(), ret)) BUG(); } else { lock_release(&evt_lock); } return 0; err: lock_release(&evt_lock); return -1; }
/* Wait for a specific event */ int evt_wait(spdid_t spdid, long extern_evt) { struct evt *e; while (1) { int ret; lock_take(&evt_lock); e = mapping_find(extern_evt); if (NULL == e) goto err; if (0 > (ret = __evt_read(e))) goto err; ACT_RECORD(ACT_WAIT, spdid, e->extern_id, cos_get_thd_id(), 0); lock_release(&evt_lock); if (1 == ret) { assert(extern_evt == e->extern_id); return 0; } else { ACT_RECORD(ACT_SLEEP, spdid, e->extern_id, cos_get_thd_id(), 0); if (0 > sched_block(cos_spd_id(), 0)) BUG(); } } err: lock_release(&evt_lock); return -1; }
int __evt_wait(spdid_t spdid, long extern_evt, int n) { struct evt *e; while (1) { int ret; lock_take(&evt_lock); e = mapping_find(extern_evt); if (NULL == e) goto err; if (0 > (ret = __evt_read(e))) goto err; ACT_RECORD(ACT_WAIT, spdid, e->extern_id, cos_get_thd_id(), 0); e->n_wait = n; e->core_id = cos_cpuid(); if (ret == 1) e->n_received = 0; lock_release(&evt_lock); if (1 == ret) { assert(extern_evt == e->extern_id); return 0; } else { ACT_RECORD(ACT_SLEEP, spdid, e->extern_id, cos_get_thd_id(), 0); /* We can use acaps to block / wakeup, which * can avoid calling scheduler. But it's like * a hack. */ if (0 > sched_block(cos_spd_id(), 0)) BUG(); } } err: lock_release(&evt_lock); return -1; }
void evt_free(spdid_t spdid, long extern_evt) { struct evt *e; lock_take(&evt_lock); e = mapping_find(extern_evt); if (NULL == e) goto done; __evt_free(e); mapping_free(extern_evt); done: lock_release(&evt_lock); return; }
int evt_set_prio(spdid_t spdid, long extern_evt, int prio) { struct evt *e; if (prio >= EVT_NUM_PRIOS) return -1; lock_take(&evt_lock); e = mapping_find(extern_evt); if (NULL == e) goto err; e->prio = prio; /* FIXME: place into correct list in the group if it is triggered */ lock_release(&evt_lock); return 0; err: lock_release(&evt_lock); return -1; }