Personally I don't see any need for segmentation support in buffers. I am just trying to shoot down what I think is flawed reasoning.
-- Ola#1 On 17 October 2014 15:03, Ola Liljedahl <[email protected]> wrote: > 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
