📄 sched_mup.c
字号:
rt_printk("Default Trap Handler: vector %d: Suspend RT task %p\n", vec,rt_current); rt_task_suspend(rt_current); rt_task_delete(rt_current); // In case the suspend does not work ? return 1;}static int OneShot = ONE_SHOT;MODULE_PARM(OneShot, "i");static int PreemptAlways = PREEMPT_ALWAYS;MODULE_PARM(PreemptAlways, "i");static int LinuxFpu = LINUX_FPU;MODULE_PARM(LinuxFpu, "i");static int Latency = TIMER_LATENCY;MODULE_PARM(Latency, "i");static int SetupTimeTIMER = TIMER_SETUP_TIME;MODULE_PARM(SetupTimeTIMER, "i");static void frstk_srq_handler(void){ while (frstk_srq.out != frstk_srq.in) { sched_free(frstk_srq.mp[frstk_srq.out]); frstk_srq.out = (frstk_srq.out + 1) & (MAX_FRESTK_SRQ - 1); }}static void init_sched_entries(void);/* ++++++++++++++++++++++++++ TIME CONVERSIONS +++++++++++++++++++++++++++++ */RTIME count2nano(RTIME counts){ int sign; if (counts > 0) { sign = 1; } else { sign = 0; counts = - counts; } counts = oneshot_timer_cpuid ? llimd(counts, 1000000000, tuned.cpu_freq): llimd(counts, 1000000000, TIMER_FREQ); return sign ? counts : - counts;}RTIME nano2count(RTIME ns){ int sign; if (ns > 0) { sign = 1; } else { sign = 0; ns = - ns; } ns = oneshot_timer_cpuid ? llimd(ns, tuned.cpu_freq, 1000000000) : llimd(ns, TIMER_FREQ, 1000000000); return sign ? ns : - ns;}RTIME count2nano_cpuid(RTIME counts, unsigned int cpuid){ int sign; if (counts > 0) { sign = 1; } else { sign = 0; counts = - counts; } counts = oneshot_timer ? llimd(counts, 1000000000, tuned.cpu_freq): llimd(counts, 1000000000, TIMER_FREQ); return sign ? counts : - counts;}RTIME nano2count_cpuid(RTIME ns, unsigned int cpuid){ int sign; if (ns > 0) { sign = 1; } else { sign = 0; ns = - ns; } ns = oneshot_timer ? llimd(ns, tuned.cpu_freq, 1000000000) : llimd(ns, TIMER_FREQ, 1000000000); return sign ? ns : - ns;}/* +++++++++++++++++++++++++++++++ TIMINGS ++++++++++++++++++++++++++++++++++ */RTIME rt_get_time(void){ int cpuid; return rt_smp_oneshot_timer[cpuid = hard_cpu_id()] ? rdtsc() : rt_smp_times[cpuid].tick_time;}RTIME rt_get_time_cpuid(unsigned int cpuid){ return oneshot_timer ? rdtsc(): rt_times.tick_time;}RTIME rt_get_time_ns(void){ int cpuid = hard_cpu_id(); return oneshot_timer ? llimd(rdtsc(), 1000000000, tuned.cpu_freq) : llimd(rt_times.tick_time, 1000000000, TIMER_FREQ);}RTIME rt_get_time_ns_cpuid(unsigned int cpuid){ return oneshot_timer ? llimd(rdtsc(), 1000000000, tuned.cpu_freq) : llimd(rt_times.tick_time, 1000000000, TIMER_FREQ);}RTIME rt_get_cpu_time_ns(void){ return llimd(rdtsc(), 1000000000, tuned.cpu_freq);}/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */RT_TASK *rt_get_base_linux_task(RT_TASK **base_linux_tasks){ int cpuid; for (cpuid = 0; cpuid < smp_num_cpus; cpuid++) { base_linux_tasks[cpuid] = rt_smp_linux_task + cpuid; } return rt_smp_linux_task;}RT_TASK *rt_alloc_dynamic_task(void){#ifdef CONFIG_RTAI_MALLOC return rt_malloc(sizeof(RT_TASK)); // For VC's, proxies and C++ support.#else return NULL;#endif}RT_TASK **rt_register_watchdog(RT_TASK *wd, int cpuid){ RT_TASK *task; if (wdog_task[cpuid]) return (RT_TASK**) -EBUSY; task = &rt_linux_task; while ((task = task->next)) { if (task != wd && task->priority == RT_SCHED_HIGHEST_PRIORITY) { return (RT_TASK**) -EBUSY; } } wdog_task[cpuid] = wd; return (RT_TASK**) 0;}void rt_deregister_watchdog(RT_TASK *wd, int cpuid){ if (wdog_task[cpuid] != wd) return; wdog_task[cpuid] = NULL;}/* ++++++++++++++ SCHEDULER ENTRIES AND RELATED INITIALISATION ++++++++++++++ */#if CONFIG_RTAI_NETRPC#include <rtai_registry.h>static struct rt_native_fun_entry rt_sched_entries[] = { { { 0, rt_named_task_init }, NAMED_TASK_INIT }, { { 0, rt_named_task_init_cpuid }, NAMED_TASK_INIT_CPUID }, { { 0, rt_named_task_delete }, NAMED_TASK_DELETE }, { { 1, rt_task_yield }, YIELD }, { { 1, rt_task_suspend }, SUSPEND }, { { 1, rt_task_resume }, RESUME }, { { 1, rt_task_make_periodic }, MAKE_PERIODIC }, { { 1, rt_task_wait_period }, WAIT_PERIOD }, { { 1, rt_sleep }, SLEEP }, { { 1, rt_sleep_until }, SLEEP_UNTIL }, { { 0, start_rt_timer }, START_TIMER }, { { 0, stop_rt_timer }, STOP_TIMER }, { { 0, rt_get_time }, GET_TIME }, { { 0, count2nano }, COUNT2NANO }, { { 0, nano2count }, NANO2COUNT }, { { 0, rt_busy_sleep }, BUSY_SLEEP }, { { 0, rt_set_periodic_mode }, SET_PERIODIC_MODE }, { { 0, rt_set_oneshot_mode }, SET_ONESHOT_MODE }, { { 0, rt_task_signal_handler }, SIGNAL_HANDLER }, { { 0, rt_task_use_fpu }, TASK_USE_FPU }, { { 0, rt_linux_use_fpu }, LINUX_USE_FPU }, { { 0, rt_preempt_always }, PREEMPT_ALWAYS_GEN }, { { 0, rt_get_time_ns }, GET_TIME_NS }, { { 0, rt_get_cpu_time_ns }, GET_CPU_TIME_NS }, { { 0, rt_set_runnable_on_cpus }, SET_RUNNABLE_ON_CPUS }, { { 0, rt_set_runnable_on_cpuid }, SET_RUNNABLE_ON_CPUID }, { { 0, rt_get_timer_cpu }, GET_TIMER_CPU }, { { 0, start_rt_apic_timers }, START_RT_APIC_TIMERS }, { { 0, rt_preempt_always_cpuid }, PREEMPT_ALWAYS_CPUID }, { { 0, count2nano_cpuid }, COUNT2NANO_CPUID }, { { 0, nano2count_cpuid }, NANO2COUNT_CPUID }, { { 0, rt_get_time_cpuid }, GET_TIME_CPUID }, { { 0, rt_get_time_ns_cpuid }, GET_TIME_NS_CPUID }, { { 1, rt_task_make_periodic_relative_ns }, MAKE_PERIODIC_NS }, { { 0, rt_set_sched_policy }, SET_SCHED_POLICY }, { { 1, rt_task_set_resume_end_times }, SET_RESUME_END }, { { 0, rt_spv_RMS }, SPV_RMS }, { { 0, rt_task_wakeup_sleeping }, WAKEUP_SLEEPING }, { { 1, rt_change_prio }, CHANGE_TASK_PRIO }, { { 0, rt_set_resume_time }, SET_RESUME_TIME }, { { 0, rt_set_period }, SET_PERIOD }, { { 0, rt_is_hard_timer_running }, HARD_TIMER_RUNNING }, { { 0, rt_get_adr }, GET_ADR }, { { 0, rt_get_name }, GET_NAME }, { { 0, 0 }, 000 }};static void nihil(void) { };struct rt_fun_entry rt_fun_lxrt[MAX_LXRT_FUN];void reset_rt_fun_entries(struct rt_native_fun_entry *entry){ while (entry->fun.fun) { if (entry->index >= MAX_LXRT_FUN) { rt_printk("*** RESET ENTRY %d FOR USER SPACE CALLS EXCEEDS ALLOWD TABLE SIZE %d, NOT USED ***\n", entry->index, MAX_LXRT_FUN); } else { rt_fun_lxrt[entry->index] = (struct rt_fun_entry){ 1, nihil }; } entry++; }}int set_rt_fun_entries(struct rt_native_fun_entry *entry){ int error; error = 0; while (entry->fun.fun) { if (rt_fun_lxrt[entry->index].fun != nihil) { rt_printk("*** SUSPICIOUS ENTRY ASSIGNEMENT FOR USER SPACE CALL AT %d, DUPLICATED INDEX OR REPEATED INITIALIZATION ***\n", entry->index); error = -1; } else if (entry->index >= MAX_LXRT_FUN) { rt_printk("*** ASSIGNEMENT ENTRY %d FOR USER SPACE CALLS EXCEEDS ALLOWED TABLE SIZE %d, NOT USED ***\n", entry->index, MAX_LXRT_FUN); error = -1; } else { rt_fun_lxrt[entry->index] = entry->fun; } entry++; } if (error) { reset_rt_fun_entries(entry); } return 0;}static void init_sched_entries(void){ int i; for (i = 0; i < MAX_LXRT_FUN; i++) { rt_fun_lxrt[i] = (struct rt_fun_entry) { 1, nihil }; } set_rt_fun_entries(rt_sched_entries);}#elsevoid reset_rt_fun_entries(struct rt_native_fun_entry *entry){}int set_rt_fun_entries(struct rt_native_fun_entry *entry){ return 0;}static void init_sched_entries(void){}#endifint set_rt_fun_ext_index(struct rt_fun_entry *fun, int idx){ return -EACCES;}void reset_rt_fun_ext_index( struct rt_fun_entry *fun, int idx){ return;}/* ++++++++++++++++++++++++++ SCHEDULER PROC FILE +++++++++++++++++++++++++++ */#ifdef CONFIG_PROC_FS/* ----------------------< proc filesystem section >----------------------*/static int rtai_read_sched(char *page, char **start, off_t off, int count, int *eof, void *data){ PROC_PRINT_VARS; int cpuid, i = 1; unsigned long t; RT_TASK *task; PROC_PRINT("\nRTAI MUP Real Time Task Scheduler.\n\n"); PROC_PRINT(" Calibrated CPU Frequency: %lu Hz\n", tuned.cpu_freq); PROC_PRINT(" Calibrated 8254 interrupt to scheduler latency: %d ns\n", imuldiv(tuned.latency - tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq)); PROC_PRINT(" Calibrated one shot setup time: %d ns\n\n", imuldiv(tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq)); PROC_PRINT("Number of RT CPUs in system: %d\n\n", NR_RT_CPUS); PROC_PRINT("Priority Period(ns) FPU Sig State CPU Task RT_TASK * TIME\n"); PROC_PRINT("------------------------------------------------------------------\n"); for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) { task = &rt_linux_task;/** Display all the active RT tasks and their state.** Note: As a temporary hack the tasks are given an id which is* the order they appear in the task list, needs fixing!*/ while ((task = task->next)) {/** The display for the task period is set to an integer (%d) as 64 bit* numbers are not currently handled correctly by the kernel routines.* Hence the period display will be wrong for time periods > ~4 secs.*/ if ((!task->lnxtsk || task->is_hard) && task->exectime[1]) { t = 1000UL*(unsigned long)llimd(task->exectime[0], 10, tuned.cpu_freq)/(unsigned long)llimd(rdtsc() - task->exectime[1], 10, tuned.cpu_freq); } else { t = 0; } PROC_PRINT("%-9d %-11lu %-4s %-4s 0x%-4x %-4d %-4d %p %-lu\n", task->priority, (unsigned long)count2nano_cpuid(task->period, task->runnable_on_cpus), task->uses_fpu ? "Yes" : "No", task->signal ? "Yes" : "No", task->state, cpuid, i, task, t); i++; } /* End while loop - display all RT tasks on a CPU. */ PROC_PRINT("TIMED\n"); task = &rt_linux_task; while ((task = task->tnext) != &rt_linux_task) { PROC_PRINT("> %p ", task); } PROC_PRINT("\nREADY\n"); task = &rt_linux_task; while ((task = task->rnext) != &rt_linux_task) { PROC_PRINT("> %p ", task); } } /* End for loop - display RT tasks on all CPUs. */ PROC_PRINT_DONE;} /* End function - rtai_read_sched */static int rtai_proc_sched_register(void) { struct proc_dir_entry *proc_sched_ent; proc_sched_ent = create_proc_entry("scheduler", S_IFREG|S_IRUGO|S_IWUSR, rtai_proc_root); if (!proc_sched_ent) { printk("Unable to initialize /proc/rtai/scheduler\n"); return(-1); } proc_sched_ent->read_proc = rtai_read_sched; return(0);} /* End function - rtai_proc_sched_register */static void rtai_proc_sched_unregister(void) { remove_proc_entry("scheduler", rtai_proc_root);} /* End function - rtai_proc_sched_unregister *//* ------------------< end of proc filesystem section >------------------*/#endif /* CONFIG_PROC_FS */int __rtai_mup_init(void){ int cpuid; sched_mem_init(); init_sched_entries(); for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) { rt_linux_task.uses_fpu = LinuxFpu != 0 ? 1 : 0; rt_linux_task.magic = 0; rt_linux_task.policy = 0; rt_linux_task.runnable_on_cpus = cpuid; rt_linux_task.state = RT_SCHED_READY; rt_linux_task.msg_queue.prev = &(rt_linux_task.msg_queue); rt_linux_task.msg_queue.next = &(rt_linux_task.msg_queue); rt_linux_task.msg_queue.task = &rt_linux_task; rt_linux_task.msg = 0; rt_linux_task.ret_queue.prev = &(rt_linux_task.ret_queue); rt_linux_task.ret_queue.next = &(rt_linux_task.ret_queue); rt_linux_task.ret_queue.task = NOTHING; rt_linux_task.priority = RT_SCHED_LINUX_PRIORITY; rt_linux_task.base_priority = RT_SCHED_LINUX_PRIORITY; rt_linux_task.signal = 0; rt_linux_task.prev = &rt_linux_task; rt_linux_task.resume_time = RT_TIME_END; rt_linux_task.tprev = rt_linux_task.tnext = rt_linux_task.rprev = rt_linux_task.rnext = &rt_linux_task; rt_linux_task.next = 0; rt_smp_current[cpuid] = &rt_linux_task; rt_smp_fpu_task[cpuid] = &rt_linux_task; oneshot_timer = OneShot ? 1 : 0; oneshot_running = 0; preempt_always = PreemptAlways ? 1 : 0; } tuned.latency = imuldiv(Latency, tuned.cpu_freq, 1000000000); tuned.setup_time_TIMER_CPUNIT = imuldiv( SetupTimeTIMER, tuned.cpu_freq, 1000000000); tuned.setup_time_TIMER_UNIT = imuldiv( SetupTimeTIMER, TIMER_FREQ, 1000000000); tuned.timers_tol[0] = 0;#ifdef CONFIG_PROC_FS rtai_proc_sched_register();#endif printk("\n***** STARTING THE MUP REAL TIME SCHEDULER WITH %sLINUX FP SUPPORT *****", LinuxFpu ? "": "NO "); printk("\n***<> LINUX TICK AT %d (HZ) <>***", HZ); printk("\n***<> CALIBRATED CPU FREQUENCY %lu (HZ) <>***", tuned.cpu_freq); printk("\n***<> CALIBRATED APIC_INTERRUPT-TO-SCHEDULER LATENCY %d (ns) <>***", imuldiv(tuned.latency - tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq)); printk("\n***<> CALIBRATED ONE SHOT APIC SETUP TIME %d (ns) <>***", imuldiv(tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq)); printk("\n***<> COMPILER: %s***\n\n", CONFIG_RTAI_COMPILER); rt_mount_rtai();// 0x7dd763ad == nam2num("MEMSRQ"). if ((frstk_srq.srq = rt_request_srq(0x7dd763ad, frstk_srq_handler, 0)) < 0) { printk("MEM SRQ: no sysrq available.\n"); return frstk_srq.srq; } frstk_srq.in = frstk_srq.out = 0; rt_request_sched_ipi(); rt_set_rtai_trap_handler(rt_trap_handler);#ifdef CONFIG_RTAI_SCHED_ISR_LOCK rt_set_ihook(&rtai_handle_isched_lock);#endif /* CONFIG_RTAI_SCHED_ISR_LOCK */ return rtai_init_features(); /* see rtai_schedcore.h */}extern void krtai_objects_release(void);void __rtai_mup_exit(void){ int cpuid; rt_set_rtai_trap_handler(NULL); stop_rt_timer(); for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) { while (rt_linux_task.next) { rt_task_delete(rt_linux_task.next); } } krtai_objects_release(); rtai_cleanup_features();#ifdef CONFIG_PROC_FS rtai_proc_sched_unregister();#endif while (frstk_srq.out != frstk_srq.in); if (rt_free_srq(frstk_srq.srq) < 0) { printk("MEM SRQ: frstk_srq %d illegal or already free.\n", frstk_srq.srq); } rt_free_sched_ipi(); sched_mem_end();#ifdef CONFIG_RTAI_SCHED_ISR_LOCK rt_set_ihook(NULL);#endif /* CONFIG_RTAI_SCHED_ISR_LOCK */ rt_umount_rtai(); printk("\n***** THE MUP REAL TIME SCHEDULER HAS BEEN REMOVED *****\n\n");}module_init(__rtai_mup_init);module_exit(__rtai_mup_exit);/* +++++++++++++++++++++++++++++ SCHEDULER END ++++++++++++++++++++++++++++ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -