This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

BSD send() => BSD_ENOMEM

Hi,

I'm actually implementing a webserver with multiple threads and sockets listening to port 80.

The MDK is version 5.29.

Assuming the BSD send() can be called from different threads for different sockets, I don't understand the return value BSD_ENOMEM, which I sometimes get.

All these error return values are not really described in detail. "Not enough memory" for BSD_ENOMEM is not really helpful.

  • Which memory got low?
    I tried to play with the Ethernet core memory (NET_MEM_POOL_SIZE), the heap and all involved stack sizes of the KEIL driver.
    No luck. Can't get rid of this error.

It does not happen very often. Let's say 1 out of 5000 send() calls.

It happens in blocking & non-blocking mode.

Any help is appreciated.

Michael

  • "Not enough memory" means the available memory in the memory pool got low.

    There is only one memory pool used in the Network component. It is configured with NET_MEM_POOL_SIZE macro. Default value is 12000 bytes.

    Try to double the pool size to 24000 bytes or more.

    Check also the thread priorities of your socket threads. The priorities should be the same as the priority of the Network Core thread, which is osPriorityNormal by default.

    If you still get this error, add osThreadYield() after each BSD send(). Maybe sending large data blocks fills the dynamic memory, before the Network Core thread gets a chance to process TCP ACKs. Stream sockets keep a shadow copy of the data being sent for a possible retransmission. Received ACKs then release the data from the shadow copy, thus freeing the memory pool.

    You might also try to send the data in smaller data blocks, or add a short osDelay() after BSD send()..

    Take a look at the select() function. It allows you to run your WEB server from a single thread only.

  • Hi Frank!

    First let me thank you for your complete and professional answer! I really appreciate it.

    • I forgot to mention that our webserver is from Segger.
    • I was assuming that the involved memory buffer is the net mem pool and I already played with the size.
      But also increasing the buffer to 60k didn't solve the problem.
      Instead I discovered a strange behavior of the enabled DHCP client: With some big values of the buffer size, the DHCP client didn't receive an IP address anymore (netDHCP_Notify() wasn't triggered anymore). But that is going to be subject of another post ;-)
    • I'm going to obey your tips with the task handling functions and give you feedback.
    • "Sending smaller blocks": Do you suggest sizing down the maximal TCP segment size or a manual segmentation on my side before I give the data to the send() function?

    Again thanks for the help.

    Michael
    Pittsburgh, USA

  • Why can't I see the answer anymore? 

  • I also saw it, but now it's gone.

    This happens sometimes.

    :(

    it's probably got moderated - hopefully it will reappear in due course ...

  • The thread was marked as having an 'Accepted Answer' before the answer was visible!