int rt_heap_free(RT_HEAP *heap, void *block) { int err, nwake; spl_t s; if (block == NULL) return -EINVAL; xnlock_get_irqsave(&nklock, s); heap = xeno_h2obj_validate(heap, XENO_HEAP_MAGIC, RT_HEAP); if (!heap) { err = xeno_handle_error(heap, XENO_HEAP_MAGIC, RT_HEAP); goto unlock_and_exit; } if (heap->mode & H_SINGLE) { /* No-op in single-block mode. */ err = 0; goto unlock_and_exit; } err = xnheap_free(&heap->heap_base, block); if (!err && xnsynch_nsleepers(&heap->synch_base) > 0) { xnpholder_t *holder, *nholder; nholder = getheadpq(xnsynch_wait_queue(&heap->synch_base)); nwake = 0; while ((holder = nholder) != NULL) { RT_TASK *sleeper = thread2rtask(link2thread(holder, plink)); void *block; block = xnheap_alloc(&heap->heap_base, sleeper->wait_args.heap.size); if (block) { nholder = xnsynch_wakeup_this_sleeper(&heap-> synch_base, holder); sleeper->wait_args.heap.block = block; nwake++; } else nholder = nextpq(xnsynch_wait_queue (&heap->synch_base), holder); } if (nwake > 0) xnpod_schedule(); } unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }
ER set_flg(ID flgid, UINT setptn) { xnpholder_t *holder, *nholder; uiflag_t *flag; ER err = E_OK; spl_t s; if (xnpod_asynch_p()) return EN_CTXID; if (flgid <= 0 || flgid > uITRON_MAX_FLAGID) return E_ID; xnlock_get_irqsave(&nklock, s); flag = xnmap_fetch(ui_flag_idmap, flgid); if (!flag) { err = E_NOEXS; goto unlock_and_exit; } if (setptn == 0) goto unlock_and_exit; flag->flgvalue |= setptn; if (!xnsynch_pended_p(&flag->synchbase)) goto unlock_and_exit; nholder = getheadpq(xnsynch_wait_queue(&flag->synchbase)); while ((holder = nholder) != NULL) { uitask_t *sleeper = thread2uitask(link2thread(holder, plink)); UINT wfmode = sleeper->wargs.flag.wfmode; UINT waiptn = sleeper->wargs.flag.waiptn; if (((wfmode & TWF_ORW) && (waiptn & flag->flgvalue) != 0) || (!(wfmode & TWF_ORW) && ((waiptn & flag->flgvalue) == waiptn))) { nholder = xnsynch_wakeup_this_sleeper(&flag->synchbase, holder); sleeper->wargs.flag.waiptn = flag->flgvalue; if (wfmode & TWF_CLR) flag->flgvalue = 0; } else nholder = nextpq(xnsynch_wait_queue(&flag->synchbase), holder); } xnpod_schedule(); unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }
int rt_event_signal(RT_EVENT *event, unsigned long mask) { xnpholder_t *holder, *nholder; int err = 0, resched = 0; spl_t s; xnlock_get_irqsave(&nklock, s); event = xeno_h2obj_validate(event, XENO_EVENT_MAGIC, RT_EVENT); if (!event) { err = xeno_handle_error(event, XENO_EVENT_MAGIC, RT_EVENT); goto unlock_and_exit; } /* Post the flags. */ event->value |= mask; /* And wakeup any sleeper having its request fulfilled. */ nholder = getheadpq(xnsynch_wait_queue(&event->synch_base)); while ((holder = nholder) != NULL) { RT_TASK *sleeper = thread2rtask(link2thread(holder, plink)); int mode = sleeper->wait_args.event.mode; unsigned long bits = sleeper->wait_args.event.mask; if (((mode & EV_ANY) && (bits & event->value) != 0) || (!(mode & EV_ANY) && ((bits & event->value) == bits))) { sleeper->wait_args.event.mask = (bits & event->value); nholder = xnsynch_wakeup_this_sleeper(&event->synch_base, holder); resched = 1; } else nholder = nextpq(xnsynch_wait_queue(&event->synch_base), holder); } if (resched) xnpod_schedule(); unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }