/* 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; }