📄 sys_lxrt.c
字号:
case LXRT_TASK_INIT: { struct arg { int name, prio, stack_size, max_msg_size, cpus_allowed; }; return (unsigned long) __task_init(arg0.name, larg->prio, larg->stack_size, larg->max_msg_size, larg->cpus_allowed); } case LXRT_TASK_DELETE: { return __task_delete(arg0.rt_task); } case LXRT_SEM_INIT: { if (rt_get_adr(arg0.name)) { return 0; } if ((arg0.sem = rt_malloc(sizeof(SEM)))) { struct arg { int name; int cnt; int typ; }; lxrt_typed_sem_init(arg0.sem, larg->cnt, larg->typ); if (rt_register(larg->name, arg0.sem, IS_SEM, current)) { return arg0.name; } else { rt_free(arg0.sem); } } return 0; } case LXRT_SEM_DELETE: { if (lxrt_sem_delete(arg0.sem)) { return -EFAULT; } rt_free(arg0.sem); return rt_drg_on_adr(arg0.sem); } case LXRT_MBX_INIT: { if (rt_get_adr(arg0.name)) { return 0; } if ((arg0.mbx = rt_malloc(sizeof(MBX)))) { struct arg { int name; int size; int qtype; }; if (lxrt_typed_mbx_init(arg0.mbx, larg->size, larg->qtype) < 0) { rt_free(arg0.mbx); return 0; } if (rt_register(larg->name, arg0.mbx, IS_MBX, current)) { return arg0.name; } else { rt_free(arg0.mbx); } } return 0; } case LXRT_MBX_DELETE: { if (lxrt_mbx_delete(arg0.mbx)) { return -EFAULT; } rt_free(arg0.mbx); return rt_drg_on_adr(arg0.mbx); } case LXRT_RWL_INIT: { if (rt_get_adr(arg0.name)) { return 0; } if ((arg0.rwl = rt_malloc(sizeof(RWL)))) { struct arg { int name; }; lxrt_rwl_init(arg0.rwl); if (rt_register(larg->name, arg0.rwl, IS_SEM, current)) { return arg0.name; } else { rt_free(arg0.rwl); } } return 0; } case LXRT_RWL_DELETE: { if (lxrt_rwl_delete(arg0.rwl)) { return -EFAULT; } rt_free(arg0.rwl); return rt_drg_on_adr(arg0.rwl); } case LXRT_SPL_INIT: { if (rt_get_adr(arg0.name)) { return 0; } if ((arg0.spl = rt_malloc(sizeof(SPL)))) { struct arg { int name; }; lxrt_spl_init(arg0.spl); if (rt_register(larg->name, arg0.spl, IS_SEM, current)) { return arg0.name; } else { rt_free(arg0.spl); } } return 0; } case LXRT_SPL_DELETE: { if (lxrt_spl_delete(arg0.spl)) { return -EFAULT; } rt_free(arg0.spl); return rt_drg_on_adr(arg0.spl); } case MAKE_HARD_RT: { if (!(task = current->this_rt_task[0]) || (int)task->is_hard > 0) { return 0; } steal_from_linux(task); return 0; } case MAKE_SOFT_RT: { if (!(task = current->this_rt_task[0]) || (int)task->is_hard <= 0) { return 0; } if ((int)task->is_hard > 1) { task->is_hard = 0; } else { give_back_to_linux(task); } return 0; } case PRINT_TO_SCREEN: { struct arg { char *display; int nch; }; return rtai_print_to_screen("%s", larg->display); } case PRINTK: { struct arg { char *display; int nch; }; return rt_printk("%s", larg->display); } case NONROOT_HRT: { current->cap_effective |= ((1 << CAP_IPC_LOCK) | (1 << CAP_SYS_RAWIO) | (1 << CAP_SYS_NICE)); return 0; } case RT_BUDDY: { return current->this_rt_task[0] && current->this_rt_task[1] == current ? (unsigned long)(current->this_rt_task[0]) : 0; } case HRT_USE_FPU: { struct arg { RT_TASK *task; int use_fpu; }; if(!larg->use_fpu) { ((larg->task)->lnxtsk)->used_math = 0; set_tsk_used_fpu(((larg->task)->lnxtsk)); } else { init_xfpu(); ((larg->task)->lnxtsk)->used_math = 1; set_tsk_used_fpu(((larg->task)->lnxtsk)); } return 0; } case GET_USP_FLAGS: { return arg0.rt_task->usp_flags; } case SET_USP_FLAGS: { struct arg { RT_TASK *task; unsigned long flags; }; arg0.rt_task->usp_flags = larg->flags; arg0.rt_task->force_soft = ((int)arg0.rt_task->is_hard > 0) && (larg->flags & arg0.rt_task->usp_flags_mask & FORCE_SOFT); return 0; } case GET_USP_FLG_MSK: { return arg0.rt_task->usp_flags_mask; } case SET_USP_FLG_MSK: { (task = current->this_rt_task[0])->usp_flags_mask = arg0.name; task->force_soft = ((int)task->is_hard > 0) && (task->usp_flags & arg0.name & FORCE_SOFT); return 0; }#ifndef FORCE_TASK_SOFT#define FORCE_TASK_SOFT 1023#endif case FORCE_TASK_SOFT: { struct task_struct *ltsk; if ((ltsk = find_task_by_pid(arg0.name))) { if ((arg0.rt_task = ltsk->this_rt_task[0])) { arg0.rt_task->force_soft = ((int)arg0.rt_task->is_hard > 0) && FORCE_SOFT; return (unsigned long)arg0.rt_task; } } return 0; } case IS_HARD: { return (int)arg0.rt_task->is_hard > 0; } case GET_EXECTIME: { struct arg { RT_TASK *task; RTIME *exectime; }; if ((larg->task)->exectime[0] && (larg->task)->exectime[1]) { larg->exectime[0] = (larg->task)->exectime[0]; larg->exectime[1] = (larg->task)->exectime[1]; larg->exectime[2] = rdtsc(); } return 0; } case GET_TIMEORIG: { struct arg { RTIME *time_orig; }; rt_gettimeorig(larg->time_orig); return 0; } default: rt_printk("RTAI/LXRT: Unknown srq #%d\n", srq); return -ENOSYS; } return 0;}long long rtai_lxrt_invoke (unsigned int lxsrq, void *arg){ long long retval;#ifdef CONFIG_RTAI_TRACE trace_true_lxrt_rtai_syscall_entry();#endif /* CONFIG_RTAI_TRACE */ retval = handle_lxrt_request(lxsrq,arg);#ifdef CONFIG_RTAI_TRACE trace_true_lxrt_rtai_syscall_exit();#endif /* CONFIG_RTAI_TRACE */ return retval;}int rtai_lxrt_fastpath (void){ int lpath; lpath = test_bit(hard_cpu_id(),&rtai_cpu_lxrt) || test_bit(hard_cpu_id(),&rtai_cpu_realtime); /* Returns zero if we may process pending Linux work on our return path (i.e. long return path through reschedule), or non-zero if we may not (fast return path). In the former case, also unstall the Linux stage into the Adeos pipeline so that interrupts can flow anew. */ if (!lpath) rtai_linux_sti(); return lpath;}int set_rt_fun_ext_index(struct rt_fun_entry *fun, int idx){ if (idx > 0 && idx < MAX_FUN_EXT && !rt_fun_ext[idx]) { rt_fun_ext[idx] = fun; return 0; } return -EACCES;}void reset_rt_fun_ext_index( struct rt_fun_entry *fun, int idx){ if (idx > 0 && idx < MAX_FUN_EXT && rt_fun_ext[idx] == fun) { rt_fun_ext[idx] = 0; }}static void linux_process_termination(void){ unsigned long num; void *adr; int type; char name[8]; RT_TASK *task2delete;/* * Linux is just about to schedule current out of existence. With this feature, * LXRT frees the real time resources allocated to it.*/ while ((num = is_process_registered(current))) { rt_global_cli(); adr = rt_get_adr(num); type = rt_get_type(num); rt_drg_on_adr(adr); rt_global_sti(); num2nam(num, name); switch (type) { case IS_SEM: rt_printk("LXRT releases SEM %s\n", name); lxrt_sem_delete(adr); rt_free(adr); break; case IS_RWL: rt_printk("LXRT releases RWL %s\n", name); lxrt_rwl_delete(adr); rt_free(adr); break; case IS_SPL: rt_printk("LXRT releases SPL %s\n", name); lxrt_spl_delete(adr); rt_free(adr); break; case IS_MBX: rt_printk("LXRT releases MBX %s\n", name); lxrt_mbx_delete(adr); rt_free(adr); break; case IS_PRX: num = rttask2pid(adr); rt_printk("LXRT releases PROXY PID %lu\n", num); lxrt_Proxy_detach(num); break; case IS_TASK: rt_printk("LXRT deregisters task %s\n", name); break; } } if ((task2delete = current->this_rt_task[0])) { if (!clr_rtext(task2delete)) { rt_drg_on_adr(task2delete); rt_printk("LXRT releases PID %d (ID: %s).\n", current->pid, current->comm); rt_free(task2delete->msg_buf[0]); rt_free(task2delete); current->this_rt_task[0] = current->this_rt_task[1] = 0; } }}int lxrt_init_archdep (void){ RT_TASK *rt_linux_tasks[NR_RT_CPUS]; sidt = rt_set_full_intr_vect(RTAI_LXRT_VECTOR, 15, 3, (void *)&RTAI_LXRT_HANDLER); if (set_rtai_callback(linux_process_termination)) { printk("Could not setup rtai_callback\n"); return -ENODEV; } rt_fun_ext[0] = rt_fun_lxrt; rt_get_base_linux_task(rt_linux_tasks); rt_linux_tasks[0]->task_trap_handler[0] = (void *)set_rt_fun_ext_index; rt_linux_tasks[0]->task_trap_handler[1] = (void *)reset_rt_fun_ext_index; return 0;}void lxrt_exit_archdep (void){ rt_reset_full_intr_vect(RTAI_LXRT_VECTOR, sidt); remove_rtai_callback(linux_process_termination);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -