Changeset a6f3cff in rtems


Ignore:
Timestamp:
06/11/99 14:11:44 (24 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
923b45c
Parents:
0643693
Message:

Patch from Ian Lance Taylor <ian@…>:

The select function is not particularly efficient when dealing with a
large number of sockets. The application has to build a big set of
bits and pass it in. RTEMS has to look through all those bits and see
what is ready. Then the application has to look through all the bits
again.

On the other hand, when using RTEMS, the select function is needed
exactly when you have a large number of sockets, because that is when
it becomes prohibitive to use a separate thread for each socket.

I think it would make more sense for RTEMS to support callback
functions which could be invoked when there is data available to read
from a socket, or when there is space available to write to a socket.

Accordingly, I implemented them.

This patch adds two new SOL_SOCKET options to setsockopt and
getsockopt: SO_SNDWAKEUP and SO_RCVWAKEUP. They take arguments of
type struct sockwakeup:

struct sockwakeup {

void (*sw_pfn) P((struct socket *, caddr_t));
caddr_t sw_arg;

};

They are used to add or remove a function which will be called when
something happens for the socket. Getting a callback doesn't imply
that a read or write will succeed, but it does imply that it is worth
trying.

This adds functionality to RTEMS which is somewhat like interrupt
driven socket I/O on Unix.

After the patch to RTEMS, I have appended a patch to
netdemos-19990407/select/test.c to test the new functionality and
demonstrate one way it might be used. To run the new test instead of
the select test, change doSocket to call echoServer2 instead of
echoServer.

Files:
16 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/libnetworking/kern/uipc_socket.c

    r0643693 ra6f3cff  
    980980                        break;
    981981
     982                case SO_SNDWAKEUP:
     983                case SO_RCVWAKEUP:
     984                    {
     985                        /* RTEMS addition.  */
     986                        struct sockwakeup *sw;
     987                        struct sockbuf *sb;
     988
     989                        if (m == NULL
     990                            || m->m_len != sizeof (struct sockwakeup)) {
     991                                error = EINVAL;
     992                                goto bad;
     993                        }
     994                        sw = mtod(m, struct sockwakeup *);
     995                        sb = (optname == SO_SNDWAKEUP
     996                              ? &so->so_snd
     997                              : &so->so_rcv);
     998                        sb->sb_wakeup = sw->sw_pfn;
     999                        sb->sb_wakeuparg = sw->sw_arg;
     1000                        if (sw->sw_pfn)
     1001                                sb->sb_flags |= SB_ASYNC;
     1002                        else
     1003                                sb->sb_flags &=~ SB_ASYNC;
     1004                        break;
     1005                    }
     1006
    9821007                default:
    9831008                        error = ENOPROTOOPT;
     
    10771102                    }
    10781103
     1104                case SO_SNDWAKEUP:
     1105                case SO_RCVWAKEUP:
     1106                    {
     1107                        struct sockbuf *sb;
     1108                        struct sockwakeup *sw;
     1109
     1110                        /* RTEMS additions.  */
     1111                        sb = (optname == SO_SNDWAKEUP
     1112                              ? &so->so_snd
     1113                              : &so->so_rcv);
     1114                        m->m_len = sizeof (struct sockwakeup);
     1115                        sw = mtod(m, struct sockwakeup *);
     1116                        sw->sw_pfn = sb->sb_wakeup;
     1117                        sw->sw_arg = sb->sb_wakeuparg;
     1118                        break;
     1119                    }
     1120
    10791121                default:
    10801122                        (void)m_free(m);
  • c/src/exec/libnetworking/rtems/rtems_glue.c

    r0643693 ra6f3cff  
    345345                sb->sb_flags &= ~SB_WAIT;
    346346                rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT);
     347        }
     348        if (sb->sb_wakeup) {
     349                (*sb->sb_wakeup) (so, sb->sb_wakeuparg);
    347350        }
    348351}
  • c/src/exec/libnetworking/sys/socket.h

    r0643693 ra6f3cff  
    3838#define _SYS_SOCKET_H_
    3939
     40#include <sys/cdefs.h>
     41
    4042/*
    4143 * Definitions related to sockets: types, address families, options.
     
    8082
    8183/*
     84 * RTEMS addition: get and set wakeup functions.
     85 */
     86#define SO_SNDWAKEUP    0x1020          /* wakeup when ready to send */
     87#define SO_RCVWAKEUP    0x1021          /* wakeup when ready to receive */
     88
     89/*
    8290 * Structure used for manipulating linger option.
    8391 */
     
    8593        int     l_onoff;                /* option on/off */
    8694        int     l_linger;               /* linger time */
     95};
     96
     97/*
     98 * RTEMS addition: structure used to get and set wakeup function.
     99 */
     100struct socket;
     101struct  sockwakeup {
     102        void    (*sw_pfn) __P((struct socket *, caddr_t));
     103        caddr_t sw_arg;
    87104};
    88105
     
    328345#ifndef KERNEL
    329346
    330 #include <sys/cdefs.h>
    331 
    332347__BEGIN_DECLS
    333348int     accept __P((int, struct sockaddr *, int *));
  • c/src/exec/libnetworking/sys/socketvar.h

    r0643693 ra6f3cff  
    9090                short   sb_flags;       /* flags, see below */
    9191                u_long  sb_timeo;       /* timeout for read/write */
     92                void    (*sb_wakeup) __P((struct socket *, caddr_t));
     93                caddr_t sb_wakeuparg;   /* arg for above */
    9294        } so_rcv, so_snd;
    9395#define SB_MAX          (256*1024)      /* default for max chars in sockbuf */
  • c/src/lib/libnetworking/kern/uipc_socket.c

    r0643693 ra6f3cff  
    980980                        break;
    981981
     982                case SO_SNDWAKEUP:
     983                case SO_RCVWAKEUP:
     984                    {
     985                        /* RTEMS addition.  */
     986                        struct sockwakeup *sw;
     987                        struct sockbuf *sb;
     988
     989                        if (m == NULL
     990                            || m->m_len != sizeof (struct sockwakeup)) {
     991                                error = EINVAL;
     992                                goto bad;
     993                        }
     994                        sw = mtod(m, struct sockwakeup *);
     995                        sb = (optname == SO_SNDWAKEUP
     996                              ? &so->so_snd
     997                              : &so->so_rcv);
     998                        sb->sb_wakeup = sw->sw_pfn;
     999                        sb->sb_wakeuparg = sw->sw_arg;
     1000                        if (sw->sw_pfn)
     1001                                sb->sb_flags |= SB_ASYNC;
     1002                        else
     1003                                sb->sb_flags &=~ SB_ASYNC;
     1004                        break;
     1005                    }
     1006
    9821007                default:
    9831008                        error = ENOPROTOOPT;
     
    10771102                    }
    10781103
     1104                case SO_SNDWAKEUP:
     1105                case SO_RCVWAKEUP:
     1106                    {
     1107                        struct sockbuf *sb;
     1108                        struct sockwakeup *sw;
     1109
     1110                        /* RTEMS additions.  */
     1111                        sb = (optname == SO_SNDWAKEUP
     1112                              ? &so->so_snd
     1113                              : &so->so_rcv);
     1114                        m->m_len = sizeof (struct sockwakeup);
     1115                        sw = mtod(m, struct sockwakeup *);
     1116                        sw->sw_pfn = sb->sb_wakeup;
     1117                        sw->sw_arg = sb->sb_wakeuparg;
     1118                        break;
     1119                    }
     1120
    10791121                default:
    10801122                        (void)m_free(m);
  • c/src/lib/libnetworking/rtems/rtems_glue.c

    r0643693 ra6f3cff  
    345345                sb->sb_flags &= ~SB_WAIT;
    346346                rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT);
     347        }
     348        if (sb->sb_wakeup) {
     349                (*sb->sb_wakeup) (so, sb->sb_wakeuparg);
    347350        }
    348351}
  • c/src/lib/libnetworking/sys/socket.h

    r0643693 ra6f3cff  
    3838#define _SYS_SOCKET_H_
    3939
     40#include <sys/cdefs.h>
     41
    4042/*
    4143 * Definitions related to sockets: types, address families, options.
     
    8082
    8183/*
     84 * RTEMS addition: get and set wakeup functions.
     85 */
     86#define SO_SNDWAKEUP    0x1020          /* wakeup when ready to send */
     87#define SO_RCVWAKEUP    0x1021          /* wakeup when ready to receive */
     88
     89/*
    8290 * Structure used for manipulating linger option.
    8391 */
     
    8593        int     l_onoff;                /* option on/off */
    8694        int     l_linger;               /* linger time */
     95};
     96
     97/*
     98 * RTEMS addition: structure used to get and set wakeup function.
     99 */
     100struct socket;
     101struct  sockwakeup {
     102        void    (*sw_pfn) __P((struct socket *, caddr_t));
     103        caddr_t sw_arg;
    87104};
    88105
     
    328345#ifndef KERNEL
    329346
    330 #include <sys/cdefs.h>
    331 
    332347__BEGIN_DECLS
    333348int     accept __P((int, struct sockaddr *, int *));
  • c/src/lib/libnetworking/sys/socketvar.h

    r0643693 ra6f3cff  
    9090                short   sb_flags;       /* flags, see below */
    9191                u_long  sb_timeo;       /* timeout for read/write */
     92                void    (*sb_wakeup) __P((struct socket *, caddr_t));
     93                caddr_t sb_wakeuparg;   /* arg for above */
    9294        } so_rcv, so_snd;
    9395#define SB_MAX          (256*1024)      /* default for max chars in sockbuf */
  • c/src/libnetworking/kern/uipc_socket.c

    r0643693 ra6f3cff  
    980980                        break;
    981981
     982                case SO_SNDWAKEUP:
     983                case SO_RCVWAKEUP:
     984                    {
     985                        /* RTEMS addition.  */
     986                        struct sockwakeup *sw;
     987                        struct sockbuf *sb;
     988
     989                        if (m == NULL
     990                            || m->m_len != sizeof (struct sockwakeup)) {
     991                                error = EINVAL;
     992                                goto bad;
     993                        }
     994                        sw = mtod(m, struct sockwakeup *);
     995                        sb = (optname == SO_SNDWAKEUP
     996                              ? &so->so_snd
     997                              : &so->so_rcv);
     998                        sb->sb_wakeup = sw->sw_pfn;
     999                        sb->sb_wakeuparg = sw->sw_arg;
     1000                        if (sw->sw_pfn)
     1001                                sb->sb_flags |= SB_ASYNC;
     1002                        else
     1003                                sb->sb_flags &=~ SB_ASYNC;
     1004                        break;
     1005                    }
     1006
    9821007                default:
    9831008                        error = ENOPROTOOPT;
     
    10771102                    }
    10781103
     1104                case SO_SNDWAKEUP:
     1105                case SO_RCVWAKEUP:
     1106                    {
     1107                        struct sockbuf *sb;
     1108                        struct sockwakeup *sw;
     1109
     1110                        /* RTEMS additions.  */
     1111                        sb = (optname == SO_SNDWAKEUP
     1112                              ? &so->so_snd
     1113                              : &so->so_rcv);
     1114                        m->m_len = sizeof (struct sockwakeup);
     1115                        sw = mtod(m, struct sockwakeup *);
     1116                        sw->sw_pfn = sb->sb_wakeup;
     1117                        sw->sw_arg = sb->sb_wakeuparg;
     1118                        break;
     1119                    }
     1120
    10791121                default:
    10801122                        (void)m_free(m);
  • c/src/libnetworking/rtems/rtems_glue.c

    r0643693 ra6f3cff  
    345345                sb->sb_flags &= ~SB_WAIT;
    346346                rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT);
     347        }
     348        if (sb->sb_wakeup) {
     349                (*sb->sb_wakeup) (so, sb->sb_wakeuparg);
    347350        }
    348351}
  • c/src/libnetworking/sys/socket.h

    r0643693 ra6f3cff  
    3838#define _SYS_SOCKET_H_
    3939
     40#include <sys/cdefs.h>
     41
    4042/*
    4143 * Definitions related to sockets: types, address families, options.
     
    8082
    8183/*
     84 * RTEMS addition: get and set wakeup functions.
     85 */
     86#define SO_SNDWAKEUP    0x1020          /* wakeup when ready to send */
     87#define SO_RCVWAKEUP    0x1021          /* wakeup when ready to receive */
     88
     89/*
    8290 * Structure used for manipulating linger option.
    8391 */
     
    8593        int     l_onoff;                /* option on/off */
    8694        int     l_linger;               /* linger time */
     95};
     96
     97/*
     98 * RTEMS addition: structure used to get and set wakeup function.
     99 */
     100struct socket;
     101struct  sockwakeup {
     102        void    (*sw_pfn) __P((struct socket *, caddr_t));
     103        caddr_t sw_arg;
    87104};
    88105
     
    328345#ifndef KERNEL
    329346
    330 #include <sys/cdefs.h>
    331 
    332347__BEGIN_DECLS
    333348int     accept __P((int, struct sockaddr *, int *));
  • c/src/libnetworking/sys/socketvar.h

    r0643693 ra6f3cff  
    9090                short   sb_flags;       /* flags, see below */
    9191                u_long  sb_timeo;       /* timeout for read/write */
     92                void    (*sb_wakeup) __P((struct socket *, caddr_t));
     93                caddr_t sb_wakeuparg;   /* arg for above */
    9294        } so_rcv, so_snd;
    9395#define SB_MAX          (256*1024)      /* default for max chars in sockbuf */
  • cpukit/libnetworking/kern/uipc_socket.c

    r0643693 ra6f3cff  
    980980                        break;
    981981
     982                case SO_SNDWAKEUP:
     983                case SO_RCVWAKEUP:
     984                    {
     985                        /* RTEMS addition.  */
     986                        struct sockwakeup *sw;
     987                        struct sockbuf *sb;
     988
     989                        if (m == NULL
     990                            || m->m_len != sizeof (struct sockwakeup)) {
     991                                error = EINVAL;
     992                                goto bad;
     993                        }
     994                        sw = mtod(m, struct sockwakeup *);
     995                        sb = (optname == SO_SNDWAKEUP
     996                              ? &so->so_snd
     997                              : &so->so_rcv);
     998                        sb->sb_wakeup = sw->sw_pfn;
     999                        sb->sb_wakeuparg = sw->sw_arg;
     1000                        if (sw->sw_pfn)
     1001                                sb->sb_flags |= SB_ASYNC;
     1002                        else
     1003                                sb->sb_flags &=~ SB_ASYNC;
     1004                        break;
     1005                    }
     1006
    9821007                default:
    9831008                        error = ENOPROTOOPT;
     
    10771102                    }
    10781103
     1104                case SO_SNDWAKEUP:
     1105                case SO_RCVWAKEUP:
     1106                    {
     1107                        struct sockbuf *sb;
     1108                        struct sockwakeup *sw;
     1109
     1110                        /* RTEMS additions.  */
     1111                        sb = (optname == SO_SNDWAKEUP
     1112                              ? &so->so_snd
     1113                              : &so->so_rcv);
     1114                        m->m_len = sizeof (struct sockwakeup);
     1115                        sw = mtod(m, struct sockwakeup *);
     1116                        sw->sw_pfn = sb->sb_wakeup;
     1117                        sw->sw_arg = sb->sb_wakeuparg;
     1118                        break;
     1119                    }
     1120
    10791121                default:
    10801122                        (void)m_free(m);
  • cpukit/libnetworking/rtems/rtems_glue.c

    r0643693 ra6f3cff  
    345345                sb->sb_flags &= ~SB_WAIT;
    346346                rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT);
     347        }
     348        if (sb->sb_wakeup) {
     349                (*sb->sb_wakeup) (so, sb->sb_wakeuparg);
    347350        }
    348351}
  • cpukit/libnetworking/sys/socket.h

    r0643693 ra6f3cff  
    3838#define _SYS_SOCKET_H_
    3939
     40#include <sys/cdefs.h>
     41
    4042/*
    4143 * Definitions related to sockets: types, address families, options.
     
    8082
    8183/*
     84 * RTEMS addition: get and set wakeup functions.
     85 */
     86#define SO_SNDWAKEUP    0x1020          /* wakeup when ready to send */
     87#define SO_RCVWAKEUP    0x1021          /* wakeup when ready to receive */
     88
     89/*
    8290 * Structure used for manipulating linger option.
    8391 */
     
    8593        int     l_onoff;                /* option on/off */
    8694        int     l_linger;               /* linger time */
     95};
     96
     97/*
     98 * RTEMS addition: structure used to get and set wakeup function.
     99 */
     100struct socket;
     101struct  sockwakeup {
     102        void    (*sw_pfn) __P((struct socket *, caddr_t));
     103        caddr_t sw_arg;
    87104};
    88105
     
    328345#ifndef KERNEL
    329346
    330 #include <sys/cdefs.h>
    331 
    332347__BEGIN_DECLS
    333348int     accept __P((int, struct sockaddr *, int *));
  • cpukit/libnetworking/sys/socketvar.h

    r0643693 ra6f3cff  
    9090                short   sb_flags;       /* flags, see below */
    9191                u_long  sb_timeo;       /* timeout for read/write */
     92                void    (*sb_wakeup) __P((struct socket *, caddr_t));
     93                caddr_t sb_wakeuparg;   /* arg for above */
    9294        } so_rcv, so_snd;
    9395#define SB_MAX          (256*1024)      /* default for max chars in sockbuf */
Note: See TracChangeset for help on using the changeset viewer.