SOMemOpt

Syntax

#include <cafe.h>
#include <cafe/network.h>

/*
 * SOMemOpt Reqs
 */
#define SO_MEMOPT_REQ_INIT                   0x01
#define SO_MEMOPT_REQ_ASYNC_CHECK_INIT       0x02
#define SO_MEMOPT_REQ_SYNC_CHECK_INIT        0x03
#define SO_MEMOPT_REQ_ABORT_SYNC_CHECK_INIT  0x04

/*
 * SOMemOpt flags
 */
#define SO_MEMOPT_FLAG_OPT_UDP 0x01

int SOMemOpt(int req_type, char* mem, unsigned int memlen, int flags);

Parameters

req_type Pointer to buffer which is used for data transfer.
SO_MEMOPT_REQ_INIT Initialize socket buffers inside user space memory. SOMemOpt with this request blocks until SOFinish is called.
SO_MEMOPT_REQ_ASYNC_CHECK_INIT Check whether initialization (performed by SO_MEMOPT_REQ_INIT) is done or not.
SO_MEMOPT_REQ_SYNC_CHECK_INIT Check whether initialization (performed by SO_MEMOPT_REQ_INIT) is done or not. SOMemOpt with this request blocks until initialization with SO_MEMOPT_REQ_INIT is properly done.
SO_MEMOPT_REQ_ABORT_SYNC_CHECK_INIT Abort blocking SOMemOpt called with SO_MEMOPT_REQ_SYNC_CHECK_INIT.
mem Pointer to buffer which is used for data transfer.
  • It needs to be allocated from MEM2.
  • It should be aligned to PPC IPC cache boundary for efficient socket buffer allocation.
  • It is NOT ALLOWED to write something in mem while SOMemOpt is blocking.
It is used only when SO_MEMOPT_REQ_INIT is passed to req_type.
memlen The length of mem. It needs to be bigger than 128KB, less than 3MB.
It is used only when SO_MEMOPT_REQ_INIT is passed to req_type.
flags Flags to pass if needed.
SO_MEMOPT_FLAGS_OPT_UDP Optimize socket buffer allocation for UDP data transfer. It is effective with req_type of SO_MEMOPT_REQ_INIT only.

Return Values

For req_type Result
SO_MEMOPT_REQ_INIT Upon success, the call will remain blocked and will be unblocked with -1 and errno==SO_EABORTED when SOFinish is called. Upon failure, it returns immediately with -1 and errno is set appropriately.
SO_MEMOPT_REQ_ASYNC_CHECK_INIT Upon success, when initialization is already completed, it returns a positive value indicating the number of bytes of memory available for the socket buffers. Note that this value is a rough estimate, and is not the total amount of memory an application can consume for socket buffers because some is used to maintain the socket buffers. 0 is returned when initialization is not completed yet. Upon failure, it returns with -1 and errno is set appropriately upon failure.
SO_MEMOPT_REQ_SYNC_CHECK_INIT The call returns when another instance of SOMemOpt is called with req_type of SO_MEMOPT_REQ_INIT and the required processing and initialization of the passed memory buffer is successfully completed. Upon success, it returns a positive value indicating the number of bytes of memory available for the socket buffers. Note that this value is a rough estimate, and is not the total amount of memory an application can consume for socket buffers because some is used to maintain the socket buffers.

It is unblocked with -1 and errno==SO_EABORTED when another instance of SOMemOpt is called with req_type of SO_MEMOPT_REQ_ABORT_SYNC_CHECK_INIT.

Upon failure, it returns with -1 and errno is set appropriately.
SO_MEMOPT_REQ_ABORT_SYNC_CHECK_INIT 0 upon success. Upon failure, it returns immediately with -1 and errno is set appropriately.

Errors

SO_ELIBNOTREADY Socket library is not initialized.
SO_ENOMEM Insufficient memory in the stack.
SO_EINVAL Specified argument is invalid (e.g. req_type is invalid, mem is NULL).
SO_EMSGSIZE Specified memlen is invalid.
SO_EALREADY SOMemOpt is already blocking previously called operation.
It is returned in following cases.
  • SOMemOpt with req_type of SO_MEMOPT_REQ_SYNC_INIT is called when another instance of SOMemOpt with same type of req_type is already blocking operation.
  • SOMemOpt with req_type of SO_MEMOPT_REQ_SYNC_CHECK_INIT is called when another instance of SOMemOpt with same type of req_type is already blocking operation.
SO_EFAULT Abnormal operation occurred in the stack.
SO_EBUSY Socket resource manager busy processing requests.
SO_EABORTED Indicates the operation was aborted.
SO_EUNKNOWN Unknown error.
SO_ERANGEINVALID Internal API error, invalid error code.
SO_EAPIERROR Internal API error.

Description

