int rt_event_create(RT_EVENT *event, const char *name, unsigned long ivalue, int mode) { int err = 0; spl_t s; if (xnpod_asynch_p()) return -EPERM; xnsynch_init(&event->synch_base, mode & EV_PRIO); event->value = ivalue; event->handle = 0; /* i.e. (still) unregistered event. */ event->magic = XENO_EVENT_MAGIC; xnobject_copy_name(event->name, name); inith(&event->rlink); event->rqueue = &xeno_get_rholder()->eventq; xnlock_get_irqsave(&nklock, s); appendq(event->rqueue, &event->rlink); xnlock_put_irqrestore(&nklock, s); #ifdef CONFIG_XENO_OPT_PERVASIVE event->cpid = 0; #endif /* CONFIG_XENO_OPT_PERVASIVE */ #ifdef CONFIG_XENO_OPT_REGISTRY /* <!> Since xnregister_enter() may reschedule, only register complete objects, so that the registry cannot return handles to half-baked objects... */ if (name) { xnpnode_t *pnode = &__event_pnode; if (!*name) { /* Since this is an anonymous object (empty name on entry) from user-space, it gets registered under an unique internal name but is not exported through /proc. */ xnobject_create_name(event->name, sizeof(event->name), (void *)event); pnode = NULL; } err = xnregistry_enter(event->name, event, &event->handle, pnode); if (err) rt_event_delete(event); } #endif /* CONFIG_XENO_OPT_REGISTRY */ return err; }
int rt_intr_create(RT_INTR *intr, const char *name, unsigned irq, rt_isr_t isr, rt_iack_t iack, int mode) { int err; spl_t s; if (xnpod_asynch_p()) return -EPERM; if (name) xnobject_copy_name(intr->name, name); else /* Kernel-side "anonymous" objects (name == NULL) get unique names. * Nevertheless, they will not be exported via the registry. */ xnobject_create_name(intr->name, sizeof(intr->name), isr); xnintr_init(&intr->intr_base, intr->name, irq, isr, iack, mode); #ifdef CONFIG_XENO_OPT_PERVASIVE xnsynch_init(&intr->synch_base, XNSYNCH_PRIO, NULL); intr->pending = 0; intr->cpid = 0; intr->mode = 0; #endif /* CONFIG_XENO_OPT_PERVASIVE */ intr->magic = XENO_INTR_MAGIC; intr->handle = 0; /* i.e. (still) unregistered interrupt. */ inith(&intr->rlink); intr->rqueue = &xeno_get_rholder()->intrq; xnlock_get_irqsave(&nklock, s); appendq(intr->rqueue, &intr->rlink); xnlock_put_irqrestore(&nklock, s); err = xnintr_attach(&intr->intr_base, intr); /* * <!> Since xnregister_enter() may reschedule, only register * complete objects, so that the registry cannot return * handles to half-baked objects... */ if (!err && name) err = xnregistry_enter(intr->name, intr, &intr->handle, &__intr_pnode); if (err) rt_intr_delete(intr); return err; }
int rt_heap_create(RT_HEAP *heap, const char *name, size_t heapsize, int mode) { int err; spl_t s; if (!xnpod_root_p()) return -EPERM; if (heapsize == 0) return -EINVAL; /* Make sure we won't hit trivial argument errors when calling xnheap_init(). */ heap->csize = heapsize; /* Record this for SBA management and inquiry. */ #ifdef __KERNEL__ if (mode & H_MAPPABLE) { if (!name || !*name) return -EINVAL; #ifdef CONFIG_XENO_OPT_PERVASIVE heapsize = xnheap_rounded_size(heapsize, PAGE_SIZE); err = xnheap_init_mapped(&heap->heap_base, heapsize, ((mode & H_DMA) ? GFP_DMA : 0) | ((mode & H_NONCACHED) ? XNHEAP_GFP_NONCACHED : 0)); if (err) return err; heap->cpid = 0; #else /* !CONFIG_XENO_OPT_PERVASIVE */ return -ENOSYS; #endif /* CONFIG_XENO_OPT_PERVASIVE */ } else #endif /* __KERNEL__ */ { void *heapmem; heapsize = xnheap_rounded_size(heapsize, XNCORE_PAGE_SIZE); heapmem = xnarch_alloc_host_mem(heapsize); if (!heapmem) return -ENOMEM; err = xnheap_init(&heap->heap_base, heapmem, heapsize, XNCORE_PAGE_SIZE); if (err) { xnarch_free_host_mem(heapmem, heapsize); return err; } } xnsynch_init(&heap->synch_base, mode & (H_PRIO | H_FIFO)); heap->handle = 0; /* i.e. (still) unregistered heap. */ heap->magic = XENO_HEAP_MAGIC; heap->mode = mode; heap->sba = NULL; xnobject_copy_name(heap->name, name); inith(&heap->rlink); heap->rqueue = &xeno_get_rholder()->heapq; xnlock_get_irqsave(&nklock, s); appendq(heap->rqueue, &heap->rlink); xnlock_put_irqrestore(&nklock, s); #ifdef CONFIG_XENO_OPT_REGISTRY /* <!> Since xnregister_enter() may reschedule, only register complete objects, so that the registry cannot return handles to half-baked objects... */ if (name) { xnpnode_t *pnode = &__heap_pnode; if (!*name) { /* Since this is an anonymous object (empty name on entry) from user-space, it gets registered under an unique internal name but is not exported through /proc. */ xnobject_create_name(heap->name, sizeof(heap->name), (void *)heap); pnode = NULL; } err = xnregistry_enter(heap->name, heap, &heap->handle, pnode); if (err) rt_heap_delete(heap); } #endif /* CONFIG_XENO_OPT_REGISTRY */ return err; }