int rt_heap_delete_inner(RT_HEAP *heap, void __user *mapaddr) { int err = 0; spl_t s; if (!xnpod_root_p()) return -EPERM; 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); xnlock_put_irqrestore(&nklock, s); return err; } xeno_mark_deleted(heap); /* Get out of the nklocked section before releasing the heap memory, since we are about to invoke Linux kernel services. */ xnlock_put_irqrestore(&nklock, s); /* * The heap descriptor has been marked as deleted before we * released the superlock thus preventing any sucessful * subsequent calls of rt_heap_delete(), so now we can * actually destroy it safely. */ #ifdef CONFIG_XENO_OPT_PERVASIVE if (heap->mode & H_MAPPABLE) err = xnheap_destroy_mapped(&heap->heap_base, __heap_post_release, mapaddr); else #endif /* CONFIG_XENO_OPT_PERVASIVE */ err = xnheap_destroy(&heap->heap_base, &__heap_flush_private, NULL); xnlock_get_irqsave(&nklock, s); if (err) heap->magic = XENO_HEAP_MAGIC; else if (!(heap->mode & H_MAPPABLE)) __heap_post_release(&heap->heap_base); xnlock_put_irqrestore(&nklock, s); return err; }
int rt_heap_delete_inner(RT_HEAP *heap, void __user *mapaddr) { int err; spl_t s; if (!xnpod_root_p()) return -EPERM; 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); xnlock_put_irqrestore(&nklock, s); return err; } xeno_mark_deleted(heap); /* Get out of the nklocked section before releasing the heap memory, since we are about to invoke Linux kernel services. */ xnlock_put_irqrestore(&nklock, s); /* * The heap descriptor has been marked as deleted before we * released the superlock thus preventing any subsequent call * to rt_heap_delete() to succeed, so now we can actually * destroy it safely. */ #ifndef __XENO_SIM__ if (heap->mode & H_MAPPABLE) xnheap_destroy_mapped(&heap->heap_base, __heap_post_release, mapaddr); else #endif { xnheap_destroy(&heap->heap_base, &__heap_flush_private, NULL); __heap_post_release(&heap->heap_base); } return 0; }
int rt_intr_delete(RT_INTR *intr) { int err = 0, rc = XNSYNCH_DONE; spl_t s; if (xnpod_asynch_p()) return -EPERM; xnlock_get_irqsave(&nklock, s); intr = xeno_h2obj_validate(intr, XENO_INTR_MAGIC, RT_INTR); if (!intr) { err = xeno_handle_error(intr, XENO_INTR_MAGIC, RT_INTR); xnlock_put_irqrestore(&nklock, s); return err; } removeq(intr->rqueue, &intr->rlink); #ifdef CONFIG_XENO_OPT_PERVASIVE rc = xnsynch_destroy(&intr->synch_base); #endif /* CONFIG_XENO_OPT_PERVASIVE */ if (intr->handle) xnregistry_remove(intr->handle); xeno_mark_deleted(intr); xnlock_put_irqrestore(&nklock, s); err = xnintr_destroy(&intr->intr_base); if (rc == XNSYNCH_RESCHED) /* Some task has been woken up as a result of the deletion: reschedule now. */ xnpod_schedule(); return err; }
int rt_buffer_delete(RT_BUFFER *bf) { int ret = 0, resched; spl_t s; if (xnpod_asynch_p()) return -EPERM; xnlock_get_irqsave(&nklock, s); bf = xeno_h2obj_validate(bf, XENO_BUFFER_MAGIC, RT_BUFFER); if (bf == NULL) { ret = xeno_handle_error(bf, XENO_BUFFER_MAGIC, RT_BUFFER); goto unlock_and_exit; } xnarch_free_host_mem(bf->bufmem, bf->bufsz); removeq(bf->rqueue, &bf->rlink); resched = xnsynch_destroy(&bf->isynch_base) == XNSYNCH_RESCHED; resched += xnsynch_destroy(&bf->osynch_base) == XNSYNCH_RESCHED; if (bf->handle) xnregistry_remove(bf->handle); xeno_mark_deleted(bf); if (resched) /* * Some task has been woken up as a result of the * deletion: reschedule now. */ xnpod_schedule(); unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return ret; }
int rt_event_delete(RT_EVENT *event) { int err = 0, rc; spl_t s; if (xnpod_asynch_p()) return -EPERM; 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; } removeq(event->rqueue, &event->rlink); rc = xnsynch_destroy(&event->synch_base); #ifdef CONFIG_XENO_OPT_REGISTRY if (event->handle) xnregistry_remove(event->handle); #endif /* CONFIG_XENO_OPT_REGISTRY */ xeno_mark_deleted(event); if (rc == XNSYNCH_RESCHED) /* Some task has been woken up as a result of the deletion: reschedule now. */ xnpod_schedule(); unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }
int rt_sem_delete(RT_SEM *sem) { int err = 0, rc; spl_t s; if (xnpod_asynch_p()) return -EPERM; xnlock_get_irqsave(&nklock, s); sem = xeno_h2obj_validate(sem, XENO_SEM_MAGIC, RT_SEM); if (!sem) { err = xeno_handle_error(sem, XENO_SEM_MAGIC, RT_SEM); goto unlock_and_exit; } removeq(sem->rqueue, &sem->rlink); rc = xnsynch_destroy(&sem->synch_base); if (sem->handle) xnregistry_remove(sem->handle); xeno_mark_deleted(sem); if (rc == XNSYNCH_RESCHED) /* Some task has been woken up as a result of the deletion: reschedule now. */ xnpod_schedule(); unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }