/ addons / rtdm / select.h
select.h
  1  /*!\file select.h
  2   * \brief file descriptors events multiplexing header.
  3   * \author Gilles Chanteperdrix
  4   *
  5   * Copyright (C) 2008 Efixo <gilles.chanteperdrix@laposte.net>
  6   *
  7   * Rtai is free software; you can redistribute it and/or modify
  8   * it under the terms of the GNU General Public License as published
  9   * by the Free Software Foundation; either version 2 of the License,
 10   * or (at your option) any later version.
 11   *
 12   * Rtai is distributed in the hope that it will be useful, but
 13   * WITHOUT ANY WARRANTY; without even the implied warranty of
 14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15   * General Public License for more details.
 16   *
 17   * You should have received a copy of the GNU General Public License
 18   * along with Rtai; if not, write to the Free Software
 19   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 20   * 02111-1307, USA.
 21   *
 22   * \ingroup select
 23   */
 24  
 25  #ifndef XNSELECT_H
 26  #define XNSELECT_H
 27  
 28  /*! \addtogroup select
 29   *@{*/
 30  
 31  #include "xn.h"
 32  
 33  #define XNSELECT_READ      0
 34  #define XNSELECT_WRITE     1
 35  #define XNSELECT_EXCEPT    2
 36  #define XNSELECT_MAX_TYPES 3
 37  
 38  struct xnselector {
 39  	xnsynch_t synchbase;
 40  	struct fds {
 41  		fd_set expected;
 42  		fd_set pending;
 43  	} fds [XNSELECT_MAX_TYPES];
 44  	xnholder_t destroy_link;
 45  	xnqueue_t bindings; /* only used by xnselector_destroy */
 46  };
 47  
 48  #define __NFDBITS__	(8 * sizeof(unsigned long))
 49  #define __FDSET_LONGS__	(__FD_SETSIZE/__NFDBITS__)
 50  #define	__FDELT__(d)	((d) / __NFDBITS__)
 51  #define	__FDMASK__(d)	(1UL << ((d) % __NFDBITS__))
 52  
 53  static inline void __FD_SET__(unsigned long __fd, __kernel_fd_set *__fdsetp)
 54  {
 55          unsigned long __tmp = __fd / __NFDBITS__;
 56          unsigned long __rem = __fd % __NFDBITS__;
 57          __fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
 58  }
 59  
 60  static inline void __FD_CLR__(unsigned long __fd, __kernel_fd_set *__fdsetp)
 61  {
 62          unsigned long __tmp = __fd / __NFDBITS__;
 63          unsigned long __rem = __fd % __NFDBITS__;
 64          __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
 65  }
 66  
 67  static inline int __FD_ISSET__(unsigned long __fd, const __kernel_fd_set *__p)
 68  {
 69          unsigned long __tmp = __fd / __NFDBITS__;
 70          unsigned long __rem = __fd % __NFDBITS__;
 71          return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
 72  }
 73  
 74  static inline void __FD_ZERO__(__kernel_fd_set *__p)
 75  {
 76  	unsigned long *__tmp = __p->fds_bits;
 77  	int __i;
 78  
 79  	__i = __FDSET_LONGS__;
 80  	while (__i) {
 81  		__i--;
 82  		*__tmp = 0;
 83  		__tmp++;
 84  	}
 85  }
 86  
 87  #ifdef CONFIG_RTAI_RTDM_SELECT
 88  
 89  struct xnselect {
 90  	xnqueue_t bindings;
 91  };
 92  
 93  #define DECLARE_XNSELECT(name) struct xnselect name
 94  
 95  struct xnselect_binding {
 96  	struct xnselector *selector;
 97  	struct xnselect *fd;
 98  	unsigned type;
 99  	unsigned bit_index;
100  	xnholder_t link;  /* link in selected fds list. */
101  	xnholder_t slink; /* link in selector list */
102  };
103  
104  #ifdef __cplusplus
105  extern "C" {
106  #endif /* __cplusplus */
107  
108  void xnselect_init(struct xnselect *select_block);
109  
110  int xnselect_bind(struct xnselect *select_block,
111  		  struct xnselect_binding *binding,
112  		  struct xnselector *selector,
113  		  unsigned type,
114  		  unsigned bit_index,
115  		  unsigned state);
116  
117  int __xnselect_signal(struct xnselect *select_block, unsigned state);
118  
119  /**
120   * Signal a file descriptor state change.
121   *
122   * @param select_block pointer to an @a xnselect structure representing the file
123   * descriptor whose state changed;
124   * @param state new value of the state.
125   *
126   * @retval 1 if rescheduling is needed;
127   * @retval 0 otherwise.
128   */
129  static inline int
130  xnselect_signal(struct xnselect *select_block, unsigned state)
131  {
132  	if (!emptyq_p(&select_block->bindings))
133  		return __xnselect_signal(select_block, state);
134  	return 0;
135  }
136  
137  void xnselect_destroy(struct xnselect *select_block);
138  
139  int xnselector_init(struct xnselector *selector);
140  
141  int xnselect(struct xnselector *selector,
142  	     fd_set *out_fds[XNSELECT_MAX_TYPES],
143  	     fd_set *in_fds[XNSELECT_MAX_TYPES],
144  	     int nfds,
145  	     xnticks_t timeout, xntmode_t timeout_mode);
146  
147  void xnselector_destroy(struct xnselector *selector);
148  
149  int xnselect_mount(void);
150  
151  int xnselect_umount(void);
152  
153  #ifdef __cplusplus
154  }
155  #endif /* __cplusplus */
156  
157  #else /* !CONFIG_RTAI_RTDM_SELECT */
158  struct xnselector;
159  #define DECLARE_XNSELECT(name)
160  #define xnselect_init(block)
161  #define xnselect_bind(select_block,binding,selector,type,bit_index,state) \
162  	({ -EBADF; })
163  #define xnselect_signal(block, state) ({ int __ret = 0; __ret; })
164  #define xnselect_destroy(block)
165  #endif /* !CONFIG_RTAI_RTDM_SELECT */
166  
167  /*@}*/
168  
169  #endif /* XNSELECT_H */