This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Socket close, reconnect and memory free

Hi,

When a socket is created, mmBulkAlloc() is called internally and the memory for sockets buffers (including TX and RX) from the standard heap.

I have a few questions about this procedure and the opposite, socket close and memory free.

1 - Which function calls mmBulkAlloc?
2 - How should I close the socket?
    I've looked at NDK_INSTALL_DIR\packages\ti\ndk\tools\console\console.c
    but I didn't quite understand it.
    Should I use shutdown(stcp_child2, SHUT_RDWR) or    fdClose( stcp_child2 )?
    Which socket should be closed? Child, parent or both?
    After closing the socket, what should be done next?
    Create a new socket using socket() or just accept() a new connection?
3 - How the socket memory is freed. I'm trying to use fdclose() and socket shutdown(), but the socket memory is not freed when I try to use a new socket I get a mmBulkAlloc error of memory overflow.
I could increase the heap, but with a lot of reconnects we would have an overflow anyway.

Thanks

  • Hi Johns_,

    Which version of the NDK are you using?

    What type of socket are you creating and working with?

    Johns_ said:
    1 - Which function calls mmBulkAlloc?

    When you create a new socket, it calls SockNew() [ti/ndk/stack/sock/sock.c], which then calls SBNew() [/ti/ndk/stack/res/sb.c] which calls mmBulkAlloc to make the allocation.

    Johns_ said:
    2 - How should I close the socket?

    You should close a socket by calling the fdClose() API.

    Johns_ said:
        After closing the socket, what should be done next?
        Create a new socket using socket() or just accept() a new connection?

    Yes, you should create a new socket using the socket() API.

    Johns_ said:
    3 - How the socket memory is freed.

    fdClose() calls SockClose().  It should call SockIntAbort which calls SBFree.

    Can you verify this by halting at your call to fdClose(), then putting break points at these functions and running?  Do you see the call chain as I described?

    Also, have you seen the ROV tool in CCS (tools -> RTOS Object Viewer)?  This tool will show you a heap view, including free and allocated blocks.  This tool is useful in debugging memory allocation/free issues.

  • Hi Steven,

    Thanks for your answers.

    Steven Connell said:
    Which version of the NDK are you using?

    NDK 2.22.0.06

    SYS/BIOS 6.33.6.50

    XDC 3.24.5.48

    Steven Connell said:
    What type of socket are you creating and working with?

    It's a TCP socket, IP v4 and STREAMNC.

    Steven Connell said:

    Can you verify this by halting at your call to fdClose(), then putting break points at these functions and running?  Do you see the call chain as I described?

    Also, have you seen the ROV tool in CCS (tools -> RTOS Object Viewer)?  This tool will show you a heap view, including free and allocated blocks.  This tool is useful in debugging memory allocation/free issues.

    I see the assembly code for this chain, but when it reaches the fdClose instruction it enters the llEnter() and then goes to idle task and never reaches SockClose or SockIntAbort (I put a breakpoint in the addresses of SockClose and SockIntAbort but they're never reached). Also, in ROV the free size of my heap doesn't increase after a fdClose() call.

    Do you have any idea what could be causing this?

    Thanks and regards.

    J.

  • Hmm, that's not what I was expecting.  Does it ever reach SBFree, it only idles?

    I'll have to have a closer look at this and get back to you tomorrow...

    Thanks for your patience.

    Steve

  • Hi Steven,

    After it enters llEnter() the next thing that I can see is that it goes to idle and never reaches the breakpoint in SBFree (neither the one in SockClose). But the C instructions that follow fdClose() are executed and it goes to the reconnection label, but with the same amount of free memory.

    SBFree is only reached when I try to accept a new connection and there's not enough free memory, but after the mmBulkFree I can't see the heap free memory increase in ROV.

    Thanks for your help.

    J.

  • Johns_

    I made a small test for this.  Can you give it a try and see if you see similar results?  I ran the following code (as a Task) on an ARM9 (using evmOMAPL138, I'm not sure which device you're on...):

    Void tcpHandler(UArg arg0, UArg arg1)
    {
        SOCKET lSocket;

        // total heap free: 0x1c8f0
        fdOpenSession(TaskSelf());

        // total heap free: 0x1c8d0 (-32 bytes)

        lSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        // total heap free: 0x188c0 (-16K bytes). (this reflects 8K TCP send and 8K TCP recv buffer allocations)

        fdClose(lSocket);

        // total heap free: 0x1c8d0 (+16K bytes). (this reflects 8K TCP send and 8K TCP recv buffers being freed)

        fdCloseSession(TaskSelf());

        // total heap free: 0x1c8f0 (+32 bytes)
    }

    I've attached the full example for reference (7288.hello_heapsTest.zip)

    Also, here's the TCP buffer sizes:

  • Johns_,

    Minor update to the above ... I realized after I posted that you are using non-copy sockets.  I tried the above test again with a non-copy socket and the results are near identical, with the difference being only 8K of buffer is allocated by the sock() call (since no receive buffer is allocated for the socket).

    Steve

  • Hi Steve,

    Thanks four your answer, it helped me solve my problem.

    The problem that I was getting was with two tasks using the same socket, so I had to do a fdclose in both tasks. Now it's working.

    I also tried closing the socket just after creating it, like you showed (using copy mode socket with Tx buffer size = Rx buffer size), but just half the memory is freed. Maybe I'm missing something.

    Thanks and regards.

    J.