SOMemOpt passes memory to the system which is used for TCP/UDP data transfer performed by the application. The system allocates socket buffers in provided buffer and uses it only for data transfer performed by the application. Note that this API with req_type of SO_MEMOPT_REQ_SYNC_INIT (which is the request type for initialization) is blocking call and it is NOT UNBLOCKED until SO library is finalized by SOFinish. This call must be made using a different thread in the application. The buffer passed to mem should be used exclusively only for this API, and it is NOT ALLOWED to write to the buffer mem from the application while SOMemOpt is blocking.

Providing buffer using SOMemOpt sets up dedicated memory which is used exclusively only for the socket receive buffer of the application (SO_RCVBUF). For example, if a memory buffer of 512KB is passed to SOMemOpt, and four sockets are configured each with 64KB of SO_RCVBUF. In this scenario, the application will always have the full 64KB memory available for receiving packets on each socket as this memory is used exclusively only for the application and is not shared with any other socket users inside the system. Refer to the Background section below for further description.

The application which expects only UDP data transfer may pass SO_MEMOPT_FLAGS_OPT_UDP to flags. Passing this flag optimizes socket buffer allocation for UDP data transfer. The application which expects more small TCP data transfer (less than 160 bytes of data excluding TCP header) also may use this flag.

Notes

Advantages

Drawbacks

Background

Normally TCP/UDP data transfer is performed with the socket buffers (as known as SO_RCVBUF for ingress and SO_SNDBUF for egress) which are prepared inside the system. These socket buffers are shared by all the socket users inside the system, not dedicated for the application. Data transfer performed by the application gets affected while other socket users in the system are consuming socket buffers (e.g. The socket which is created by the application and configured to use 64KB of SO_RCVBUF, may not be able to use fully 64KB at the moment when there is insufficient socket buffers due to consumption by other socket users inside system). Refer to Efficient Memory Utilization section in Overview for further information about the behavior.

Initialization

It is not mandatory but the application may call SOMemOpt with req_type of SO_MEMOPT_REQ_SYNC_CHECK_INIT or SO_MEMOPT_REQ_ASYNC_CHECK_INIT to check whether initialization performed by SOMemOpt with req_type of SO_MEMOPT_REQ_INIT is completed or not. Since SOMemOpt is blocked when it is called with req_type of SO_MEMOPT_REQ_INIT, initialization is done implicitly inside the system. The application may wait few milliseconds or use this feature in this situation.

Refer Return Values section for returned values in each case.

Steps to initialize

  1. Initialize SO library by SOInit.
  2. Allocate aligned buffer from MEM2.
  3. [Optional]Call SOMemOpt with req_type of SO_MEMOPT_REQ_SYNC_CHECK_INIT
    or
    call SOMemOpt with req_type of SO_MEMOPT_REQ_ASYNC_CHECK_INIT in a while loop.
  4. Call SOMemOpt with req_type of SO_MEMOPT_REQ_INIT by specifying allocated buffer to mem (and the length of mem to memlen) in other thread.
  5. [Optional]SOMemOpt called with req_type of SO_MEMOPT_REQ_SYNC_CHECK_INIT is returned with positive value when initialization is completed.
    or
    SOMemOpt called with req_type of SO_MEMOPT_REQ_ASYNC_CHECK_INIT returns positive value.
  6. Create socket by SOSocket.
  7. Enable SO_RUSRBUF option by SOSetSockOpt.
  8. Enable SO_WINSCALE by SOSetSockOpt.
  9. Configure SO_RCVBUF size by SOSetSockOpt.
  10. Perform any data transfers.

Demo

There is a flag to enable this feature in $CAFE_ROOT/system/src/demo/speedtest/speedtest.c. Set APP_MEMORY_WAIT_BY_BLOCKING to 1 to use this feature in speedtest demo (see here for description of the speedtest demo).

Set APP_MEMORY_WAIT_BY_BLOCKING to 1 to perform blocking operation to check completion of initialization (which uses SO_MEMOPT_REQ_SYNC_CHECK_INIT). Otherwise set it to 0 to perform non-blocking operation (which uses SO_MEMOPT_REQ_ASYNC_CHECK_INIT).

After SO library is initialized by SOInit, it creates new thread and call SOMemOpt with req_type of SO_MEMOPT_REQ_INIT to initialize socket buffers in this thread. Then it waits initialization gets completed by SOMemOpt with req_type of SO_MEMOPT_REQ_SYNC_CHECK_INIT or SO_MEMOPT_REQ_ASYNC_CHECK_INIT. After it is initialized properly, it sets SO_RUSRBUF by SOSetSockOpt and sets 256KB to SO_RCVBUF. Following HTTP download is performed with socket buffers allocated inside provide memory.

Do Not Call From

Callbacks Do not call this function from any callback function.
Interrupt handler Do not call this function from any interrupt handler.
Exception handler Do not call this function from any exception handler.

See Also

SOSetSockOpt

Revision History

2014/07/03 Initial version.


CONFIDENTIAL