But segmentation is already needed in a current and known subclass (i.e.
packets). We are not talking about some other feature which we don't know
if it will be needed. So this is not a case of "just in case".

-- Ola#1


On 17 October 2014 14:45, Ola Dahl <[email protected]> wrote:

> Hi,
>
> I do not think it is wise to put features in the base class "just in case"
> they would be needed in some future (not yet known) subclass.
>
> So if the concept of segmentation is relevant for packets but not for
> timers then I think it should be implemented as a feature of packets.
>
> Best regards,
>
> Ola D
>
> On Fri, Oct 17, 2014 at 2:33 PM, Bill Fischofer <[email protected]
> > wrote:
>
>> I agree that packets are the buffer type that most likely uses segments,
>> however there are many advantages to putting this support in the base class
>> rather than the subclass independent of the number of buffer subclasses
>> that will use this support today.
>>
>>    - It's simpler
>>    - It's more extensible
>>    - It results in cleaner and more efficient application code
>>
>> Allow me to expand on these points.  First simplicity.  Call the work
>> required to support segmentation in the implementation X.  That X is going
>> to be pretty much constant no matter where it is done.  But if the
>> implementation has a choice between doing X at a low level vs. doing it at
>> a high level then it's simpler for the implementation to do it once and be
>> done with it.  If the implementation does it at a higher level then it is
>> either constrained to map that higher-level implementation to be built on a
>> set of lower-level functions that may or may not be appropriate or else it
>> needs to do a completely parallel implementation that is optimal but highly
>> duplicative.
>>
>> Extensibility should be clear.  If at some future point we decide
>> segmentation would be useful for some new buffer type (e.g., IPC) then
>> that's trivial to do if the base class supports it and awkward if it's only
>> part of packets.
>>
>> From an application standpoint, it's cleaner because the packet APIs are
>> just wrappers around their corresponding buffer APIs and can be mapped
>> directly.  Otherwise we have a set of APIs that don't map and are not
>> easily translatable.
>>
>> With regard to efficient segment access, that's what the
>> odp_packet_addr() routine provides--one-step fast-path addressability to
>> the first segment of a packet.  An odp_packet_t is an abstract opaque
>> type.  It is not, and cannot be treated as an address by the application.
>>
>> Does that make sense?
>>
>> Bill
>>
>>
>>
>>
>> On Fri, Oct 17, 2014 at 5:37 AM, Savolainen, Petri (NSN - FI/Espoo) <
>> [email protected]> wrote:
>>
>>>  Hi,
>>>
>>>
>>>
>>> 1. The only segmentation use case is for segmented packet, not for
>>> segmented buffers.
>>>
>>>
>>>
>>> 2. Common case for packets is that everything application needs is in
>>> the first segment. Odp_packet_t could refer always into that “first
>>> segment”, so that application (in the common case) would not need to use
>>> odp_packet_seg_xxx() calls at all – only odp_packet_xxx() calls.
>>>
>>>
>>>
>>> When buffer level features are minimized, the need for
>>> odp_buffer_xxx(odp_packet_to_buffer(pkt),...) is minimized. All packet
>>> manipulation should happen through odp_packet_xxx(pkt, …) calls.
>>>
>>>
>>>
>>>
>>>
>>> -Petri
>>>
>>>
>>>
>>>
>>>
>>> *From:* ext Bill Fischofer [mailto:[email protected]]
>>> *Sent:* Friday, October 17, 2014 1:17 PM
>>> *To:* Savolainen, Petri (NSN - FI/Espoo)
>>> *Cc:* ext Jacob, Jerin; [email protected]
>>>
>>> *Subject:* Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support API
>>>
>>>
>>>
>>> I'm not sure how to understand these two statements:
>>>
>>>
>>>
>>> 1. There's no use case for segmented buffers
>>>
>>> 2. We should optimize for the common case (with segments)
>>>
>>>
>>>
>>> These seem contradictory.
>>>
>>>
>>>
>>> The use case for segmented buffers is that some platforms have a
>>> HW-defined and managed segmented buffer model. If we insist that the
>>> application be able to specify and control packet segment sizes we are
>>> making the decision to exclude such platforms from supporting ODP.  The
>>> optimization suggested is precisely what is being proposed here.  By
>>> default packets are assumed to be contained in implementation-managed
>>> segmented buffers and the first segment will be large enough to contain all
>>> packet headers for non-pathological cases.  The case where the application
>>> wishes to traverse the entire packet in SW is expected to be rare because
>>> in the data plane you simply do not have the cycles to do this at line rate
>>> for all packets.
>>>
>>>
>>>
>>> As for having both odp_buffer_xxx() and odp_packet_xxx() APIs, this is
>>> simply syntax to avoid the constant need for explicit conversion functions
>>> since unlike C++, C does not support generic functions.  So you cannot pass
>>> an odp_packet_t to a function that expects an odp_buffer_t argument without
>>> a conversion call.  Do we really want to force applications to constantly
>>> be writing code like:
>>>
>>>
>>>
>>> odp_buffer_xxx(odp_packet_to_buffer(pkt),...)
>>>
>>>
>>>
>>> rather than
>>>
>>>
>>>
>>> odp_packet_xxx(pkt,...)
>>>
>>>
>>>
>>> Not only is this awkward, it is also inefficient.  By having the
>>> explicit odp_packet_xxx() calls, the implementation is free to optimize
>>> these references in whatever manner is appropriate to that implementation.
>>> For some this may be a simple preprocessor-type expansion while for others
>>> there may be more sophisticated handling.  But the application should
>>> neither know nor care about how the implementation chooses to do this.
>>>
>>>
>>>
>>> On Fri, Oct 17, 2014 at 2:27 AM, Savolainen, Petri (NSN - FI/Espoo) <
>>> [email protected]> wrote:
>>>
>>> Hi,
>>>
>>>
>>>
>>> This is also my opinion. There’s no use case for segmented buffers in
>>> v1.0 - so let’s keep it simple and define that buffers (and thus buffer
>>> pools) are always unsegmented. Segmentation comes into play only with
>>> packets (and only with those packets that cannot fit into a single buffer).
>>> For example, if implementation has max buffer size 256, any packets larger
>>> than that are segmented and segments are handled with packet_seg_xxx calls.
>>>
>>>
>>>
>>> Also, I’d propose that we optimize for the common case (with segments) -
>>> so that the odp_packet_t handle would refer always to the head of packet
>>> segment. If the first segment (data/data_len pointed by the odp_packet_t)
>>> carries all data application is interested in (=protocol headers), the
>>> application would not have to use the segment API at all. Most applications
>>> would not see any difference between small/large or segmented/unsegmented
>>> packets as long as all headers fit into the first segment.
>>>
>>>
>>>
>>> -Petri
>>>
>>>
>>>
>>>
>>>
>>> *From:* [email protected] [mailto:
>>> [email protected]] *On Behalf Of *ext Jacob, Jerin
>>> *Sent:* Friday, October 17, 2014 9:34 AM
>>> *To:* Bill Fischofer
>>> *Cc:* [email protected]
>>> *Subject:* Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support API
>>>
>>>
>>>
>>> The need for segment API infrastructure is very clear.The question is,
>>> Do we need separate APIs for
>>>
>>> segment management at odp_buffer_segment* AND odp_packet_segment* levels
>>> ?
>>>
>>> as ODP_BUFFER_TYPE_TIMEOUT and ODP_BUFFER_TYPE_RAW will be always
>>> unsegmented and if there is a
>>>
>>> API for odp_packet_segement* then there will be not be any consumer for
>>> odp_buffer_segment* API for 1.0​
>>>
>>>
>>>  ------------------------------
>>>
>>> *From:* Bill Fischofer <[email protected]>
>>> *Sent:* Thursday, October 16, 2014 9:08 PM
>>> *To:* Jacob, Jerin
>>> *Cc:* Ola Liljedahl; Balasubramanian Manoharan; [email protected]
>>> *Subject:* Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support API
>>>
>>>
>>>
>>> From the buffer design doc (p. 8-9):
>>>  *Buffer Pool Options*
>>>
>>> The *odp_buffer_opts_e* enum is used to specify additional options
>>> relating to the buffer pool.  Buffer pool options defined are:
>>>
>>>
>>> ·     ODP_BUFFER_OPTS_NONE
>>>
>>> ·     ODP_BUFFER_OPTS_UNSEGMENTED
>>>
>>>
>>> These options are additive so an application can simply specify a
>>> buf_opts by ORing together the options needed.  Note that buffer pool
>>> options are themselves OPTIONAL and a given implementation MAY fail the
>>> buffer pool creation request with an appropriate *errno* if the
>>> requested option is not supported by the underlying ODP implementation,
>>> with the exception that UNSEGMENTED pools MUST be supported for non-packet
>>> types and for packet types as long as the requested size is less than the
>>> implementation-defined native packet segment size.
>>>
>>>
>>> Use ODP_BUFFER_OPTS_NONE to specify default buffer pool options with no
>>> additions.  The ODP_BUFFER_OPTS_UNSEGMENTED option specifies that the
>>> buffer pool should be unsegmented.
>>>
>>>
>>> So unsegmented buffer pool support is available.  As far as RAW buffers
>>> go, again from the doc (p. 14):
>>>  *ODP_BUFFER_TYPE_RAW*
>>>
>>> This is the “basic” buffer type which simply consists of a single
>>> fixed-sized block of contiguous memory.  Buffers of this type do not
>>> support user meta data and the only built-in meta data supported for this
>>> type of buffer are those that are statically computable, such as pool and
>>> size. This type of buffer is entirely under application control and most of
>>> the buffer APIs defined in this document are not available.  APIs for this
>>> type of buffer are described in this document.
>>>
>>>
>>>
>>> So RAW buffers are always unsegmented.  The intent is that Packets are
>>> by default segmented but can be unsegmented while the other buffer types
>>> are by default unsegmented but (with the exception of RAW buffers) can be
>>> made segmented.  This is because all buffers start out as a single segment
>>> and hence are unsegmented until they are expanded to overflow that single
>>> segment.
>>>
>>>
>>>
>>> Hope that clarifies things.  Again, this is all very straightforward and
>>> only comes into play when actually needed.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Wed, Oct 8, 2014 at 4:03 AM, Jacob, Jerin <
>>> [email protected]> wrote:
>>>
>>> If there is no valid use case for supporting segmentation for raw
>>> buffers then lets drop it. At least it will reduce the effort of
>>>
>>> implementing and testing/verification buffer APIs on  different
>>> platforms.
>>>
>>>
>>>   ------------------------------
>>>
>>> *From:* [email protected] <
>>> [email protected]> on behalf of Ola Liljedahl <
>>> [email protected]>
>>> *Sent:* Wednesday, October 8, 2014 1:37 PM
>>> *To:* Balasubramanian Manoharan
>>> *Cc:* [email protected]
>>> *Subject:* Re: [lng-odp] [ODP/PATCH v1] ODP Buffer Segment Support API
>>>
>>>
>>>
>>> As I wrote in my comment to the architecture discussion yesterday, I am
>>> against segmentation for buffers. Or at least there must be the possibility
>>> to create a buffer pool with guaranteed non-segmented buffers. Segmented
>>> packets are OK but not all usages for buffers relate to packets. A lot of
>>> internal usages (timeouts, SW messages, internal data structures) will not
>>> be able to handle segmented buffers so *you must be able to force the
>>> creation of buffer pools with non-segmented buffers.*
>>>
>>>
>>>
>>> -- Ola
>>>
>>>
>>>
>>>
>>>
>>> On 8 October 2014 09:50, Balasubramanian Manoharan <
>>> [email protected]> wrote:
>>>
>>> This patch contains ODP Buffer Management missing APIs
>>> The intent of this patch is to port the missing APIs from Buffer
>>> Management design document into Linux-generic repo.
>>> The dummy functions will be replaced during linux-generic implementation.
>>>
>>> Signed-off-by: Balasubramanian Manoharan <[email protected]>
>>> ---
>>>  platform/linux-generic/include/api/odp_buffer.h    | 203
>>> ++++++++++++++++++++-
>>>  .../linux-generic/include/api/odp_buffer_pool.h    |  30 +++
>>>  platform/linux-generic/odp_buffer.c                | 120 ++++++++++++
>>>  platform/linux-generic/odp_buffer_pool.c           |   7 +
>>>  4 files changed, 351 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/platform/linux-generic/include/api/odp_buffer.h
>>> b/platform/linux-generic/include/api/odp_buffer.h
>>> index d8577fd..aeb75ed 100644
>>> --- a/platform/linux-generic/include/api/odp_buffer.h
>>> +++ b/platform/linux-generic/include/api/odp_buffer.h
>>> @@ -28,8 +28,34 @@ extern "C" {
>>>   */
>>>  typedef uint32_t odp_buffer_t;
>>>
>>> -#define ODP_BUFFER_INVALID (0xffffffff) /**< Invalid buffer */
>>> +/**
>>> +* ODP buffer segment
>>> +*/
>>> +typedef uint32_t odp_buffer_segment_t;
>>>
>>> +/**
>>> +* ODP buffer type
>>> +*/
>>> +typedef enum odp_buffer_type {
>>> +       ODP_BUFFER_TYPE_INVALID = -1,   /**< Buffer type invalid */
>>> +       ODP_BUFFER_TYPE_ANY = 0,        /**< Buffer that can hold any
>>> other
>>> +                                       buffer type */
>>> +       ODP_BUFFER_TYPE_RAW = 1,        /**< Raw buffer,
>>> +                                       no additional metadata */
>>> +       ODP_BUFFER_TYPE_PACKET = 2,     /**< Packet buffer */
>>> +       ODP_BUFFER_TYPE_TIMEOUT = 3     /**< Timeout buffer */
>>> +} odp_buffer_type_e;
>>> +
>>> +/**
>>> +* ODP buffer options
>>> +*/
>>> +typedef enum odp_buffer_opts {
>>> +       ODP_BUFFER_OPTS_NONE,
>>> +       ODP_BUFFER_OPTS_UNSEGMENTED
>>> +} odp_buffer_opts_e;
>>> +
>>> +#define ODP_BUFFER_INVALID (0xffffffff) /**< Invalid buffer */
>>> +#define ODP_SEGMENT_INVALID (0xffffffff) /**< Invalid segment */
>>>
>>>  /**
>>>   * Buffer start address
>>> @@ -58,14 +84,6 @@ size_t odp_buffer_size(odp_buffer_t buf);
>>>   */
>>>  int odp_buffer_type(odp_buffer_t buf);
>>>
>>> -#define ODP_BUFFER_TYPE_INVALID (-1) /**< Buffer type invalid */
>>> -#define ODP_BUFFER_TYPE_ANY       0  /**< Buffer that can hold any other
>>> -                                         buffer type */
>>> -#define ODP_BUFFER_TYPE_RAW       1  /**< Raw buffer, no additional
>>> metadata */
>>> -#define ODP_BUFFER_TYPE_PACKET    2  /**< Packet buffer */
>>> -#define ODP_BUFFER_TYPE_TIMEOUT   3  /**< Timeout buffer */
>>> -
>>> -
>>>  /**
>>>   * Tests if buffer is valid
>>>   *
>>> @@ -76,6 +94,110 @@ int odp_buffer_type(odp_buffer_t buf);
>>>  int odp_buffer_is_valid(odp_buffer_t buf);
>>>
>>>  /**
>>> + * Tests if buffer is segmented
>>> + *
>>> + * @param[in]  buf     Buffer handle
>>> + *
>>> + * @return             1 if buffer has more than one segment,
>>> + *                     otherwise 0
>>> + */
>>> +
>>> +int odp_buffer_is_segmented(odp_buffer_t buf);
>>> +
>>> +/**
>>> + * Get address and size of user meta data associated with a buffer
>>> + *
>>> + * @param[in]  buf             Buffer handle
>>> + * @param[out] udata_size      Number of bytes of user meta data
>>> available
>>> + *                             at the returned address
>>> + * @return                     Address of the user meta data for this
>>> buffer
>>> + *                             or NULL if the buffer has no user meta
>>> data.
>>> + */
>>> +void *odp_buffer_udata(odp_buffer_t buf, size_t *udata_size);
>>> +
>>> +/**
>>> + * Get address of user meta data associated with a buffer
>>> + *
>>> + * @param[in]  buf     Buffer handle
>>> + *
>>> + * @return             Address of the user meta data for this buffer
>>> + *                     or NULL if the buffer has no user meta data.
>>> + */
>>> +void *odp_buffer_udata_addr(odp_buffer_t buf);
>>> +
>>> +/**
>>> + * Get count of number of segments in a buffer
>>> + *
>>> + * @param[in]  buf     Buffer handle
>>> + *
>>> + * @return             Count of the number of segments in buf
>>> + */
>>> +size_t odp_buffer_segment_count(odp_buffer_t buf);
>>> +
>>> +/**
>>> + * Get the segment identifier for a buffer segment by index
>>> + *
>>> + * @param[in]  buf     Buffer handle
>>> + * @param[in]  ndx     Segment index of segment of interest
>>> + *
>>> + * @return             Segment identifier or ODP_SEGMENT_INVALID if the
>>> + *                     supplied ndx is out of range.
>>> + */
>>> +odp_buffer_segment_t odp_buffer_segment_by_index(odp_buffer_t buf,
>>> size_t ndx);
>>> +
>>> +/**
>>> + * Get the next segment identifier for a buffer segment
>>> + *
>>> + * @param[in]  buf     Buffer handle
>>> + * @param[in]  seg     Segment identifier of the previous segment
>>> + *
>>> + * @return             Segment identifier of the next segment,
>>> +                       or ODP_SEGMENT_INVALID.
>>> + */
>>> +odp_buffer_segment_t odp_buffer_segment_next(odp_buffer_t buf,
>>> +                                            odp_buffer_segment_t seg);
>>> +/**
>>> + * Get start address for a specified buffer segment
>>> + *
>>> + * @param[in]  buf     Buffer handle
>>> + * @param[in]  seg     Segment identifier of the buffer to be addressed
>>> + * @param[out] seglen  Returned number of bytes in this buffer
>>> + *                     segment available at returned address
>>> + *
>>> + * @return             Segment start address or NULL
>>> + */
>>> +void *odp_buffer_segment_map(odp_buffer_t buf, odp_buffer_segment_t seg,
>>> +size_t *seglen);
>>> +
>>> +/**
>>> + *Unmap a buffer segment
>>> + *
>>> + * @param[in]  seg     Buffer segment handle
>>> + */
>>> +void odp_buffer_segment_unmap(odp_buffer_segment_t seg);
>>> +
>>> +/**
>>> +* Get start address for a specified buffer offset
>>> +*
>>> +* @param[in]   buf     Buffer handle
>>> +* @param[in]   offset  Byte offset within the buffer to be addressed
>>> +* @param[out]  seglen  Returned number of bytes in this buffer
>>> +*                      segment available at returned address
>>> +*
>>> +* @return              Offset start address or NULL
>>> +*/
>>> +void *odp_buffer_offset_map(odp_buffer_t buf, size_t offset,
>>> +size_t *seglen);
>>> +
>>> +/**
>>> + * Unmap a buffer segment by offset
>>> + *
>>> + * @param[in]  buf     Buffer handle
>>> + * @param[in]  offset  Buffer offset
>>> + */
>>> +void odp_buffer_offset_unmap(odp_buffer_t buf, size_t offset);
>>> +
>>> +/**
>>>   * Print buffer metadata to STDOUT
>>>   *
>>>   * @param buf      Buffer handle
>>> @@ -83,6 +205,69 @@ int odp_buffer_is_valid(odp_buffer_t buf);
>>>   */
>>>  void odp_buffer_print(odp_buffer_t buf);
>>>
>>> +/**
>>> + * Split a buffer into two buffers at a specified split point
>>> + *
>>> + * @param[in]  buf     Handle of buffer to split
>>> + * @param[in]  offset  Byte offset within buf to split buffer
>>> + *
>>> + * @return             Buffer handle of the created split buffer
>>> + */
>>> +odp_buffer_t odp_buffer_split(odp_buffer_t buf, size_t offset);
>>> +
>>> +/**
>>> + * Join two buffers into a single buffer
>>> + *
>>> + * @param[in]  buf1    Buffer handle of first buffer to join
>>> + * @param[in]  buf2    Buffer handle of second buffer to join
>>> + *
>>> + * @return             Buffer handle of the joined buffer
>>> + */
>>> +odp_buffer_t odp_buffer_join(odp_buffer_t buf1, odp_buffer_t buf2);
>>> +
>>> +/**
>>> + * Trim a buffer at a specified trim point
>>> + *
>>> + * @param[in]  buf     Buffer handle of buffer to trim
>>> + * @param[in]  offset  byte offset within buf to trim
>>> + *
>>> + * @return             Handle of the trimmed buffer or
>>> + *                     ODP_BUFFER_INVALID if the operation was not
>>> performed
>>> + */
>>> +odp_buffer_t odp_buffer_trim(odp_buffer_t buf, size_t offset);
>>> +/**
>>> + * Extend a buffer for a specified number of bytes
>>> + *
>>> + * @param[in]  buf     Buffer handle of buffer to expand
>>> + * @param[in]  ext     size, in bytes, of the extent to add to the
>>> + *                     existing buffer.
>>> + *
>>> + * @return             Handle of the extended buffer or
>>> ODP_BUFFER_INVALID
>>> + *                     if the operation was not performed
>>> + */
>>> +odp_buffer_t odp_buffer_extend(odp_buffer_t buf, size_t ext);
>>> +
>>> +/**
>>> + * Clone a buffer, returning an exact copy of it
>>> + *
>>> + * @param[in]  buf     Buffer handle of buffer to duplicate
>>> + *
>>> + * @return             Handle of the duplicated buffer or
>>> ODP_BUFFER_INVALID
>>> + *                     if the operation was not performed
>>> + */
>>> +odp_buffer_t odp_buffer_clone(odp_buffer_t buf);
>>> +
>>> +/**
>>> + * Copy a buffer, returning an exact copy of it
>>> + *
>>> + * @param[in]  buf     Buffer handle of buffer to copy
>>> + *
>>> + * @return             Handle of the copied buffer or ODP_BUFFER_INVALID
>>> + *                     if the operation was not performed
>>> + */
>>> +odp_buffer_t odp_buffer_copy(odp_buffer_t buf);
>>> +
>>> +
>>>
>>>  #ifdef __cplusplus
>>>  }
>>> diff --git a/platform/linux-generic/include/api/odp_buffer_pool.h
>>> b/platform/linux-generic/include/api/odp_buffer_pool.h
>>> index fe88898..f85d96c 100644
>>> --- a/platform/linux-generic/include/api/odp_buffer_pool.h
>>> +++ b/platform/linux-generic/include/api/odp_buffer_pool.h
>>> @@ -52,6 +52,27 @@ odp_buffer_pool_t odp_buffer_pool_create(const char
>>> *name,
>>>
>>>
>>>  /**
>>> + * Get the next buffer pool from its predecessor
>>> + *
>>> + * @param[in]  pool            Buffer pool handle
>>> + * @param[out] name            Name of the pool
>>> + *                             (max ODP_BUFFER_POOL_NAME_LEN - 1 chars)
>>> + * @param[out] udata_size      Size of user meta data used by this pool.
>>> + * @param[out] buf_num         Number of buffers contained in this pool
>>> + * @param[out] buf_size        Default size of application data in each
>>> buffer
>>> + * @param[out] buf_type        Buffer type of the pool
>>> + * @param[out] buf_opts        Buffer options for this pool
>>> + * @param[out] predef          Predefined (1) or Created (0).
>>> + *
>>> + * @return                     Buffer pool handle
>>> + */
>>> +odp_buffer_pool_t odp_buffer_pool_next(odp_buffer_pool_t pool,
>>> +                                      char *name, size_t *udata_size,
>>> +                                      size_t *buf_num, size_t *buf_size,
>>> +                                      enum odp_buffer_type *buf_type,
>>> +                                      enum odp_buffer_opts *buf_opts,
>>> +                                      uint32_t *predef);
>>> +/**
>>>   * Find a buffer pool by name
>>>   *
>>>   * @param name      Name of the pool
>>> @@ -80,6 +101,15 @@ void odp_buffer_pool_print(odp_buffer_pool_t pool);
>>>   */
>>>  odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool);
>>>
>>> +/**
>>> +* Allocate a buffer from a buffer pool
>>> +*
>>> +* @param[in]   pool    Pool handle
>>> +* @param[in]   size    Size of object to store in buffer
>>> +*
>>> +* @return              Buffer handle or ODP_BUFFER_INVALID
>>> +*/
>>> +odp_buffer_t odp_buffer_alloc_size(odp_buffer_pool_t pool, size_t size);
>>>
>>>  /**
>>>   * Buffer free
>>> diff --git a/platform/linux-generic/odp_buffer.c
>>> b/platform/linux-generic/odp_buffer.c
>>> index e54e0e7..7f4b4f0 100644
>>> --- a/platform/linux-generic/odp_buffer.c
>>> +++ b/platform/linux-generic/odp_buffer.c
>>> @@ -45,6 +45,21 @@ int odp_buffer_is_valid(odp_buffer_t buf)
>>>         return (handle.index != ODP_BUFFER_INVALID_INDEX);
>>>  }
>>>
>>> +int odp_buffer_is_segmented(odp_buffer_t buf)
>>> +{
>>> +       odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(buf);
>>> +
>>> +       if (buf_hdr->scatter.num_bufs == 0)
>>> +               return 0;
>>> +       else
>>> +               return 1;
>>> +}
>>> +
>>> +size_t odp_buffer_segment_count(odp_buffer_t buf)
>>> +{
>>> +       odp_buffer_hdr_t *buf_hdr = odp_buf_to_hdr(buf);
>>> +       return (size_t)buf_hdr->scatter.num_bufs + 1;
>>> +}
>>>
>>>  int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf)
>>>  {
>>> @@ -101,8 +116,113 @@ void odp_buffer_print(odp_buffer_t buf)
>>>         printf("\n%s\n", str);
>>>  }
>>>
>>> +void *odp_buffer_udata(odp_buffer_t buf, size_t *udata_size)
>>> +{
>>> +       (void)buf;
>>> +       (void)udata_size;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> +void *odp_buffer_udata_addr(odp_buffer_t buf)
>>> +{
>>> +       (void)buf;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> +odp_buffer_segment_t odp_buffer_segment_by_index(odp_buffer_t buf,
>>> +                                                size_t ndx)
>>> +{
>>> +       (void)buf;
>>> +       (void)ndx;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> +odp_buffer_segment_t odp_buffer_segment_next(odp_buffer_t buf,
>>> +                                            odp_buffer_segment_t seg)
>>> +{
>>> +       (void)buf;
>>> +       (void)seg;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> +void *odp_buffer_segment_map(odp_buffer_t buf, odp_buffer_segment_t seg,
>>> +                            size_t *seglen)
>>> +{
>>> +       (void)buf;
>>> +       (void)seg;
>>> +       (void)seglen;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +void *odp_buffer_offset_map(odp_buffer_t buf, size_t offset,
>>> +size_t *seglen)
>>> +{
>>> +       (void)buf;
>>> +       (void)offset;
>>> +       (void)seglen;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +void odp_buffer_offset_unmap(odp_buffer_t buf, size_t offset)
>>> +{
>>> +       (void)buf;
>>> +       (void)offset;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return;
>>> +}
>>> +
>>>  void odp_buffer_copy_scatter(odp_buffer_t buf_dst, odp_buffer_t buf_src)
>>>  {
>>>         (void)buf_dst;
>>>         (void)buf_src;
>>>  }
>>> +
>>> +odp_buffer_t odp_buffer_split(odp_buffer_t buf, size_t offset)
>>> +{
>>> +       (void)buf;
>>> +       (void)offset;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> +odp_buffer_t odp_buffer_join(odp_buffer_t buf1, odp_buffer_t buf2)
>>> +{
>>> +       (void)buf1;
>>> +       (void)buf2;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> +odp_buffer_t odp_buffer_trim(odp_buffer_t buf, size_t offset)
>>> +{
>>> +       (void)buf;
>>> +       (void)offset;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +odp_buffer_t odp_buffer_extend(odp_buffer_t buf, size_t ext)
>>> +{
>>> +       (void)buf;
>>> +       (void)ext;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> +odp_buffer_t odp_buffer_clone(odp_buffer_t buf)
>>> +{
>>> +       (void)buf;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> +odp_buffer_t odp_buffer_copy(odp_buffer_t buf)
>>> +{
>>> +       (void)buf;
>>> +       ODP_UNIMPLEMENTED();
>>> +       return 0;
>>> +}
>>> +
>>> diff --git a/platform/linux-generic/odp_buffer_pool.c
>>> b/platform/linux-generic/odp_buffer_pool.c
>>> index a48d7d6..bff4db5 100644
>>> --- a/platform/linux-generic/odp_buffer_pool.c
>>> +++ b/platform/linux-generic/odp_buffer_pool.c
>>> @@ -471,6 +471,13 @@ odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t
>>> pool_hdl)
>>>         return handle.u32;
>>>  }
>>>
>>> +odp_buffer_t odp_buffer_alloc_size(odp_buffer_pool_t pool, size_t size)
>>> +{
>>> +       (void)pool;
>>> +       (void) size;
>>> +       ODP_ERR("%s function is yet to be implemented", __func__);
>>> +       return 0;
>>> +}
>>>
>>>  void odp_buffer_free(odp_buffer_t buf)
>>>  {
>>> --
>>> 2.0.1.472.g6f92e5f
>>>
>>>
>>> _______________________________________________
>>> lng-odp mailing list
>>> [email protected]
>>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> lng-odp mailing list
>>> [email protected]
>>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>>
>>>
>>>
>>>
>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> [email protected]
>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>
>>
>
> _______________________________________________
> lng-odp mailing list
> [email protected]
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to