lwip-devel
[Top][All Lists]
Advanced

[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/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]