On Wed, Oct 29, 2014 at 12:48 PM, Ciprian Barbu
<[email protected]> wrote:
> On Fri, Oct 24, 2014 at 5:51 PM, Mike Holmes <[email protected]> wrote:
>> Add guidelines for the ODP implimenter to follow.
>>
>> Signed-off-by: Mike Holmes <[email protected]>
>> ---
>>  api_guide_lines.dox | 144 
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 144 insertions(+)
>>  create mode 100644 api_guide_lines.dox
>>
>> diff --git a/api_guide_lines.dox b/api_guide_lines.dox
>> new file mode 100644
>> index 0000000..4944947
>> --- /dev/null
>> +++ b/api_guide_lines.dox
>> @@ -0,0 +1,144 @@
>> +/* Copyright (c) 2043, Linaro Limited
>> + * All rights reserved
>> + *
>> + * SPDX-License-Identifier:     BSD-3-Clause
>> + */
>> +
>> +/**
>> +
>> +@page api_guide_lines  API Guide Lines
>> +
>> +@tableofcontents
>> +
>> +@section introduction Introduction
>> +ODP APIs are implemented as callable C functions that often return a typed 
>> value.
>> +This document describes the approach to handling return values and error 
>> indications expected of conforming ODP implementations.
>> +As such it should be regarded as providing guidelines for how to create new 
>> ODP APIs.
>> +
>> +@section functional Functional Definition
>> +This section defines the use of data types, calling conventions, and return 
>> codes used by ODP APIs.
>> +All ODP APIs MUST follow these conventions as part of their design.
>> +
>> +@subsection naming Naming Conventions
>> +All ODP APIs begin with the prefix odp_ and those that describe an action 
>> to be performed on an object follow the naming convention of object followed 
>> by action.
>
> Note that not all ODP APIs start with odp_, we also have
> odph_packet_alloc, which is wrong to begin with in my opinion, because
> the ODP Packet Management API names this API odp_packet_alloc.
>
>> +The advantage of this approach is that an alphabetical list of APIs for an 
>> object all sort together since they all have names of the form 
>> odp_object_action().
>> +
>> +So for example the API call to allocate a buffer is named 
>> odp_buffer_alloc() rather than odp_alloc_buffer().
>> +
>> +@subsection data_types Data Types and Use of typedef
>> +ODP is designed to allow broad variability in how APIs are implemented on 
>> various platforms.
>> +To support this, most APIs operate on abstract data types that are defined 
>> via typedef on a per-implementation basis.
>> +These abstract types follow the naming convention of odp_object_t.
>> +
>> +Typedefs that encapsulate C structs follow the convention:
>> +
>> +@code
>> +typedef struct odp_<descriptive_name> {
>> +...
>> +} odp_<descriptive_name>_t;
>> +@endcode
>> +
>> +The use of typedef allows implementations to choose underlying data 
>> representations that map efficiently to platform capabilities while 
>> providing accessor functions to provide structured access to implementation 
>> information in a portable manner
>> +Similarly, the use of enum is RECOMMENDED to provide value abstraction for 
>> API parameters while enabling the implementation to choose code points that 
>> map well to platform native values
>
> Final <dot> to end sentence here.
>
>> +
>> +Several native C types are used conventionally within ODP and SHOULD be 
>> employed in API design:
>> +
>> +type | Correct use
>> + |---| :---------
>> +void | SHOULD be used for APIs that do not return a value
>
> Full stop.
>
>> +void*| SHOULD be used for APIs that return a pointer intended to be used by 
>> the caller as a pointer.  For example, a routine that returns the address of 
>> an application context area SHOULD use a void * return type
>
> Maybe reformulate as: SHOULD be used for APIs that return a pointer
> intended to be used by the caller *as such*. Just a suggestion, you
> can leave it like this if you think it's clearer. Also missing full
> stop.
>
>> +int  | SHOULD be used for APIs that return a boolean value.  The values 1 = 
>> true, 0 = false are used for this purpose. Similarly, int SHOULD also be 
>> used for APIs that return a simple success/failure indication to the caller. 
>>  In this case the return value 0 indicates success while non-zero (typically 
>> -1) indicates failure and errno is set to a reason code that indicates the 
>> nature of the failure.
>> +
>> +@subsection parameters Parameter Structure and Validation
>> +ODP is a framework for use in the data plane.
>> +Data plane applications typically have extreme performance requirements 
>> mandating very strict attention to path length considerations in the design 
>> of all ODP APIs, with the exception of those designed to be used 
>> infrequently such as only during initialization or termination processing.
>> +
>> +Minimizing pathlength in API design involves several considerations:
>> + - The number of parameters passed to a call.  In general, ODP APIs 
>> designed for frequent use SHOULD have few parameters.  Limiting parameter 
>> count to one or two well-chosen parameters SHOULD be the goal for APIs 
>> designed for frequent use.  If a call requires more complex parameter data 
>> then it is RECOMMENDED that instead of multiple parameters a single pointer 
>> to a struct that can be statically templated and modified by the caller be 
>> used.
>> + - The use of macros and inlining.  ODP APIs MAY be implemented as 
>> preprocessor macros and/or inline functions.  This is especially true for 
>> accessor functions that are designed to provide getters/setters for object 
>> meta data.
>> + - Limiting parameter validation and error-checking processing.  While 
>> useful for development and debugging, providing “bullet-proof” APIs that 
>> perform extensive parameter validation and error checking is often 
>> inappropriate.  While validations that can be performed statically at 
>> compile time or at little to no runtime cost SHOULD be considered, APIs MAY 
>> choose to leave behavior as undefined when presented with invalid parameters 
>> in the interest of runtime efficiency.
>> +
>> +One of the reasons for using abstract types is to avoid having 
>> implementation knowledge “bleed through” the API, leading to possible 
>> parameter errors.
>> +When one API returns an opaque token to an application it is reasonable to 
>> expect that the application can pass that token to subsequent APIs without 
>> needing expensive runtime validation.
>> +
>> +ODP provides the helper APIs ODP_STATIC_ASSERT(cond,msg) and 
>> ODP_ASSERT(cond,msg)  that SHOULD be used in implementations for performing 
>> appropriate validation.
>> +The former is a compile-time assertion and hence adds no additional path 
>> length.
>> +The latter is controlled by the ODP_NO_DEBUG compile-time switch and so is 
>> suitable for use in development/debug builds that can be compiled out for 
>> production use.
>> +Other mechanisms available to the implementer are:
>> + - ODP_ABORT() is provided for situations where further execution of the 
>> code must not occur and a level of tracing information should be left in the 
>> log.
>> + - ODP_DEPRECATED() is used to signify that a call is planned for 
>> obsolescence.
>> + - ODP_LOG() is used to direct implementation messages to the application.
>> +
>> +
>> +@subsection function_calls Function Calls
>> +ODP APIs typically have prototypes of the form:
>> +
>> +@code
>> +odp_return_type_t odp_api(p1_type p1, p2_type p2, …);
>> +@endcode
>> +Where:
>> +
>> +type              | Description
>> + |---------       | :---------
>> +odp_return_type_t | Is the return value produced by the API call.  As noted 
>> above, the native types void, void *, and int are also used. Other APIs 
>> return abstract types defined via typedef
>> +p1_type           | Is the data type of the first parameter
>> +p2_type           | Is the data type of the second parameter, etc.
>> +
>> +For ODP APIs that return void, results are undefined if the input 
>> parameters are invalid.
>> +For those that return void *, the value ODP_NULL or ODP_INVALID MAY be used 
>> to indicate call failure.
>> +For non-boolean APIs returning int, a return value of 0 indicates success 
>> while non-zero indicates failure.
>
> I thought we are only supposed to use 0 and 1. It was stated like this
> above (at least that's what I understand from it) when mentioning
> boolean type.

Ignore this, I rushed to conclusions.

>
>> +
>> +@subsection errno Use of errno
>> +ODP APIs SHOULD make use of the thread-local variable errno, defined in the 
>> standard library include file errno.h,  to indicate a reason for an API call 
>> failure when appropriate.
>> +This convention allows callers to easily determine success/failure of a 
>> call with a single test and then decode the failure as desired from the 
>> extended reason provided by errno.
>> +So, for example, an attempt to allocate a buffer from a buffer pool might 
>> return ODP_BUFFER_INVALID if the call was unsuccessful and errno could then 
>> be set to an appropriate reason (no storage available (ENOMEM, ENOBUFS), 
>> pool not recognized (EINVAL), etc.).
>> +
>> +In general APIs are free to define their own errno usage conventions and 
>> values or reuse standard errno values when appropriate.
>> +When “standard” codes exist, implementations SHOULD make use of them so 
>> that standard utility functions like perror() can decode them intelligently.
>> +There are, however, a small set of standard codes that are commonly used.
>> +One errno value that MUST be present for all APIs is 
>> ODP_FUNCTION_NOT_AVAILABLE.
>> +This special reason code is used to indicate that the underlying 
>> implementation does not support the requested API, and SHOULD be equated to 
>> ENOSYS.
>> +This may be because the requested API is specifically designated as 
>> OPTIONAL or that the caller is using a pre-release version of an API that 
>> does not have all functionality implemented yet.
>> +
>> +Another standard errno is ODP_IMPLEMENTATION_LIMIT.
>> +This code SHOULD be used if a API call is made that exceeds a permitted 
>> limit of the underlying implementation, and SHOULD be equated to ERANGE.
>> +For example, many APIs MAY mandate certain minimum functionality but 
>> provide latitude on maximums.
>> +An example of this might be the number of queues that an application can 
>> create.
>> +An attempt to allocate more queues than the underlying implementation 
>> supports would result in this failure code being returned via errno
>
> Full stop.
>
>> +
>> +@subsection boolean Boolean
>> +For odp booleans are integers (int)
>> +The values 1 = true, 0 = false are used for this purpose.
>
> Boolean mentioned again, 1 and 0 only valid, see previous comment.
>
>> +
>> +@subsection success Success and Failure
>> +Pass indications are integers (int) and SHOULD also be used for APIs that 
>> return a simple success/failure indication to the caller.
>> +In this case the return value 0 indicates success while non-zero (typically 
>> -1) indicates failure and errno is set to a reason code that indicates the 
>> nature of the failure.
>> +
>> +
>> +@section implementation Implementation Considerations
>> +To support application portability and preserve implementation flexibility, 
>> ODP APIs MUST be designed with several guiding principles in mind.
>> +
>> +@subsection application_view Application View vs. Implementation View
>> +ODP APIs MUST present an application view of a problem in their externals.
>> +That is, the API should allow the application to specify what it wants to 
>> do while the underlying implementation of that API controls how the 
>> requested function is realized.
>> +As a result, ODP APIs SHOULD NOT be designed with a specific implementation 
>> in mind.
>> +This is the reason, for example, that packet I/O in ODP follows a queued 
>> model.
>> +It is an implementation responsibility to determine how packets are 
>> physically read and written, and whatever internal structures are needed to 
>> perform this most efficiently are an implementation rather than an 
>> application concern.
>> +In some platforms this may involve the use of receive rings and buffer 
>> bursting, while in others this may be a simple memory-mapped register 
>> operation to interface with a hardware packet scheduler/distributor.
>> +The ODP application does not care, how packets arrive for processing, only 
>> that a packet is available for it to work on.
>
> First comma, is that, necessary (after does not care) ?
>
>> +
>> +Similarly, ODP applications reference packets data fields in terms of the 
>> information that is needed, rather than focusing on how that information is 
>> obtained.
>> +The assumption is that the underlying implementation has pre-parsed the 
>> packet to extract the most relevant data as packet meta data that is 
>> immediately available to the application without requiring the application 
>> to do this work itself.
>> +Over time, as network speeds increase, more and higher level networking 
>> functions are expected to migrate directly into hardware and ODP APIs MUST 
>> be mindful of this evolution in their design.
>> +
>> +@subsection essential_functions Essential functions vs. Extensions
>> +At the same time, APIs SHOULD reflect essential needs of data plane 
>> application programming and SHOULD NOT strive to offer comprehensive 
>> solutions to every possible contingency.
>> +How to draw this line is a judgement call based on experience but API 
>> designers MUST take implementation practicalities into consideration when 
>> designing APIs to ensure that APIs and features can be implemented 
>> efficiently on a wide variety of underlying platforms.
>> +This is one of the reasons why some features MAY be defined as OPTIONAL.
>> +While allowed, the proliferation of OPTIONAL features SHOULD be avoided to 
>> enable broad application portability across many implementations.
>> +At the same time, a “least common denominator” approach MUST NOT be taken 
>> as that defeats the purpose of providing higher-level abstractions in APIs
>
> Full stop.
>
>> +
>> +@section defaults Default behaviours
>> +When an API has a default behaviour it must be possible for the application 
>> to explicitly call for that behaviour, this guards against the default 
>> changing and breaking the application.
>
> Everything else looks good, nice write up :-)
>
>> +
>> +*/
>> --
>> 2.1.0
>>
>>
>> _______________________________________________
>> 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