On Tue, Jan 18, 2000 at 06:15:44PM -0800, Robert Kavaler wrote:
> We have been using RTLinux for some time now, and I have been making
> changes to some of the prepackaged libraries, mainly rtl_fifo.  I am
> presenting them here so that they may be incorporated into the kernel so
> that I don't have to constantly patch downloaded kernels.  There are
> three changes that I made to the fifo stuff, and one to the posixio
> stuff:
> 
> 1.  Fixed a "bug" in rtf_put so that the return value is the number of
> bytes written (I think that this is an old bug but I only joined the
> newsgroup recently).

fixed in 2.0

> 2.  Added a reference counter callback to the rt process that gets
> executed when a user opens and closes a fifo.  I needed this in order to
> prevent a realtime module from being unloaded when a user has the fifo
> open.  The logic in the fifo stuff doesn't handle this case, so I just
> wanted to prevent it from occuring.  This callback is also useful to
> clean up after the user task exits, especially if the user task crashes.

I've been meaning to do this, good.

> 
> 3.  Filled in the posixio interface for rtl_fifo so that it does
> something reasonable instead of just returning 0.

Fixed in 2.0 I believe.

> 4.  Added mmap and ioctl functions to the posix interface, if that makes
> sense.

What do they do?

> 
> I also have a question regarding the both my reference counter callback
> and the standard fifo user callback.  The way I see it implemented, the
> callbacks run at the linux kernel level and not the realtime kernel
> level.  Thus, either callback can be interrupted by the realtime kernel
> and not run to completion until after the rt tasks are executed.  Thus,
> the callback code is not actually synchonized to the realtime kernel.
> This seems like a problem.  How can I synchonize the callback to a rt
> kernel task?

Can you be more precise about what you want?
The 2.0.pre1 has new RT callbacks with fifo, but perhaps this is not what you want?

> 
> By the way, I am using the beta13 release of RTLinux with a 2.2.11
> kernel.
> 
> Robert Kavaler
> 

