
|
[openbeosnetteam]
||
[Date Prev]
[05-2002 Date Index]
[Date Next]
||
[Thread Prev]
[05-2002 Thread Index]
[Thread Next]
[openbeosnetteam] Re: End of select on R5
- From: "David Reid" <dreid@xxxxxxxxxxxx>
- To: <openbeosnetteam@xxxxxxxxxxxxx>
- Date: Fri, 3 May 2002 16:19:38 +0100
BTW, I am getting a bit concerned by the high number of sem's that we're
using. I think we'll need to work hard to reduce this, but the schemes I
have in mind are mainly for when we get into the kernel :(
david
----- Original Message -----
From: "David Reid" <dreid@xxxxxxxxxxxx>
To: <openbeosnetteam@xxxxxxxxxxxxx>
Sent: Friday, May 03, 2002 3:47 PM
Subject: [openbeosnetteam] Re: End of select on R5
> Well, if you can code it so it works :)
>
> My comment about userland was that I was looking for full performance, and
> that basically requires a lot of knowledge of stuff we don't have access
> to... Still, if this works, then Philippe please code it and commit it.
>
> david
>
> ----- Original Message -----
> From: <philippe.houdoin@xxxxxxx>
> To: <openbeosnetteam@xxxxxxxxxxxxx>
> Sent: Friday, May 03, 2002 1:30 PM
> Subject: [openbeosnetteam] Re: End of select on R5
>
>
> > Quoting David Reid:
> > > It should be possible to write another implementation of select,
though
> > > I suspect we'd have then to restrict the stack to userland and do some
> > > different things, but if people wanted to then it could be done.
> >
> > Yes, I've in mind a select() implementation which could even works in
> kernel stack and don't break all our kernel-side code: we can simulate the
> way R5/BONE kernel select() syscall do (well, naysayers will use "don't"
> here ;-)) his job, but only for our net_stack_driver. So that would works
> only on sockets, not on all fd. Like
> > under R5 net_server, in fact.
> >
> > This implementation could works like this:
> >
> > libnet/select.c:
> > struct selectsync {
> > sem_id sem;
> > volatile uint32 ref;
> > }
> >
> > select(int nbits, fd_set * r, fd_set * w, fd_set * e,
> > struct timeval * t)
> > {
> > int fd;
> > struct selectsync ss;
> > status_t status;
> >
> >
> > ss.sem = create_sem(0, "selectsync");
> >
> > // call, indirectly, net_stack_select() for each event to monitor
> > // as we are not the vfs, we can't call this device hook ourself, but
> > // our NET_STACK_SELECT could for us!
> > for(fd = 1; fd < nbits; fd++) {
> > if (FD_ISSET(fd, r)) {
> > ss.ref = (fd << 8) | 1;
> > ioctl(fd, NET_STACK_SELECT, &ss, sizeof(ss));
> > }
> > if (FD_ISSET(fd, w)) {
> > ss.ref = (fd << 8) | 2;
> > ioctl(fd, NET_STACK_SELECT, &ss, sizeof(ss));
> > }
> > if (FD_ISSET(fd, e)) {
> > ss.ref = (fd << 8) | 3;
> > ioctl(fd, NET_STACK_SELECT, &ss, sizeof(ss));
> > }
> > }
> >
> > // okay, up to now no event was notified
> > ss.ref = 0;
> >
> > if (t) {
> > bigtime_t timeout;
> >
> > timeout = t->sec * 1000000 + t->usec;
> > status = acquire_sem_etc(ss.sem, 1, B_RELATIVE_TIMEOUT, timeout);
> > } else
> > status = acquire_sem(ss.sem);
> >
> > // unregister socket event notification
> > for(fd = 1; fd < nbits; fd++) {
> > if (FD_ISSET(fd, r)) {
> > ss.ref = (fd << 8) | 1;
> > ioctl(fd, NET_STACK_DESELECT, &ss, sizeof(ss));
> > }
> > if (FD_ISSET(fd, w)) {
> > ss.ref = (fd << 8) | 2;
> > ioctl(fd, NET_STACK_DESELECT, &ss, sizeof(ss));
> > }
> > if (FD_ISSET(fd, e)) {
> > ss.ref = (fd << 8) | 3;
> > ioctl(fd, NET_STACK_DESELECT, &ss, sizeof(ss));
> > }
> > }
> >
> > delete_sem(ss.sem);
> >
> > if (status == B_TIMED_OUT)
> > return 0;
> >
> > if (status != B_OK) {
> > errno = status;
> > return -1;
> > }
> >
> > FD_ZERO(r);
> > FD_ZERO(w);
> > FD_ZERO(e);
> >
> > switch (ss.ref & (0xF)) {
> > case 1: FD_SET((ss.ref >> 8), r); break;
> > case 2: FD_SET((ss.ref >> 8), w); break;
> > case 3: FD_SET((ss.ref >> 8), e); break;
> > }
> >
> > return 1;
> > }
> >
> > driver/net_stack_driver.c:
> > typedef struct selectsync {
> > sem_id sem;
> > volatile uint32 ref;
> > } selectsync;
> >
> > net_stack_control()
> > {
> > [...]
> > case NET_STACK_SELECT: {
> > struct selectsync * ss = (struct selectsync *) data;
> > return net_stack_select(cookie, (ss.ref & 0xF), ss.ref, ss);
> > }
> >
> > case NET_STACK_DESELECT: {
> > struct selectsync * ss = (struct selectsync *) data;
> > return net_stack_select(cookie, (ss.ref & 0xF), ss);
> > }
> > [...]
> > }
> >
> > static void notify_select_event(selectsync * sync, uint32 ref)
> > {
> > sync.ref = ref;
> > release_sem(sync.sem);
> > }
> >
> > That way we'll introduce only minor modification to kernel code, and
> > the big change will only on libnet.so select() code. Which still would
be
> > better than net_server one, as we could support read and write and
> exception
> > selecting...
> >
> > But, the full point here is...
> >
> > > Given that most folks I talk to are running Dano or Bone these days,
> > > it hardly seems worth the effort though.
> >
> > ... does it worth the effort?
> > Only time will tell.
> >
> > -Philippe.
> >
> >
>
>
>
|

|