?? psc.c
字號(hào):
pthread_setfp_np(irq_threads[action.sa_signal].ptid, 1);#endif /* CONFIG_RTL_FP_SUPPORT */ rtl_hard_restore_flags(flags); } /* is it a timer? */ else if (action.sa_signal < RTLINUX_SIGUSR0) { /* if we're doing a DFL/IGN we need to kill the task * and if we're changing the handler we need to kill it */ if ( (tt = find_timer_thread(current->pid, action.sa_signal))) { pthread_kill(tt->ptid, RTL_SIGNAL_CANCEL); /* This is bad when this thread does bad things. * -Nathan * pthread_join( tt->ptid, NULL ); */ remove_timer_thread(tt); } /* check if we're free-ing this timer signal */ if ((action.sa_handler == RTLINUX_SIG_DFL) || (action.sa_handler == RTLINUX_SIG_IGN)) goto out; if (! (tt = kmalloc(sizeof(struct timer_thread), GFP_KERNEL))) return -ENOMEM; tt->pid = current->pid; tt->action = action; pthread_create(&tt->ptid, NULL, timer_handler, (void *) tt);#ifdef CONFIG_RTL_FP_SUPPORT pthread_setfp_np(tt->ptid, 1);#endif /* CONFIG_RTL_FP_SUPPORT */ insert_timer_thread(tt); } /* is it a signal for general use? */ else if (action.sa_signal <= RTLINUX_SIGUSR3) { /* * We do things here a lot like we do with timers so we can * use the same housekeeping functions. * -- Cort */ /* if we're doing a DFL/IGN we need to remove the timer * and if we're changing the handler we need to kill it */ if ( (tt = find_timer_thread(current->pid, action.sa_signal))) remove_timer_thread(tt); /* check if we're free-ing this timer signal */ if ((action.sa_handler == RTLINUX_SIG_DFL) || (action.sa_handler == RTLINUX_SIG_IGN)) goto out; if (! (tt = kmalloc(sizeof(struct timer_thread), GFP_KERNEL))) return -ENOMEM; tt->pid = current->pid; tt->action = action;#ifdef CONFIG_RTL_FP_SUPPORT/* pthread_setfp_np(tt->ptid, 1); *//* TODO */#endif /* CONFIG_RTL_FP_SUPPORT */ insert_timer_thread(tt); } else { return -EINVAL; } out: return count;}/* This is roughly modeled after the sigaction_write function above. * -Nathan */static int sigprocmask_write(struct file *file, const char *buffer, unsigned long count, void *data){ unsigned long flags; rtlinux_sigset_t our_procmask; struct timer_thread *our_thread; int i; /* make sure we got everything we should have */ if (count != sizeof(our_procmask)) return (-EINVAL); /* get the bitmask from the syscall */ if (copy_from_user((void *) &our_procmask, (void *) buffer, sizeof(rtlinux_sigset_t))) return (-EFAULT); /* should we disable interrupts here? Yeah, probably. */ rtl_hard_savef_and_cli(flags); /* go through all the irq threads and find the ones specific to this * pid and set their signal action masks */ for (i = 0; i < NR_IRQS; i++) { if (irq_threads[i].pid == current->pid) memcpy(&(irq_threads[i].action.sa_mask), &our_procmask, sizeof(rtlinux_sigset_t)); } /* go through all the timer threads and find the ones specific to * this pid and set their signal action masks */ for (our_thread = timer_threads; our_thread; our_thread = our_thread->next) { if (our_thread->pid == current->pid) { memcpy(&(our_thread->action.sa_mask), &our_procmask, sizeof(rtlinux_sigset_t)); our_thread->pending = 0; /* for each of the timer signals */ for (i = NR_IRQS; i < RTLINUX_SIGMAX; i++) { /* if this signal is our mask, pend it */ our_thread->pending |= rtlinux_sigismember(&our_procmask, i); } } } /* . . . and re-enable interrupts here. -Nathan */ rtl_hard_restore_flags(flags); /* go through all the interrupts and make sure we disable the ones we * don't want */ for (i = 0; i < NR_IRQS; i++) { if ((rtlinux_sigismember(&our_procmask, i)) == 1) { rtl_hard_disable_irq(i); } /* whilst enabling the ones we do want */ else rtl_hard_enable_irq(i); } return (count);}int gethrtime_read(char *page, char **start, off_t off, int count, int *eof, void *data){ int size = 0; size = sprintf(page, "%lu", (unsigned long) gethrtime); return (size);}int rtf_put_read(char *page, char **start, off_t off, int count, int *eof, void *data){ int size = 0; size = sprintf(page, "%lu", (unsigned long) rtf_put); return (size);}int rtf_get_read(char *page, char **start, off_t off, int count, int *eof, void *data){ int size = 0; size = sprintf(page, "%lu", (unsigned long) rtf_get); return (size);}int rtf_destroy_read(char *page, char **start, off_t off, int count, int *eof, void *data){ int size = 0; size = sprintf(page, "%lu", __NR_rtf_destroy); return (size);}int rtf_create_read(char *page, char **start, off_t off, int count, int *eof, void *data){ int size = 0; size = sprintf(page, "%lu", __NR_rtf_create); return (size);}/* grab a free syscall entry and own it. -Nathan */typedef int (*rtlinux_syscall_t) (int, ...);int hook_free_syscall(rtlinux_syscall_t rtlinux_syscall){ int __NR_rtlinux = 254; sys_ni_syscall = sys_call_table[255]; while ((sys_call_table[__NR_rtlinux] != (unsigned long) sys_ni_syscall)) __NR_rtlinux--; sys_call_table[__NR_rtlinux] = (unsigned long) rtlinux_syscall; return __NR_rtlinux;}int rtf_create_wrapper(unsigned int fifo, int size){ rtl_irqstate_t flags; int ret = 0; rtl_hard_savef_and_cli(flags); ret = rtf_create(fifo, size); rtl_hard_restore_flags(flags); return ret;}int rtf_destroy_wrapper(unsigned int minor){ rtl_irqstate_t flags; int ret = 0; rtl_hard_savef_and_cli(flags); ret = rtf_destroy(minor); rtl_hard_restore_flags(flags); return ret;}int init_module(void){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) proc_rtlinux = proc_mkdir("rtlinux", 0);#else proc_rtlinux = create_proc_entry("rtlinux", S_IFDIR, 0);#endif proc_sigaction = create_proc_entry("sigaction", S_IFREG | S_IWUSR, proc_rtlinux); proc_sigaction->write_proc = sigaction_write; proc_sigprocmask = create_proc_entry("sigprocmask", S_IFREG | S_IWUSR, proc_rtlinux); proc_sigprocmask->write_proc = sigprocmask_write; proc_gethrtime = create_proc_entry("gethrtime", S_IFREG | S_IRUSR, proc_rtlinux); proc_gethrtime->read_proc = gethrtime_read; proc_rtf_put = create_proc_entry("rtf_put", S_IFREG | S_IRUSR, proc_rtlinux); proc_rtf_put->read_proc = rtf_put_read; proc_rtf_get = create_proc_entry("rtf_get", S_IFREG | S_IRUSR, proc_rtlinux); proc_rtf_get->read_proc = rtf_get_read; /* setup rtf_create syscall -Nathan */ __NR_rtf_create = hook_free_syscall((rtlinux_syscall_t) rtf_create_wrapper); proc_rtf_create = create_proc_entry("rtf_create", S_IFREG | S_IRUSR, proc_rtlinux); proc_rtf_create->read_proc = rtf_create_read; /* setup rtf_destroy syscall -Nathan */ __NR_rtf_destroy = hook_free_syscall((rtlinux_syscall_t) rtf_destroy_wrapper); proc_rtf_destroy = create_proc_entry("rtf_destroy", S_IFREG | S_IRUSR, proc_rtlinux); proc_rtf_destroy->read_proc = rtf_destroy_read; return 0;}void cleanup_module(void){ int i; remove_proc_entry("sigprocmask", proc_rtlinux); remove_proc_entry("sigaction", proc_rtlinux); remove_proc_entry("gethrtime", proc_rtlinux); remove_proc_entry("rtf_put", proc_rtlinux); remove_proc_entry("rtf_get", proc_rtlinux); remove_proc_entry("rtf_create", proc_rtlinux); remove_proc_entry("rtf_destroy", proc_rtlinux); /* unsetup rtf_create syscall */ remove_proc_entry("rtf_create", proc_rtlinux); sys_call_table[__NR_rtf_create] = sys_ni_syscall; /* unsetup rtf_destroy syscall */ remove_proc_entry("rtf_destroy", proc_rtlinux); sys_call_table[__NR_rtf_destroy] = sys_ni_syscall; remove_proc_entry("rtlinux", &proc_root); /* free all the irq's we've taken */ for (i = 0; i < NR_IRQS; i++) { if (irq_threads[i].pid) { rtl_free_irq(i); force_sig(SIGTERM, find_task_by_pid(irq_threads[i].pid)); } } /* free all the timers we've taken and kill the task */ while (timer_threads) { pthread_kill(timer_threads->ptid, RTL_SIGNAL_CANCEL); /* This is bad when this thread does bad things. * -Nathan * pthread_join( timer_threads->ptid, NULL ); */ remove_timer_thread(timer_threads); }}void psc_deliver_signal(int signal, struct task_struct *tsk){ struct timer_thread *tt = find_timer_thread(tsk->pid, signal); if (!tt) return; /* call the handler and remove it if 1) fails or 2) is oneshot */ if (call_handler(&tt->action, tsk->pid) || (tt->action.sa_flags & RTLINUX_SA_ONESHOT)) remove_timer_thread(tt);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -