From d2a2fab6fec186f72ae7f43710a09bf368fa15f8 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 1 Dec 2001 01:15:35 +0000 Subject: [PATCH] I'm tired of these being in a separate directory --- comedi/rt_pend_tq.c | 98 +++++++++++++++++++++++++++++++++++++++++++++ comedi/rt_pend_tq.h | 9 +++++ 2 files changed, 107 insertions(+) create mode 100644 comedi/rt_pend_tq.c create mode 100644 comedi/rt_pend_tq.h diff --git a/comedi/rt_pend_tq.c b/comedi/rt_pend_tq.c new file mode 100644 index 00000000..ff08ed76 --- /dev/null +++ b/comedi/rt_pend_tq.c @@ -0,0 +1,98 @@ +/* rt_pend_tq.c */ +#include +#include +#include +#include // for rt spinlocks +#include "rt_pend_tq.h" +#ifdef CONFIG_COMEDI_RTAI +#include +#endif +#ifdef CONFIG_COMEDI_RTL +#include +#endif + +#ifdef standalone +#include +#define rt_pend_tq_init init_module +#define rt_pend_tq_cleanup cleanup_module +#endif + +volatile static struct rt_pend_tq rt_pend_tq[RT_PEND_TQ_SIZE]; +volatile static struct rt_pend_tq * volatile rt_pend_head= rt_pend_tq, + * volatile rt_pend_tail = rt_pend_tq; +int rt_pend_tq_irq=0; +spinlock_t rt_pend_tq_lock = SPIN_LOCK_UNLOCKED; + +// WARNING: following code not checked against race conditions yet. +#define INC_CIRCULAR_PTR(ptr,begin,size) do {if(++(ptr)>=(begin)+(size)) (ptr)=(begin); } while(0) +#define DEC_CIRCULAR_PTR(ptr,begin,size) do {if(--(ptr)<(begin)) (ptr)=(begin)+(size)-1; } while(0) + +int rt_pend_call(void (*func)(int arg1, void * arg2), int arg1, void * arg2) +{ + unsigned long flags; + + if(func==NULL) + return -EINVAL; + if(rt_pend_tq_irq<=0) + return -ENODEV; + comedi_spin_lock_irqsave(&rt_pend_tq_lock, flags); + INC_CIRCULAR_PTR(rt_pend_head,rt_pend_tq,RT_PEND_TQ_SIZE); + if(rt_pend_head==rt_pend_tail) { + // overflow, we just refuse to take this request + DEC_CIRCULAR_PTR(rt_pend_head,rt_pend_tq,RT_PEND_TQ_SIZE); + comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags); + return -EAGAIN; + } + rt_pend_head->func=func; + rt_pend_head->arg1=arg1; + rt_pend_head->arg2=arg2; + comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags); +#ifdef CONFIG_COMEDI_RTAI + rt_pend_linux_srq(rt_pend_tq_irq); +#endif +#ifdef CONFIG_COMEDI_RTL + rtl_global_pend_irq(rt_pend_tq_irq); +#endif + return 0; +} + +#ifdef CONFIG_COMEDI_RTAI +void rt_pend_irq_handler(void) +#endif +#ifdef CONFIG_COMEDI_RTL +void rt_pend_irq_handler(int irq, void *dev, struct pt_regs * regs) +#endif +{ + while(rt_pend_head!=rt_pend_tail) { + INC_CIRCULAR_PTR(rt_pend_tail,rt_pend_tq,RT_PEND_TQ_SIZE); + rt_pend_tail->func(rt_pend_tail->arg1,rt_pend_tail->arg2); + } +} + +int rt_pend_tq_init(void) +{ + rt_pend_head=rt_pend_tail=rt_pend_tq; +#ifdef CONFIG_COMEDI_RTAI + rt_pend_tq_irq=rt_request_srq(0,rt_pend_irq_handler,NULL); +#endif +#ifdef CONFIG_COMEDI_RTL + rt_pend_tq_irq=rtl_get_soft_irq(rt_pend_irq_handler,"rt_pend_irq"); +#endif + if(rt_pend_tq_irq>0) + printk("rt_pend_tq: RT bottom half scheduler initialized OK\n"); + else + printk("rt_pend_tq: rtl_get_soft_irq failed\n"); + return 0; +} + +void rt_pend_tq_cleanup(void) +{ + printk("rt_pend_tq: unloading\n"); +#ifdef CONFIG_COMEDI_RTAI + rt_free_srq(rt_pend_tq_irq); +#endif +#ifdef CONFIG_COMEDI_RTL + free_irq(rt_pend_tq_irq,NULL); +#endif +} + diff --git a/comedi/rt_pend_tq.h b/comedi/rt_pend_tq.h new file mode 100644 index 00000000..5475a0cb --- /dev/null +++ b/comedi/rt_pend_tq.h @@ -0,0 +1,9 @@ +#define RT_PEND_TQ_SIZE 16 +struct rt_pend_tq { + void (*func)(int arg1, void * arg2); + int arg1; + void *arg2; +} ; +extern int rt_pend_call(void (*func)(int arg1, void * arg2), int arg1, void * arg2); +extern int rt_pend_tq_init(void); +extern void rt_pend_tq_cleanup(void); -- 2.26.2