OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [rtems/] [rtems_select.c] - Blame information for rev 389

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *  $Id: rtems_select.c,v 1.2 2001-09-27 12:02:00 chris Exp $
3
 */
4
 
5
#include <string.h>
6
#include <stdarg.h>
7
/* #include <stdlib.h> */
8
#include <stdio.h>
9
 
10
#include <rtems.h>
11
#include <rtems/libio.h>
12
#include <rtems/error.h>
13
#include <rtems/rtems_bsdnet.h>
14
 
15
#include <sys/errno.h>
16
#include <sys/fcntl.h>
17
#include <sys/types.h>
18
#include <sys/param.h>
19
#include <sys/mbuf.h>
20
#include <sys/socket.h>
21
#include <sys/socketvar.h>
22
#include <sys/protosw.h>
23
#include <sys/proc.h>
24
#include <sys/filio.h>
25
 
26
#include <net/if.h>
27
#include <net/route.h>
28
 
29
/*
30
 *********************************************************************
31
 *            RTEMS implementation of select() system call           *
32
 *********************************************************************
33
 */
34
 
35
/*
36
 * This implementation is quite restricted:
37
 *      Works on sockets only -- no support for other devices!
38
 *      A given socket can be in a read-select or a read/recv* by only
39
 *              one task at a time.
40
 *      A given socket can be in a write-select or a write/send* by only
41
 *              one task at a time.
42
 *
43
 * NOTE - select() is a very expensive system call.  It should be avoided
44
 *        if at all possible.  In many cases, rewriting the application
45
 *        to use multiple tasks (one per socket) is a better solution.
46
 */
47
 
48
static __inline int imin(int a, int b) { return (a < b ? a : b); }
49
struct socket *rtems_bsdnet_fdToSocket(int fd);
50
 
51
static int
52
socket_select (struct socket *so, int which, rtems_id tid)
53
{
54
        switch (which) {
55
 
56
        case FREAD:
57
                if (soreadable(so))
58
                        return (1);
59
                so->so_rcv.sb_flags |= SB_WAIT;
60
                so->so_rcv.sb_sel.si_pid = tid;
61
                break;
62
 
63
        case FWRITE:
64
                if (sowriteable(so))
65
                        return (1);
66
                so->so_rcv.sb_flags |= SB_WAIT;
67
                so->so_snd.sb_sel.si_pid = tid;
68
                break;
69
 
70
        case 0:
71
                if (so->so_oobmark || (so->so_state & SS_RCVATMARK))
72
                        return (1);
73
                so->so_rcv.sb_sel.si_pid = tid;
74
                break;
75
        }
76
        return (0);
77
}
78
 
79
static int
80
selscan (rtems_id tid, fd_mask **ibits, fd_mask **obits, int nfd, int *retval)
81
{
82
        struct socket *so;
83
        int msk, i, fd;
84
        fd_mask bits, bit;
85
        int n = 0;
86
        static int flag[3] = { FREAD, FWRITE, 0 };
87
 
88
        for (msk = 0; msk < 3; msk++) {
89
                if (ibits[msk] == NULL)
90
                        continue;
91
                for (i = 0; i < nfd; i += NFDBITS) {
92
                        bits = ibits[msk][i/NFDBITS];
93
                        for (fd = i, bit = 1 ; bits && (fd < nfd) ; fd++, bit <<= 1) {
94
                                if ((bits & bit) == 0)
95
                                        continue;
96
                                bits &= ~bit;
97
                                so = rtems_bsdnet_fdToSocket (fd);
98
                                if (so == NULL)
99
                                        return (EBADF);
100
                                if (socket_select (so, flag[msk], tid)) {
101
                                        obits[msk][fd/NFDBITS] |=
102
                                                        (1 << (fd % NFDBITS));
103
                                        n++;
104
                                }
105
                        }
106
                }
107
        }
108
        *retval = n;
109
        return (0);
110
}
111
 
112
int
113
select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tv)
114
{
115
        fd_mask *ibits[3], *obits[3];
116
        fd_set ob[3];
117
        int error, timo;
118
        int retval;
119
        rtems_id tid;
120
        rtems_interval then, now;
121
        rtems_event_set events;
122
 
123
        if (nfds < 0)
124
                return (EINVAL);
125
        if (tv) {
126
                timo = tv->tv_sec * hz + tv->tv_usec / tick;
127
                if (timo == 0)
128
                        timo = 1;
129
                rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
130
        }
131
        else {
132
                timo = 0;
133
        }
134
 
135
#define getbits(name,i) if (name) { \
136
                ibits[i] = &name->fds_bits[0]; \
137
                obits[i] = &ob[i].fds_bits[0]; \
138
                FD_ZERO(&ob[i]); \
139
        } \
140
        else ibits[i] = NULL
141
        getbits (readfds, 0);
142
        getbits (writefds, 1);
143
        getbits (exceptfds, 2);
144
#undef getbits
145
 
146
        rtems_task_ident (RTEMS_SELF, 0, &tid);
147
        rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &events);
148
        for (;;) {
149
                rtems_bsdnet_semaphore_obtain ();
150
                error = selscan(tid, ibits, obits, nfds, &retval);
151
                rtems_bsdnet_semaphore_release ();
152
                if (error || retval)
153
                        break;
154
                if (timo) {
155
                        rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
156
                        timo -= now - then;
157
                        if (timo <= 0)
158
                                break;
159
                        then = now;
160
                }
161
                rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, timo, &events);
162
        }
163
 
164
#define putbits(name,i) if (name) *name = ob[i]
165
        putbits (readfds, 0);
166
        putbits (writefds, 1);
167
        putbits (exceptfds, 2);
168
#undef putbits
169
        if (error) {
170
                errno = error;
171
                retval = -1;
172
        }
173
        return (retval);
174
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.