コード例 #1
0
ファイル: shm.c プロジェクト: Enextuse/RTAI
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;
	}
}
コード例 #2
0
static int rtai_shm_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
#endif
{
	switch (cmd) {
		case SHM_ALLOC: {
			TRACE_RTAI_SHM(TRACE_RTAI_EV_SHM_MALLOC, ((unsigned long *)arg)[0], cmd, current->pid);
			return rt_shm_alloc_usp(((unsigned long *)arg)[0], ((long *)arg)[1], ((long *)arg)[2]);
		}
		case SHM_FREE: {
			TRACE_RTAI_SHM(TRACE_RTAI_EV_SHM_FREE, arg, cmd, current->pid);
			return _rt_shm_free(arg, rt_get_type(arg));
		}
		case SHM_SIZE: {
			TRACE_RTAI_SHM(TRACE_RTAI_EV_SHM_GET_SIZE, arg, cmd, current->pid);
			return rt_shm_size((unsigned long *)((unsigned long *)arg)[0]);
		}
#ifdef CONFIG_RTAI_MALLOC
		case HEAP_SET: {
			rt_set_heap(((unsigned long *)arg)[0], (void *)((unsigned long *)arg)[1]);
			return 0;
		}
#endif
	}
	return 0;
}
コード例 #3
0
static RTAI_SYSCALL_MODE int rt_shm_alloc_usp(unsigned long name, int size, int suprt)
{
	TRACE_RTAI_SHM(TRACE_RTAI_EV_SHM_MALLOC, name, size, current->pid);

	if (_rt_shm_alloc(name, size, suprt)) {
		current->rtai_tskext(TSKEXT1) = (void *)name;
		return abs(rt_get_type(name));
	}
	return 0;
}
コード例 #4
0
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;
}
コード例 #5
0
static RTAI_SYSCALL_MODE int rt_shm_size(unsigned long *arg)
{
	int size;
	struct vm_area_struct *vma;

	size = abs(rt_get_type(*arg));
	for (vma = (current->mm)->mmap; vma; vma = vma->vm_next) {
		if (vma->vm_private_data == (void *)*arg && (vma->vm_end - vma->vm_start) == size) {
			*arg = vma->vm_start;
			return size;
		}
	}
	return 0;
}
コード例 #6
0
static void rtai_shm_vm_close(struct vm_area_struct *vma)
{
	_rt_shm_free((unsigned long)vma->vm_private_data, rt_get_type((unsigned long)vma->vm_private_data));
}
コード例 #7
0
RTAI_SYSCALL_MODE int rt_shm_free(unsigned long name)
{
	TRACE_RTAI_SHM(TRACE_RTAI_EV_SHM_KFREE, name, 0, 0);
	return _rt_shm_free(name, rt_get_type(name));
}
コード例 #8
0
void linux_process_termination(void)
{
	RT_TASK *task2delete, *task2unblock, *base_linux_tasks[NR_RT_CPUS];
	int cpu, slot, nr_task_lists;
	pid_t my_pid;
	struct task_struct *ltsk;
	unsigned long num;
	void *adr;

/*
 * Linux is just about to schedule *ltsk out of existence.
 * With this feature, LXRT frees the real time resources allocated
 * by the task ltsk.
*/
	ltsk = current;
	rt_get_base_linux_task(base_linux_tasks);
	nr_task_lists = rt_sched_type() == MUP_SCHED ? NR_RT_CPUS : 1;
	rt_global_cli();
	for (cpu = 0; cpu < nr_task_lists; cpu++) {

		task2delete = base_linux_tasks[cpu];
		// Try to find if RTAI was aware of this dying Linux task.
        	while ((task2delete = task2delete->next) && task2delete->lnxtsk != ltsk);
		// First let's free the registered resources.
	        for (slot = 1; slot <= MAX_SLOTS; slot++) {
	                if ((num = is_process_registered(ltsk)) > 0) {
				adr = rt_get_adr(num);
       				switch (rt_get_type(num)) {
                       	        case IS_SEM:
					rt_printk("LXRT Informed releases SEM %p\n", adr);
					rt_sem_delete(adr);
					rt_free(adr);
					break;
                                case IS_MBX:
					rt_printk("LXRT Informed releases MBX %p\n", adr);
                                        rt_mbx_delete(adr);
                                        rt_free(adr);
                                        break;
                                case IS_PRX:
rt_printk("LXRT Informed releases PRX %p\n", adr);
                                        rt_Proxy_detach(rttask2pid(adr));
                                        break;
// to do:                       case IS_SHMEM:
				}
				rt_drg_on_adr(adr); 
                        }
                }

        // Synchronous IPC pid may need to be released
		if ((my_pid = rttask2pid(task2delete))) {
			rt_printk("Release vc %04X\n", my_pid);
			rt_vc_release(my_pid);
                }

	        if (!task2delete) {
			continue; // The user deleted the task but forgot to delete the resources.
		}

        // Other RTAI tasks may be SEND, RPC or RETURN blocked on task2delete.
Loop:
		task2unblock = base_linux_tasks[cpu];
		while ((task2unblock = task2unblock->next)) {
                	if (!(task2unblock->state & (SEND | RPC | RETURN))) {
				continue;
			} else if (task2unblock->msg_queue.task == task2delete) {
                        	task2unblock->state &= ~(SEND | RPC | RETURN | DELAYED);
	                        LXRT_RESUME(task2unblock);
				rt_global_cli();
				goto Loop;
                        }
                }

        // To do: other RTAI tasks may want to be informed as well.

	        // Ok, let's delete the task.
		if (!rt_task_delete(task2delete)) {
rt_printk("LXRT Informed releases RT %p, lnxpid %d (%p), name %s.\n", task2delete, ltsk->pid, ltsk, ltsk->comm);
			rt_free(task2delete->msg_buf[0]);
			rt_free(task2delete);
			rt_drg_on_adr(task2delete);
			break;
                }
        }
	rt_global_sti();
}