[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOC
From: |
Frédéric Bernon |
Subject: |
[lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING |
Date: |
Tue, 03 Jul 2007 21:54:27 +0000 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4 |
Follow-up Comment #6, task #6994 (project lwip):
(Simon Goldschmidt wrote about the sockets2.c file attached):
Hi,
some remarks about the file:
>>>>
/** @todo we should replace that by a memp_malloc */
#define MEMP_NUM_SOCKETS MEMP_NUM_NETCONN
<<<<
You return a void* casted to an int as the socket handle. That's a cool
& fast way to implement (I also had that idea some time ago, LOL! :) but
it's getting harder later: You have to provide a simple way for the
FD_SETs select() uses to set/get/delete a file descriptor from an
FD_SET. There are two ways to do it:
a) the linux way: return an int as socket file descriptor, require the
programmer to give the highest fd number, create an array from 0 to
highest_fd_number with one bit for each fd in that range. Set/get/delete
is very fast then (e.g. 'fd_set |= (1<<fd)')
b) the windows way: return a void* as socket handle, implement the
FD_SET as an array of structs containing the void* and a bit for set/not
set. This way, select is slower, but normal operations are faster.
I think by now, I favour the windows way, because select is 'rarely'
used and the rest of the operations are faster. We have to have a look
on sizeof(int) versus sizeof(void*), though! Then, of course, your idea
to replace socket_malloc by memp_malloc is a good one! BTW:
sys_sem_wait(socksem) can be replaced by SYS_ARCH_PROTECT as long as you
don't call any OS-functions in between that could lead to scheduling.
>>>>
<<<<
About the recv mboxes: by now, I favour your idea of somehow including
the ipaddr/port into pbufs for speedup. But that definitively has to be
an option, as it 'wastes' 6 bytes on each pbuf! Or how could we solve
that? I mean, if you have PBUF_POOL size set to 128 bytes, you waste 72
bytes when receiving one packet of 1514 bytes (a full ethernet packet).
I think that's a loss that some can't afford.
>>>>
/** @todo is it possible to directly call tcp_recved? deadlocking case? */
tcp_recved(sock->pcb.tcp, len);
<<<<
I don't think it deadlocks. tcp_recved() calls tcp_output() (through
tcp_ack/tcp_ack_now), which only sends data and doesn't receive, so
pcb->recv shouldn't get called again. We have to watch out for slow
targets, though (where tcp receives faster than the application reads,
especially with the RX-thread having a higher prio than the application
thread).
>>>>
lwip_send
<<<<
That's a hack, isn't it? (The sleep(0), I mean.) while (tosend > 0) and
we get an error from tcp_write, we should block and let the RX task (or
lwip core task) deal with transmission/ACKing which is (aside from
tcp_poll) the only point where ERR_MEM could have gone.
more general:
- using sockets from multiple threads: does that work if we only lock? I
think it should, but there is a problem with lwip_send/tcp_write when
running out of RAM / send-buffer! We would have to lock other writes
until the first has finished to prevent from having both writes mixed
their data.
- about lwip_shutdown: how is it implemented in other stacks? Is a FIN
sent when closing the TX side? For the RX side, can we simply throw away
the data inside sock_tcp_recv?
- set/getsockopt: I think we could combine the test with the 'actual
option processing' to save some code space (the switch is done twice....)
- nonblocking I/O: we should check RX byte counters for nonblocking
recv, TX bufsize for nonblocking send. Nonblocking connect can return
EAGAIN (so we have to remember we are currently in a connect sequence).
What about nonblocking accept, does that exists? Nonblocking close
should be handled by SO_LINGER.
Last but not least (but that can be postponed), I would implement
fastsock functions that return the pbufs directly (to prevent
copy-on-receive) and take pbuf (to prevent copy-on-write, but that's
harder for the programmer) and maybe also RX-callback functions (e.g.
inside sock_tcp_recv/sock_udp_recv, instead of posting to an mbox, call
a callback function) to be even faster and still kind of compatible to
the sockets API. The goal for that would be to remove netconn api in the
future to have only one simple & fast API above the raw API.
OK, this list is somewhat disordered and might not be complete. But I
think the file is a fine start! Thanks for working on that!
(file #13236)
_______________________________________________________
Additional Item Attachment:
_______________________________________________________
Reply to this item at:
<http://savannah.nongnu.org/task/?6994>
_______________________________________________
Message posté via/par Savannah
http://savannah.nongnu.org/
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING,
Frédéric Bernon <=
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Frédéric Bernon, 2007/07/03
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Frédéric Bernon, 2007/07/03
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Frédéric Bernon, 2007/07/03
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Kieran Mansley, 2007/07/06
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Frédéric Bernon, 2007/07/06
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Jonathan Larmour, 2007/07/27
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Frédéric Bernon, 2007/07/27
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Jonathan Larmour, 2007/07/27
- [lwip-devel] [task #6994] Redesign Socket Layer with LWIP_TCPIP_CORE_LOCKING, Frédéric Bernon, 2007/07/27