> Index: linux/rt-kernel/i386/beta13/rtl/include/rtl_fifo.h
> diff -u linux/rt-kernel/i386/beta13/rtl/include/rtl_fifo.h:1.1 
>linux/rt-kernel/i386/beta13/rtl/include/rtl_fifo.h:1.5
> --- linux/rt-kernel/i386/beta13/rtl/include/rtl_fifo.h:1.1    Tue Aug 17 17:32:14 
>1999
> +++ linux/rt-kernel/i386/beta13/rtl/include/rtl_fifo.h        Tue Jan 18 16:51:24 
>2000
> @@ -20,6 +20,18 @@
>  
>  
>  
> +/* attach a reference counter callback to an RT-FIFO
> + *
> + * Used to allow modules to keep track of user tasks that have a fifo
> + * open so that they can prevent being unloaded.  The callback 
> + * ref_counter is called with inc = 1 when a user opens the fifo, 
> + * -1 when the user closes a fifo.
> + */
> +extern int rtf_create_ref_counter(unsigned int fifo, /* RT-FIFO */
> +     void (*ref_counter)(unsigned int fifo, int inc) /* function to be called */);
> +
> +
> +
>  /* create an RT-FIFO
>   * 
>   * An RT-FIFO \arg{fifo} is created with initial size of \arg{size}.
> Index: linux/rt-kernel/i386/beta13/rtl/include/arch-i386/rt_irq.h
> diff -u linux/rt-kernel/i386/beta13/rtl/include/arch-i386/rt_irq.h:1.1 
>linux/rt-kernel/i386/beta13/rtl/include/arch-i386/rt_irq.h:1.2
> --- linux/rt-kernel/i386/beta13/rtl/include/arch-i386/rt_irq.h:1.1    Tue Aug 17 
>17:32:14 1999
> +++ linux/rt-kernel/i386/beta13/rtl/include/arch-i386/rt_irq.h        Mon Nov 29 
>12:44:02 1999
> @@ -27,7 +27,7 @@
>       return rtl_request_global_irq(irq, rtl_compat_irq_handler);
>  }
>  
> -extern int free_RTirq(unsigned int irq)
> +extern inline int free_RTirq(unsigned int irq)
>  {
>       return rtl_free_global_irq (irq);
>  }
> Index: linux/rt-kernel/i386/beta13/rtl/fifos/rtl_fifo.c
> diff -u linux/rt-kernel/i386/beta13/rtl/fifos/rtl_fifo.c:1.1 
>linux/rt-kernel/i386/beta13/rtl/fifos/rtl_fifo.c:1.5
> --- linux/rt-kernel/i386/beta13/rtl/fifos/rtl_fifo.c:1.1      Tue Aug 17 17:32:14 
>1999
> +++ linux/rt-kernel/i386/beta13/rtl/fifos/rtl_fifo.c  Tue Jan 18 16:49:49 2000
> @@ -42,6 +42,7 @@
>       int start;
>       int len;
>       int (*user_handler) (unsigned int fifo);
> +     void (*ref_counter)(unsigned int fifo, int inc);
>       struct wait_queue *wait;
>       struct tq_struct wake_up_task;
>  };
> @@ -58,6 +59,7 @@
>  #define RTF_BUF(minor)               (RTF_ADDR(minor)->bufsize)
>  #define RTF_START(minor)     (RTF_ADDR(minor)->start)
>  #define RTF_HANDLER(minor)   (RTF_ADDR(minor)->user_handler)
> +#define RTF_REF_COUNTER(minor)       (RTF_ADDR(minor)->ref_counter)
>  #define RTF_LEN(minor)               (RTF_ADDR(minor)->len)
>  #define RTF_FREE(minor)              (RTF_BUF(minor) - RTF_LEN(minor))
>  #define RTF_WAIT(minor)              (RTF_ADDR(minor)->wait)
> @@ -149,6 +151,7 @@
>       RTF_SLEEPS(minor) = 0;
>       RTF_USER_OPEN(minor) = 0;
>       RTF_HANDLER(minor) = &default_user_handler;
> +     RTF_REF_COUNTER(minor) = NULL;
>  
>       RTF_WAKE_UP_TASK(minor).next = 0;
>       RTF_WAKE_UP_TASK(minor).sync = 0;
> @@ -189,6 +192,15 @@
>  }
>  
>  
> +int rtf_create_ref_counter(unsigned int minor, void (*ref_counter)(unsigned int 
>fifo, int inc))
> +{
> +     if (minor >= RTF_NO || !RTF_OPEN(minor) || !ref_counter) {
> +             return -EINVAL;
> +     }
> +     RTF_REF_COUNTER(minor) = ref_counter;
> +     return 0;
> +}
> +
>  /* these can be called from RT tasks and interrupt handlers */
>  static void fifo_wake_sleepers(int );
>  
> @@ -231,7 +243,7 @@
>       }
>       rtl_end_critical(interrupt_state);
>       fifo_wake_sleepers(minor);
> -     return count;
> +     return written;
>  }
>  
>  
> @@ -301,6 +313,9 @@
>       RTF_USER_OPEN(minor) = 1;
>  
>       MOD_INC_USE_COUNT;
> +     if(RTF_REF_COUNTER(minor)) {
> +         (*RTF_REF_COUNTER(minor))(minor, 1);
> +     }
>       return 0;
>  }
>  
> @@ -316,6 +331,9 @@
>       RTF_SLEEPS(minor) = 0;
>       RTF_USER_OPEN(minor) = 0;
>       MOD_DEC_USE_COUNT;
> +     if(RTF_REF_COUNTER(minor)) {
> +         (*RTF_REF_COUNTER(minor))(minor, -1);
> +     }
>       return 0;
>  }
>  
> @@ -520,15 +538,18 @@
>  
>  static int rtl_rtf_open (struct rtl_file *filp)
>  {
> +     int  ret;
> +
>       if (!(filp->f_flags & O_NONBLOCK)) {
>               return -EACCES; /* TODO: implement blocking IO */
>       }
> -     return 0;
> +     ret = rtf_create(RTL_MINOR_FROM_FILEPTR(filp), 2048);
> +     return (ret == 0 || ret == -EBUSY) ? 0 : ret;
>  }
>  
>  static int rtl_rtf_release (struct rtl_file *filp)
>  {
> -     return 0;
> +     return rtf_destroy(RTL_MINOR_FROM_FILEPTR(filp));
>  }
>  
>  static ssize_t rtl_rtf_write(struct rtl_file *filp, const char *buf, size_t count, 
>loff_t* ppos)
> Index: linux/rt-kernel/i386/beta13/rtl/system/rtl_posixio.c
> diff -u linux/rt-kernel/i386/beta13/rtl/system/rtl_posixio.c:1.1 
>linux/rt-kernel/i386/beta13/rtl/system/rtl_posixio.c:1.2
> --- linux/rt-kernel/i386/beta13/rtl/system/rtl_posixio.c:1.1  Tue Aug 17 17:32:16 
>1999
> +++ linux/rt-kernel/i386/beta13/rtl/system/rtl_posixio.c      Mon Aug 30 19:23:41 
>1999
> @@ -15,7 +15,10 @@
>  #include <linux/fcntl.h>
>  #include <linux/errno.h>
>  #include <linux/ctype.h>
> +#include <linux/mm.h>
>  
> +#include <asm/io.h>
> +
>  #include <rtl_posixio.h>
>  
>  #define MAX_RTL_FILES 128
> @@ -127,25 +130,55 @@
>  ssize_t write(int fd, const void *buf, size_t count)
>  {
>       CHECKFD(fd);
> -     return rtl_files[fd] . f_op -> write (&rtl_files[fd], buf, count, 0);
> +     return (rtl_files[fd] . f_op -> write) ? 
> +             rtl_files[fd] . f_op -> write (&rtl_files[fd], buf, count, 0) :
> +             -EINVAL;
>  }
>  
>  ssize_t read(int fd, void *buf, size_t count)
>  {
>       CHECKFD(fd);
> -     return rtl_files[fd] . f_op -> read (&rtl_files[fd], buf, count, 0);
> +     return (rtl_files[fd] . f_op -> read) ?
> +             rtl_files[fd] . f_op -> read (&rtl_files[fd], buf, count, 0) :
> +             -EINVAL;
>  }
>  
>  caddr_t  mmap(void  *start,  size_t length, int prot , int flags, int fd, off_t 
>offset)
>  {
> -     return (caddr_t) -EINVAL;
> +     struct vm_area_struct vm;
> +
> +     if ((unsigned int) (fd) >= MAX_RTL_FILES || !rtl_files[fd].f_op) {
> +             return NULL;
> +     }
> +     if(rtl_files[fd] . f_op -> mmap == NULL || start != 0) {
> +             return NULL;
> +     }
> +     vm . vm_offset = offset;
> +     vm . vm_start = 0;
> +     vm . vm_end = length;
> +     if(rtl_files[fd] . f_op -> mmap (&rtl_files[fd], &vm) != 0) {
> +             return NULL;
> +     }
> +     return (caddr_t) vm . vm_start;
> +     
> +
>  }
>  
> -int munmap(void *start, size_t length)
> +int
> +munmap(void *start, size_t length)
>  {
> -     return -EINVAL;
> +     iounmap(start);
> +     return 0;
>  }
>  
> +int ioctl(int fd, unsigned int cmd, unsigned long arg)
> +{
> +     CHECKFD(fd);
> +     
> +     return (rtl_files[fd] . f_op -> ioctl) ?
> +             rtl_files[fd] . f_op -> ioctl (&rtl_files[fd], cmd, arg) :
> +             -EINVAL;
> +}
>  
>  int init_module(void)
>  {


-- 
---------------------------------------------------------
Victor Yodaiken 
FSMLabs:  www.fsmlabs.com  www.rtlinux.com
FSMLabs is a servicemark and a service of 
VJY Associates L.L.C, New Mexico.

--- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
----
For more information on Real-Time Linux see:
http://www.rtlinux.org/~rtlinux/

Reply via email to