static inline void *_rt_shm_alloc(unsigned long name, int size, int suprt) { void *adr; // suprt = USE_GFP_ATOMIC; // to force some testing if (!(adr = rt_get_adr_cnt(name)) && size > 0 && suprt >= 0 && RT_SHM_OP_PERM()) { size = ((size - 1) & PAGE_MASK) + PAGE_SIZE; if ((adr = suprt ? rkmalloc(&size, SUPRT[suprt]) : rvmalloc(size))) { if (!rt_register(name, adr, suprt ? -size : size, 0)) { if (suprt) { rkfree(adr, size); } else { rvfree(adr, size); } return 0; } memset(ALIGN2PAGE(adr), 0, size); } } return ALIGN2PAGE(adr); }
static RTAI_SYSCALL_MODE void rt_set_heap(unsigned long name, void *adr) { void *heap, *hptr; int size; RT_TASK *task; heap = rt_get_adr(name); hptr = ALIGN2PAGE(heap); size = ((abs(rt_get_type(name)) - sizeof(rtheap_t) - (hptr - heap)) & PAGE_MASK); heap = hptr + size; if (!atomic_cmpxchg((atomic_t *)hptr, 0, name)) { rtheap_init(heap, hptr, size, PAGE_SIZE, 0); } RTAI_TASK(return); if (name == GLOBAL_HEAP_ID) { task->heap[GLOBAL].heap = &rtai_global_heap; task->heap[GLOBAL].kadr = rtai_global_heap_adr; task->heap[GLOBAL].uadr = adr; } else { task->heap[SPECIFIC].heap = heap; task->heap[SPECIFIC].kadr = hptr; task->heap[SPECIFIC].uadr = adr; } }
static int rtai_shm_f_mmap(struct file *file, struct vm_area_struct *vma) { unsigned long name; int size; if (!vma->vm_ops) { vma->vm_ops = &rtai_shm_vm_ops; vma->vm_flags |= VM_LOCKED; name = (unsigned long)(vma->vm_private_data = current->rtai_tskext(TSKEXT1)); current->rtai_tskext(TSKEXT1) = current->rtai_tskext(TSKEXT0) ? current : NULL; return (size = rt_get_type(name)) < 0 ? rkmmap(ALIGN2PAGE(rt_get_adr(name)), -size, vma) : rvmmap(rt_get_adr(name), size, vma); } return -EFAULT; }