The checkpatch warning is not present with the CI like version of Ubuntu
[1], I see that on 15.04 it is not a checkpatch issue.

[1] https://hub.docker.com/r/roxell/check-odp-ubuntu/



On 11 December 2015 at 10:18, Mike Holmes <mike.hol...@linaro.org> wrote:

>
>
> On 11 December 2015 at 10:08, Bill Fischofer <bill.fischo...@linaro.org>
> wrote:
>
>> The problem is that this is documentation text (pseudocode) not code and
>> yet some tools insist on trying to treat it as if it's a code patch.
>> Checkpatch should not apply to documentation this way.
>>
>
> In this case then we need to turn all the other spaces to tabs becasue now
> we have a mix.
> I want to keep it consistent one way or the other or reviewing will be
> difficult depending on the viewers tab setting.
>
> +...thread init processing
> +
> +while (1) {
> +        odp_event_t ev;   <-- only this one is newly tabbed
> +       odp_queue_t which_q;
> +       ev = odp_schedule(&which_q, <wait option>);
> +       ...process the event
> +}
> +----
>
>
> I honestly think it is just easier to not use tabs in the docs.
>
>
>
>>
>> On Fri, Dec 11, 2015 at 9:04 AM, Mike Holmes <mike.hol...@linaro.org>
>> wrote:
>>
>>> Using patch:
>>> lng-odp_PATCHv3_doc_userguide_add_application_programming_section.mbox
>>>   Trying to apply patch
>>>   Patch applied
>>> Applying: doc: userguide: add application programming section
>>> /home/mike/git/check-odp/build/odp-apply/.git/rebase-apply/patch:446:
>>> indent with spaces.
>>>         odp_event_t ev;
>>> /home/mike/git/check-odp/build/odp-apply/.git/rebase-apply/patch:613:
>>> indent with spaces.
>>>         odp_init_local();
>>> /home/mike/git/check-odp/build/odp-apply/.git/rebase-apply/patch:616:
>>> indent with spaces.
>>>         while (1) {
>>> /home/mike/git/check-odp/build/odp-apply/.git/rebase-apply/patch:617:
>>> indent with spaces.
>>>        ev = odp_schedule(&which_q, ODP_SCHED_WAIT);
>>> warning: 4 lines add whitespace errors.
>>> 0001-doc-userguide-add-application-programming-section.patch: unified
>>> diff output, UTF-8 Unicode text
>>>
>>> When I look at all these with git show I see a tab got in there rather
>>> than a space which is inconsistent with the rest of the text.
>>>
>>> Do you have the .gitconfig whitespace =
>>> trailing-space,space-before-tab,indent-with-non-tab,error-all if not you
>>> may not be seeing some things.
>>>
>>>
>>>
>>>
>>>
>>> On 8 December 2015 at 17:36, Bill Fischofer <bill.fischo...@linaro.org>
>>> wrote:
>>>
>>>> Complete the reformatting to standard asciidoc style, expand the
>>>> ODP Application Programming section, and include a reorganized and
>>>> expanded discussion of ODP queues.
>>>>
>>>> Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org>
>>>> ---
>>>>  doc/users-guide/users-guide.adoc | 451
>>>> +++++++++++++++++++++++++++++++--------
>>>>  1 file changed, 359 insertions(+), 92 deletions(-)
>>>>
>>>> diff --git a/doc/users-guide/users-guide.adoc
>>>> b/doc/users-guide/users-guide.adoc
>>>> index cf77fa0..d660fb8 100644
>>>> --- a/doc/users-guide/users-guide.adoc
>>>> +++ b/doc/users-guide/users-guide.adoc
>>>> @@ -8,16 +8,19 @@ OpenDataPlane (ODP)  Users-Guide
>>>>  Abstract
>>>>  --------
>>>>  This document is intended to guide a new ODP application developer.
>>>> -Further details about ODP may be found at the 
>>>> http://opendataplane.org[ODP]
>>>> home page.
>>>> +Further details about ODP may be found at the http://opendataplane.org
>>>> [ODP]
>>>> +home page.
>>>>
>>>>  .Overview of a system running ODP applications
>>>>  image::../images/overview.png[align="center"]
>>>>
>>>> -ODP is an API specification that allows many implementations to
>>>> provide platform independence, automatic hardware acceleration and CPU
>>>> scaling to high performance networking  applications.
>>>> -This document describes how to write an application that can
>>>> successfully take advantage of the API.
>>>> +ODP is an API specification that allows many implementations to provide
>>>> +platform independence, automatic hardware acceleration and CPU scaling
>>>> to
>>>> +high performance networking  applications. This document describes how
>>>> to
>>>> +write an application that can successfully take advantage of the API.
>>>>
>>>>  :numbered:
>>>> -== Introduction ==
>>>> +== Introduction
>>>>  .OpenDataPlane Components
>>>>  image::../images/odp_components.png[align="center"]
>>>>
>>>> @@ -42,7 +45,7 @@ ODP API specification--that is the responsibility of
>>>> each ODP implementation.
>>>>  * Application-centric.  Covers functional needs of data plane
>>>> applications.
>>>>  * Ensures portability by specifying the functional behavior of ODP.
>>>>  * Defined jointly and openly by application writers and platform
>>>> implementers.
>>>> -* Archiected to be implementable on a wide range of platforms
>>>> efficiently
>>>> +* Architected to be implementable on a wide range of platforms
>>>> efficiently
>>>>  * Sponsored, governed, and maintained by the Linaro Networking Group
>>>> (LNG)
>>>>
>>>>  .ODP Implementations
>>>> @@ -68,7 +71,7 @@ where the application will run on a target platform
>>>> chosen by someone else.
>>>>  * One size does not fit all--supporting multiple implementations
>>>> allows ODP
>>>>  to adapt to widely differing internals among platforms.
>>>>  * Anyone can create an ODP implementation tailored to their platform
>>>> -* Distribution and mainteinance of each implementation is as owner
>>>> wishes
>>>> +* Distribution and maintenance of each implementation is as owner
>>>> wishes
>>>>    - Open source or closed source as business needs determine
>>>>    - Have independent release cycles and service streams
>>>>  * Allows HW and SW innovation in how ODP APIs are implemented on each
>>>> platform.
>>>> @@ -100,7 +103,7 @@ drivers supported by DPDK.
>>>>  they are derived from a reference implementation.
>>>>
>>>>  .ODP Validation Test Suite
>>>> -Third, to enure consistency between different ODP implementations, ODP
>>>> +Third, to ensure consistency between different ODP implementations, ODP
>>>>  consists of a validation suite that verifies that any given
>>>> implementation of
>>>>  ODP faithfully provides the specified functional behavior of each ODP
>>>> API.
>>>>  As a separate open source component, the validation suite may be used
>>>> by
>>>> @@ -115,16 +118,16 @@ ODP API specification.
>>>>  * Key to ensuring application portability across all ODP
>>>> implementations
>>>>  * Tests that ODP implementations conform to the specified functional
>>>> behavior
>>>>  of ODP APIs.
>>>> -* Can be run at any time by users and vendors to validat
>>>> implementations
>>>> -od ODP.
>>>> +* Can be run at any time by users and vendors to validate
>>>> implementations
>>>> +of ODP.
>>>>
>>>> -=== ODP API Specification Versioning ===
>>>> +=== ODP API Specification Versioning
>>>>  As an evolving standard, the ODP API specification is released under an
>>>>  incrementing version number, and corresponding implementations of ODP,
>>>> as well
>>>>  as the validation suite that verifies API conformance, are linked to
>>>> this
>>>> -version number. ODP versions are specified using a stanard three-level
>>>> +version number. ODP versions are specified using a standard three-level
>>>>  number (major.minor.fixlevel) that are incremented according to the
>>>> degree of
>>>> -change the level represents. Increments to the fixlevel represent
>>>> clarification
>>>> +change the level represents. Increments to the fix level represent
>>>> clarification
>>>>  of the specification or other minor changes that do not affect either
>>>> the
>>>>  syntax or semantics of the specification. Such changes in the API
>>>> specification
>>>>  are expected to be rare. Increments to the minor level
>>>> @@ -136,26 +139,26 @@ the major level represent significant structural
>>>> changes that most likely
>>>>  require some level of application source code change, again as
>>>> documented in
>>>>  the release notes for that version.
>>>>
>>>> -=== ODP Implementation Versioning ===
>>>> +=== ODP Implementation Versioning
>>>>  ODP implementations are free to use whatever release naming/numbering
>>>>  conventions they wish, as long as it is clear what level of the ODP
>>>> API a given
>>>>  release implements. A recommended convention is to use the same three
>>>> level
>>>>  numbering scheme where the major and minor numbers correspond to the
>>>> ODP API
>>>> -level and the fixlevel represents an implementation-defined service
>>>> level
>>>> +level and the fix level represents an implementation-defined service
>>>> level
>>>>  associated with that API level implementation. The LNG-supplied ODP
>>>> reference
>>>>  implementations follow this convention.
>>>>
>>>> -=== ODP Validation Test Suite Versioning ===
>>>> +=== ODP Validation Test Suite Versioning
>>>>  The ODP validation test suite follows these same naming conventions.
>>>> The major
>>>>  and minor release numbers correspond to the ODP API level that the
>>>> suite
>>>> -validates and the fixlevel represents the service level of the
>>>> validation
>>>> +validates and the fix level represents the service level of the
>>>> validation
>>>>  suite itself for that API level.
>>>>
>>>> -=== ODP Design Goals ===
>>>> +=== ODP Design Goals
>>>>  ODP has three primary goals that follow from its component structure.
>>>> The first
>>>>  is application portability across a wide range of platforms. These
>>>> platforms
>>>>  differ in terms of processor instruction set architecture, number and
>>>> types of
>>>> -application processing cores, memory oranization, as well as the
>>>> number and
>>>> +application processing cores, memory organization, as well as the
>>>> number and
>>>>  type of platform specific hardware acceleration and offload features
>>>> that
>>>>  are available. ODP applications can move from one conforming
>>>> implementation
>>>>  to another with at most a recompile.
>>>> @@ -175,7 +178,7 @@ of processing cores that are available to realize
>>>> application function. The
>>>>  result is that an application written to this model does not require
>>>> redesign
>>>>  as it scales from 4, to 40, to 400 cores.
>>>>
>>>> -== Organization of this Document ==
>>>> +== Organization of this Document
>>>>  This document is organized into several sections. The first presents a
>>>> high
>>>>  level overview of the ODP API component areas and their associated
>>>> abstract
>>>>  data types. This section introduces ODP APIs at a conceptual level.
>>>> @@ -190,14 +193,14 @@ full reference specification for each API. The
>>>> latter is intended to be used
>>>>  by ODP application programmers, as well as implementers, to understand
>>>> the
>>>>  precise syntax and semantics of each API.
>>>>
>>>> -== ODP API Concepts ==
>>>> +== ODP API Concepts
>>>>  ODP programs are built around several conceptual structures that every
>>>> -appliation programmer needs to be familiar with to use ODP
>>>> effectively. The
>>>> +application programmer needs to be familiar with to use ODP
>>>> effectively. The
>>>>  main ODP concepts are:
>>>>  Thread, Event, Queue, Pool, Shared Memory, Buffer, Packet, PktIO,
>>>> Timer,
>>>>  and Synchronizer.
>>>>
>>>> -=== Thread ===
>>>> +=== Thread
>>>>  The thread is the fundamental programming unit in ODP.  ODP
>>>> applications are
>>>>  organized into a collection of threads that perform the work that the
>>>>  application is designed to do. ODP threads may or may not share memory
>>>> with
>>>> @@ -209,7 +212,7 @@ A control thread is a supervisory thread that
>>>> organizes
>>>>  the operation of worker threads. Worker threads, by contrast, exist to
>>>>  perform the main processing logic of the application and employ a run
>>>> to
>>>>  completion model. Worker threads, in particular, are intended to
>>>> operate on
>>>> -dedicated processing cores, especially in many core proessing
>>>> environments,
>>>> +dedicated processing cores, especially in many core processing
>>>> environments,
>>>>  however a given implementation may multitask multiple threads on a
>>>> single
>>>>  core if desired (typically on smaller and lower performance target
>>>>  environments).
>>>> @@ -219,7 +222,7 @@ _thread mask_ and _scheduler group_ that determine
>>>> where they can run and
>>>>  the type of work that they can handle. These will be discussed in
>>>> greater
>>>>  detail later.
>>>>
>>>> -=== Event ===
>>>> +=== Event
>>>>  Events are what threads process to perform their work. Events can
>>>> represent
>>>>  new work, such as the arrival of a packet that needs to be processed,
>>>> or they
>>>>  can represent the completion of requests that have executed
>>>> asynchronously.
>>>> @@ -232,7 +235,7 @@ References to events are via handles of abstract
>>>> type +odp_event_t+. Cast
>>>>  functions are provided to convert these into specific handles of the
>>>>  appropriate type represented by the event.
>>>>
>>>> -=== Queue ===
>>>> +=== Queue
>>>>  A queue is a message passing channel that holds events.  Events can be
>>>>  added to a queue via enqueue operations or removed from a queue via
>>>> dequeue
>>>>  operations. The endpoints of a queue will vary depending on how it is
>>>> used.
>>>> @@ -244,7 +247,7 @@ stateful processing on events as well as stateless
>>>> processing.
>>>>
>>>>  Queues are represented by handles of abstract type +odp_queue_t+.
>>>>
>>>> -=== Pool ===
>>>> +=== Pool
>>>>  A pool is a shared memory area from which elements may be drawn. Pools
>>>>  represent the backing store for events, among other things. Pools are
>>>>  typically created and destroyed by the application during
>>>> initialization and
>>>> @@ -256,32 +259,32 @@ are Buffer and Packet.
>>>>
>>>>  Pools are represented by handles of abstract type +odp_pool_t+.
>>>>
>>>> -=== Shared Memory ===
>>>> +=== Shared Memory
>>>>  Shared memory represents raw blocks of storage that are sharable
>>>> between
>>>>  threads. They are the building blocks of pools but can be used
>>>> directly by
>>>>  ODP applications if desired.
>>>>
>>>>  Shared memory is represented by handles of abstract type +odp_shm_t+.
>>>>
>>>> -=== Buffer ===
>>>> +=== Buffer
>>>>  A buffer is a fixed sized block of shared storage that is used by ODP
>>>>  components and/or applications to realize their function. Buffers
>>>> contain
>>>>  zero or more bytes of application data as well as system maintained
>>>>  metadata that provide information about the buffer, such as its size
>>>> or the
>>>>  pool it was allocated from. Metadata is an important ODP concept
>>>> because it
>>>>  allows for arbitrary amounts of side information to be associated with
>>>> an
>>>> -ODP object. Most ODP objects have assocaited metadata and this
>>>> metadata is
>>>> +ODP object. Most ODP objects have associated metadata and this
>>>> metadata is
>>>>  manipulated via accessor functions that act as getters and setters for
>>>> -this information. Getter acces functions permit an application to read
>>>> +this information. Getter access functions permit an application to read
>>>>  a metadata item, while setter access functions permit an application
>>>> to write
>>>>  a metadata item. Note that some metadata is inherently read only and
>>>> thus
>>>>  no setter is provided to manipulate it.  When object have multiple
>>>> metadata
>>>>  items, each has its own associated getter and/or setter access
>>>> function to
>>>>  inspect or manipulate it.
>>>>
>>>> -Buffers are represened by handles of abstract type +odp_buffer_t+.
>>>> +Buffers are represented by handles of abstract type +odp_buffer_t+.
>>>>
>>>> -=== Packet ===
>>>> +=== Packet
>>>>  Packets are received and transmitted via I/O interfaces and represent
>>>>  the basic data that data plane applications manipulate.
>>>>  Packets are drawn from pools of type +ODP_POOL_PACKET+.
>>>> @@ -294,7 +297,7 @@ with each packet for its own use.
>>>>
>>>>  Packets are represented by handles of abstract type +odp_packet_t+.
>>>>
>>>> -=== PktIO ===
>>>> +=== PktIO
>>>>  PktIO is how ODP represents I/O interfaces. A pktio object is a logical
>>>>  port capable of receiving and/or transmitting packets. This may be
>>>> directly
>>>>  supported by the underlying platform as an integrated feature,
>>>> @@ -302,7 +305,7 @@ or may represent a device attached via a PCIE or
>>>> other bus.
>>>>
>>>>  PktIOs are represented by handles of abstract type +odp_pktio_t+.
>>>>
>>>> -=== Timer ===
>>>> +=== Timer
>>>>  Timers are how ODP applications measure and respond to the passage of
>>>> time.
>>>>  Timers are drawn from specialized pools called timer pools that have
>>>> their
>>>>  own abstract type (+odp_timer_pool_t+). Applications may have many
>>>> timers
>>>> @@ -310,7 +313,7 @@ active at the same time and can set them to use
>>>> either relative or absolute
>>>>  time. When timers expire they create events of type +odp_timeout_t+,
>>>> which
>>>>  serve as notifications of timer expiration.
>>>>
>>>> -=== Synchronizer ===
>>>> +=== Synchronizer
>>>>  Multiple threads operating in parallel typically require various
>>>>  synchronization services to permit them to operate in a reliable and
>>>>  coordinated manner. ODP provides a rich set of locks, barriers, and
>>>> similar
>>>> @@ -325,7 +328,7 @@ flow of work through an ODP application. These
>>>> include the Classifier,
>>>>  Scheduler, and Traffic Manager.  These components relate to the three
>>>>  main stages of packet processing: Receive, Process, and Transmit.
>>>>
>>>> -=== Classifier ===
>>>> +=== Classifier
>>>>  The *Classifier* provides a suite of APIs that control packet receive
>>>> (RX)
>>>>  processing.
>>>>
>>>> @@ -362,8 +365,8 @@ Note that the use of the classifier is optional.
>>>> Applications may directly
>>>>  receive packets from a corresponding PktIO input queue via direct
>>>> polling
>>>>  if they choose.
>>>>
>>>> -=== Scheduler ===
>>>> -The *Scheduler* provides a suite of APIs that control scalabable event
>>>> +=== Scheduler
>>>> +The *Scheduler* provides a suite of APIs that control scalable event
>>>>  processing.
>>>>
>>>>  .ODP Scheduler and Event Processing
>>>> @@ -391,10 +394,10 @@ scheduled back to a thread to continue processing
>>>> with the results of the
>>>>  requested asynchronous operation.
>>>>
>>>>  Threads themselves can enqueue events to queues for downstream
>>>> processing
>>>> -by other threads, permitting flexibility in how applicaitions structure
>>>> +by other threads, permitting flexibility in how applications structure
>>>>  themselves to maximize concurrency.
>>>>
>>>> -=== Traffic Manager ===
>>>> +=== Traffic Manager
>>>>  The *Traffic Manager* provides a suite of APIs that control traffic
>>>> shaping and
>>>>  Quality of Service (QoS) processing for packet output.
>>>>
>>>> @@ -413,23 +416,33 @@ goals. Again, the advantage here is that on many
>>>> platforms traffic management
>>>>  functions are implemented in hardware, permitting transparent offload
>>>> of
>>>>  this work.
>>>>
>>>> -Glossary
>>>> ---------
>>>> -[glossary]
>>>> -odp_worker::
>>>> -    An opd_worker is a type of odp_thread. It will usually be isolated
>>>> from the scheduling of any host operating system and is intended for
>>>> fast-path processing with a low and predictable latency. Odp_workers will
>>>> not generally receive interrupts and will run to completion.
>>>> -odp_control::
>>>> -    An odp_control is a type of odp_thread. It will be isolated from
>>>> the host operating system house keeping tasks but will be scheduled by it
>>>> and may receive interrupts.
>>>> -odp_thread::
>>>> -    An odp_thread is a flow of execution that in a Linux environment
>>>> could be a Linux process or thread.
>>>> -event::
>>>> -    An event is a notification that can be placed in a queue.
>>>> -
>>>> -The include structure
>>>> ----------------------
>>>> -Applications only include the 'include/odp.h file which includes the
>>>> 'platform/<implementation name>/include/plat' files to provide a complete
>>>> definition of the API on that platform.
>>>> -The doxygen documentation defining the behavior of the ODP API is all
>>>> contained in the public API files, and the actual definitions for an
>>>> implementation will be found in the per platform directories.
>>>> -Per-platform data that might normally be a #define can be recovered
>>>> via the appropriate access function if the #define is not directly visible
>>>> to the application.
>>>> +== ODP Application Programming
>>>> +At the highest level, an *ODP Application* is a program that uses one
>>>> or more
>>>> +ODP APIs. Because ODP is a framework rather than a programming
>>>> environment,
>>>> +applications are free to also use other APIs that may or may not
>>>> provide the
>>>> +same portability characteristics as ODP APIs.
>>>> +
>>>> +ODP applications vary in terms of what they do and how they operate,
>>>> but in
>>>> +general all share the following characteristics:
>>>> +
>>>> +. They are organized into one or more _threads_ that execute in
>>>> parallel.
>>>> +. These threads communicate and coordinate their activities using
>>>> various
>>>> +_synchronization_ mechanisms.
>>>> +. They receive packets from one or more _packet I/O interfaces_.
>>>> +. They examine, transform, or otherwise process packets.
>>>> +. They transmit packets to one or more _packet I/O interfaces_.
>>>> +
>>>> +ODP provides APIs to assist in each of these areas.
>>>> +
>>>> +=== The include structure
>>>> +Applications only include the 'include/odp.h' file, which includes the
>>>> +'platform/<implementation name>/include/odp' files to provide a
>>>> complete
>>>> +definition of the API on that platform. The doxygen documentation
>>>> defining
>>>> +the behavior of the ODP API is all contained in the public API files,
>>>> and the
>>>> +actual definitions for an implementation will be found in the per
>>>> platform
>>>> +directories. Per-platform data that might normally be a +#define+ can
>>>> be
>>>> +recovered via the appropriate access function if the #define is not
>>>> directly
>>>> +visible to the application.
>>>>
>>>>  .Users include structure
>>>>  ----
>>>> @@ -442,51 +455,305 @@ Per-platform data that might normally be a
>>>> #define can be recovered via the appr
>>>>  │   └── odp.h   This file should be the only file included by the
>>>> application.
>>>>  ----
>>>>
>>>> -Initialization
>>>> ---------------
>>>> -IMPORTANT: ODP depends on the application to perform a graceful
>>>> shutdown, calling the terminate functions should only be done when the
>>>> application is sure it has closed the ingress and subsequently drained all
>>>> queues etc.
>>>> +=== Initialization
>>>> +IMPORTANT: ODP depends on the application to perform a graceful
>>>> shutdown,
>>>> +calling the terminate functions should only be done when the
>>>> application is
>>>> +sure it has closed the ingress and subsequently drained all queues,
>>>> etc.
>>>> +
>>>> +=== Startup
>>>> +The first API that must be called by an ODP application is
>>>> 'odp_init_global()'.
>>>> +This takes two pointers. The first, +odp_init_t+, contains ODP
>>>> initialization
>>>> +data that is platform independent and portable, while the second,
>>>> ++odp_platform_init_t+, is passed unparsed to the implementation
>>>> +to be used for platform specific data that is not yet, or may never be
>>>> +suitable for the ODP API.
>>>> +
>>>> +Calling odp_init_global() establishes the ODP API framework and MUST be
>>>> +called before any other ODP API may be called. Note that it is only
>>>> called
>>>> +once per application. Following global initialization, each thread in
>>>> turn
>>>> +calls 'odp_init_local()' is called. This establishes the local ODP
>>>> thread
>>>> +context for that thread and MUST be called before other ODP APIs may be
>>>> +called by that thread.
>>>> +
>>>> +=== Shutdown
>>>> +Shutdown is the logical reverse of the initialization procedure, with
>>>> +'odp_term_local()' called for each thread before 'odp_term_global()' is
>>>> +called to terminate ODP.
>>>> +
>>>> +.ODP Application Structure Flow Diagram
>>>> +image::../images/resource_management.png[align="center"]
>>>>
>>>> -Startup
>>>> -~~~~~~~~
>>>> -The first API that must be called is 'odp_init_global()'.
>>>> -This takes two pointers, odp_init_t contains ODP initialization data
>>>> that is platform independent and portable.
>>>> -The second odp_platform_init_t is passed un parsed to the
>>>> implementation and can be used for platform specific data that is not yet,
>>>> or may never be suitable for the ODP API.
>>>> +== Common Conventions
>>>> +Many ODP APIs share common conventions regarding their arguments and
>>>> return
>>>> +types. This section highlights some of the more common and frequently
>>>> used
>>>> +conventions.
>>>> +
>>>> +=== Handles and Special Designators
>>>> +ODP resources are represented via _handles_ that have abstract type
>>>> +_odp_resource_t_.  So pools are represented by handles of type
>>>> +odp_pool_t+,
>>>> +queues by handles of type +odp_queue_t+, etc. Each such type
>>>> +has a distinguished type _ODP_RESOURCE_INVALID_ that is used to
>>>> indicate a
>>>> +handle that does not refer to a valid resource of that type. Resources
>>>> are
>>>> +typically created via an API named _odp_resource_create()_ that
>>>> returns a
>>>> +handle of type _odp_resource_t_ that represents the created object.
>>>> This
>>>> +returned handle is set to _ODP_RESOURCE_INVALID_ if, for example, the
>>>> +resource could not be created due to resource exhaustion. Invalid
>>>> resources
>>>> +do not necessarily represent error conditions. For example,
>>>> +ODP_EVENT_INVALID+
>>>> +in response to an +odp_queue_deq()+ call to get an event from a queue
>>>> simply
>>>> +indicates that the queue is empty.
>>>> +
>>>> +=== Addressing Scope
>>>> +Unless specifically noted in the API, all ODP resources are global to
>>>> the ODP
>>>> +application, whether it runs as a single process or multiple
>>>> processes. ODP
>>>> +handles therefore have common meaning within an ODP application but
>>>> have no
>>>> +meaning outside the scope of the application.
>>>> +
>>>> +=== Resources and Names
>>>> +Many ODP resource objects, such as pools and queues, support an
>>>> +application-specified character string _name_ that is associated with
>>>> an ODP
>>>> +object at create time.  This name serves two purposes: documentation,
>>>> and
>>>> +lookup. The lookup function is particularly useful to allow an ODP
>>>> application
>>>> +that is divided into multiple processes to obtain the handle for the
>>>> common
>>>> +resource.
>>>> +
>>>> +== Queues
>>>> +Queues are the fundamental event sequencing mechanism provided by ODP
>>>> and all
>>>> +ODP applications make use of them either explicitly or implicitly.
>>>> Queues are
>>>> +created via the 'odp_queue_create()' API that returns a handle of type
>>>> ++odp_queue_t+ that is used to refer to this queue in all subsequent
>>>> APIs that
>>>> +reference it. Queues have one of two ODP-defined _types_, POLL, and
>>>> SCHED that
>>>> +determine how they are used. POLL queues directly managed by the ODP
>>>> +application while SCHED queues make use of the *ODP scheduler* to
>>>> provide
>>>> +automatic scalable dispatching and synchronization services.
>>>> +
>>>> +.Operations on POLL queues
>>>> +[source,c]
>>>> +----
>>>> +odp_queue_t poll_q1 = odp_queue_create("poll queue 1",
>>>> ODP_QUEUE_TYPE_POLL, NULL);
>>>> +odp_queue_t poll_q2 = odp_queue_create("poll queue 2",
>>>> ODP_QUEUE_TYPE_POLL, NULL);
>>>> +...
>>>> +odp_event_t ev = odp_queue_deq(poll_q1);
>>>> +...do something
>>>> +int rc = odp_queue_enq(poll_q2, ev);
>>>> +----
>>>>
>>>> -The second API that must be called is 'odp_init_local()', this must be
>>>> called once per odp_thread, regardless of odp_thread type.  Odp_threads may
>>>> be of type ODP_THREAD_WORKER or ODP_THREAD_CONTROL
>>>> +The key distinction is that dequeueing events from POLL queues is an
>>>> +application responsibility while dequeueing events from SCHED queues
>>>> is the
>>>> +responsibility of the ODP scheduler.
>>>>
>>>> -Shutdown
>>>> -~~~~~~~~~
>>>> -Shutdown is the logical reverse of the initialization procedure, with
>>>> 'odp_thread_term()' called for each worker before 'odp_term_global()' is
>>>> called.
>>>> +.Operations on SCHED queues
>>>> +[source,c]
>>>> +----
>>>> +odp_queue_param_t qp;
>>>> +odp_queue_param_init(&qp);
>>>> +odp_schedule_prio_t prio = ...;
>>>> +odp_schedule_group_t sched_group = ...;
>>>> +qp.sched.prio = prio;
>>>> +qp.sched.sync = ODP_SCHED_SYNC_[NONE|ATOMIC|ORDERED];
>>>> +qp.sched.group = sched_group;
>>>> +qp.lock_count = n; /* Only relevant for ordered queues */
>>>> +odp_queue_t sched_q1 = odp_queue_create("sched queue 1",
>>>> ODP_QUEUE_TYPE_SCHED, &qp);
>>>> +
>>>> +...thread init processing
>>>> +
>>>> +while (1) {
>>>> +        odp_event_t ev;
>>>> +       odp_queue_t which_q;
>>>> +       ev = odp_schedule(&which_q, <wait option>);
>>>> +       ...process the event
>>>> +}
>>>> +----
>>>>
>>>> -image::../images/resource_management.png[align="center"]
>>>> +With scheduled queues, events are sent to a queue, and the the sender
>>>> chooses
>>>> +a queue based on the service it needs. The sender does not need to know
>>>> +which ODP thread (on which core) or hardware accelerator will process
>>>> +the event, but all the events on a queue are eventually scheduled and
>>>> processed.
>>>> +
>>>> +As can be seen, SCHED queues have additional attributes that are
>>>> specified at
>>>> +queue create that control how the scheduler is to process events
>>>> contained
>>>> +on them. These include group, priority, and synchronization class.
>>>> +
>>>> +=== Scheduler Groups
>>>> +The scheduler's dispatching job is to return the next event from the
>>>> highest
>>>> +priority SCHED queue that the caller is eligible to receive events
>>>> from.
>>>> +This latter consideration is determined by the queues _scheduler
>>>> group_, which
>>>> +is set at queue create time, and by the caller's _scheduler group
>>>> mask_ that
>>>> +indicates which scheduler group(s) it belongs to. Scheduler groups are
>>>> +represented by handles of type +odp_scheduler_group_t+ and are created
>>>> by
>>>> +the *odp_scheduler_group_create()* API. A number of scheduler groups
>>>> are
>>>> +_predefined_ by ODP.  These include +ODP_SCHED_GROUP_ALL+ (all
>>>> threads),
>>>> ++ODP_SCHED_GROUP_WORKER+ (all worker threads), and
>>>> +ODP_SCHED_GROUP_CONTROL+
>>>> +(all control threads). The application is free to create additional
>>>> scheduler
>>>> +groups for its own purpose and threads can join or leave scheduler
>>>> groups
>>>> +using the *odp_scheduler_group_join()* and
>>>> *odp_scheduler_group_leave()* APIs
>>>> +
>>>> +=== Scheduler Priority
>>>> +The +prio+ field of the +odp_queue_param_t+ specifies the queue's
>>>> scheduling
>>>> +priority, which is how queues within eligible scheduler groups are
>>>> selected
>>>> +for dispatch. Queues have a default scheduling priority of NORMAL but
>>>> can be
>>>> +set to HIGHEST or LOWEST according to application needs.
>>>> +
>>>> +=== Scheduler Synchronization
>>>> +In addition to its dispatching function, which provide automatic
>>>> scalability to
>>>> +ODP applications in many core environments, the other main function of
>>>> the
>>>> +scheduler is to provide event synchronization services that greatly
>>>> simplify
>>>> +application programming in a parallel processing environment. A queue's
>>>> +SYNC mode determines how the scheduler handles the synchronization
>>>> processing
>>>> +of multiple events originating from the same queue.
>>>> +
>>>> +Three types of queue scheduler synchronization area supported:
>>>> Parallel,
>>>> +Atomic, and Ordered.
>>>> +
>>>> +==== Parallel Queues
>>>> +SCHED queues that specify a sync mode of ODP_SCHED_SYNC_NONE are
>>>> unrestricted
>>>> +in how events are processed.
>>>> +
>>>> +.Parallel Queue Scheduling
>>>> +image::../images/parallel_queue.png[align="center"]
>>>>
>>>> -Queues
>>>> -------
>>>> -There are three queue types, atomic, ordered and parallel.
>>>> -A queue belongs to a single odp_worker and a odp_worker may have
>>>> multiple queues.
>>>> +All events held on parallel queues are eligible to be scheduled
>>>> simultaneously
>>>> +and any required synchronization between them is the responsibility of
>>>> the
>>>> +application. Events originating from parallel queues thus have the
>>>> highest
>>>> +throughput rate, however they also potentially involve the most work
>>>> on the
>>>> +part of the application. In the Figure above, four threads are calling
>>>> +*odp_schedule()* to obtain events to process. The scheduler has
>>>> assigned
>>>> +three events from the first queue to three threads in parallel. The
>>>> fourth
>>>> +thread is processing a single event from the third queue. The second
>>>> queue
>>>> +might either be empty, of lower priority, or not in a scheduler group
>>>> matching
>>>> +any of the threads being serviced by the scheduler.
>>>> +
>>>> +=== Atomic Queues
>>>> +Atomic queues simplify event synchronization because only a single
>>>> event
>>>> +from a given atomic queue may be processed at a time. Events scheduled
>>>> from
>>>> +atomic queues thus can be processed lock free because the locking is
>>>> being
>>>> +done implicitly by the scheduler.
>>>> +
>>>> +.Atomic Queue Scheduling
>>>> +image::../images/atomic_queue.png[align="center"]
>>>>
>>>> -Events are sent to a queue, and the the sender chooses a queue based
>>>> on the service it needs.
>>>> -The sender does not need to know which odp_worker (on which core) or
>>>> HW accelerator will process the event, but all the events on a queue are
>>>> eventually scheduled and processed.
>>>> +In this example, no matter how many events may be held in an atomic
>>>> queue, only
>>>> +one of them can be scheduled at a time. Here two threads process
>>>> events from
>>>> +two different atomic queues. Note that there is no synchronization
>>>> between
>>>> +different atomic queues, only between events originating from the same
>>>> atomic
>>>> +queue. The queue context associated with the atomic queue is held
>>>> until the
>>>> +next call to the scheduler or until the application explicitly
>>>> releases it
>>>> +via a call to *odp_schedule_release_atomic()*.
>>>>
>>>> -NOTE: Both ordered and parallel queue types improve throughput over an
>>>> atomic queue (due to parallel event processing), but the user has to take
>>>> care of the context data synchronization (if needed).
>>>> +Note that while atomic queues simplify programming, the serial nature
>>>> of
>>>> +atomic queues will impair scaling.
>>>>
>>>> -Atomic Queue
>>>> -~~~~~~~~~~~~
>>>> -Only one event at a time may be processed from a given queue. The
>>>> processing maintains order and context data synchronization but this will
>>>> impair scaling.
>>>> +=== Ordered Queues
>>>> +Ordered queues provide the best of both worlds by providing the
>>>> inherent
>>>> +scaleabilty of parallel queues, with the easy synchronization of atomic
>>>> +queues.
>>>>
>>>> -.Overview Atomic Queue processing
>>>> -image::../images/atomic_queue.png[align="center"]
>>>> +.Ordered Queue Scheduling
>>>> +image::../images/ordered_queue.png[align="center"]
>>>>
>>>> -Ordered Queue
>>>> -~~~~~~~~~~~~~
>>>> -An ordered queue will ensure that the sequencing at the output is
>>>> identical to that of the input, but multiple events may be processed
>>>> simultaneously and the order is restored before the events move to the next
>>>> queue
>>>> +When scheduling events from an ordered queue, the scheduler dispatches
>>>> multiple
>>>> +events from the queue in parallel to different threads, however the
>>>> scheduler
>>>> +also ensures that the relative sequence of these events on output
>>>> queues
>>>> +is identical to their sequence from their originating ordered queue.
>>>> +
>>>> +As with atomic queues, the ordering guarantees associated with ordered
>>>> queues
>>>> +refer to events originating from the same queue, not for those
>>>> originating on
>>>> +different queues. Thus in this figure three thread are processing
>>>> events 5, 3,
>>>> +and 4, respectively from the first ordered queue. Regardless of how
>>>> these
>>>> +threads complete processing, these events will appear in their original
>>>> +relative order on their output queue.
>>>> +
>>>> +==== Order Preservation
>>>> +Relative order is preserved independent of whether events are being
>>>> sent to
>>>> +different output queues.  For example, if some events are sent to
>>>> output queue
>>>> +A while others are sent to output queue B then the events on these
>>>> output
>>>> +queues will still be in the same relative order as they were on their
>>>> +originating queue.  Similarly, if the processing consumes events so
>>>> that no
>>>> +output is issued for some of them (_e.g.,_ as part of IP fragment
>>>> reassembly
>>>> +processing) then other events will still be correctly ordered with
>>>> respect to
>>>> +these sequence gaps. Finally, if multiple events are enqueued for a
>>>> given
>>>> +order (_e.g.,_ as part of packet segmentation processing for MTU
>>>> +considerations), then each of these events will occupy the originator's
>>>> +sequence in the target output queue(s). In this case the relative
>>>> order of these
>>>> +events will be in the order that the thread issued *odp_queue_enq()*
>>>> calls for
>>>> +them.
>>>> +
>>>> +The ordered context associated with the dispatch of an event from an
>>>> ordered
>>>> +queue lasts until the next scheduler call or until explicitly released
>>>> by
>>>> +the thread calling *odp_schedule_release_ordered()*. This call may be
>>>> used
>>>> +as a performance advisory that the thread no longer requires ordering
>>>> +guarantees for the current context. As a result, any subsequent
>>>> enqueues
>>>> +within the current scheduler context will be treated as if the thread
>>>> was
>>>> +operating in a parallel queue context.
>>>> +
>>>> +==== Ordered Locking
>>>> +Another powerful feature of the scheduler's handling of ordered queues
>>>> is
>>>> +*ordered locks*. Each ordered queue has associated with it a number of
>>>> ordered
>>>> +locks as specified by the _lock_count_ parameter at queue create time.
>>>> +
>>>> +Ordered locks provide an efficient means to perform in-order sequential
>>>> +processing within an ordered context. For example, supposed events
>>>> with relative
>>>> +order 5, 6, and 7 are executing in parallel by three different
>>>> threads. An
>>>> +ordered lock will enable these threads to synchronize such that they
>>>> can
>>>> +perform some critical section in their originating queue order. The
>>>> number of
>>>> +ordered locks supported for each ordered queue is implementation
>>>> dependent (and
>>>> +queryable via the *odp_config_max_ordered_locks_per_queue()* API). If
>>>> the
>>>> +implementation supports multiple ordered locks then these may be used
>>>> to
>>>> +protect different ordered critical sections within a given ordered
>>>> context.
>>>> +
>>>> +==== Summary: Ordered Queues
>>>> +To see how these considerations fit together, consider the following
>>>> code:
>>>> +
>>>> +.Processing with Ordered Queues
>>>> +[source,c]
>>>> +----
>>>> +void worker_thread()
>>>> +{
>>>> +        odp_init_local();
>>>> +       ...other initialization processing
>>>> +
>>>> +        while (1) {
>>>> +               ev = odp_schedule(&which_q, ODP_SCHED_WAIT);
>>>> +               ...process events in parallel
>>>> +               odp_schedule_order_lock(0);
>>>> +               ...critical section processed in order
>>>> +               odp_schedule_order_unlock(0);
>>>> +               ...continue processing in parallel
>>>> +               odp_queue_enq(dest_q, ev);
>>>> +       }
>>>> +}
>>>> +----
>>>>
>>>> -.Overview Ordered Queue processing
>>>> -image::../images/ordered_queue.png[align="center"]
>>>> +This represents a simplified structure for a typical worker thread
>>>> operating
>>>> +on ordered queues. Multiple events are processed in parallel and the
>>>> use of
>>>> +ordered queues ensures that they will be placed on +dest_q+ in the
>>>> same order
>>>> +as they originated.  While processing in parallel, the use of ordered
>>>> locks
>>>> +enables critical sections to be processed in order within the overall
>>>> parallel
>>>> +flow. When a thread arrives at the _odp_schedule_order_lock()_ call,
>>>> it waits
>>>> +until the locking order for this lock for all prior events has been
>>>> resolved
>>>> +and then enters the critical section. The
>>>> _odp_schedule_order_unlock()_ call
>>>> +releases the critical section and allows the next order to enter it.
>>>>
>>>> -Parallel Queue
>>>> -~~~~~~~~~~~~~~
>>>> -There are no restrictions on the number of events being processed.
>>>> +=== Queue Scheduling Summary
>>>>
>>>> -.Overview parallel Queue processing
>>>> -image::../images/parallel_queue.png[align="center"]
>>>> +NOTE: Both ordered and parallel queues improve throughput over atomic
>>>> queues
>>>> +due to parallel event processing, but require that the application take
>>>> +steps to ensure context data synchronization if needed.
>>>> +
>>>> +== Glossary
>>>> +[glossary]
>>>> +worker thread::
>>>> +    A worker is a type of ODP thread. It will usually be isolated from
>>>> +    the scheduling of any host operating system and is intended for
>>>> fast-path
>>>> +    processing with a low and predictable latency. Worker threads will
>>>> not
>>>> +    generally receive interrupts and will run to completion.
>>>> +control thread::
>>>> +    A control threadis a type of ODP thread. It will be isolated from
>>>> the host
>>>> +    operating system house keeping tasks but will be scheduled by it
>>>> and may
>>>> +    receive interrupts.
>>>> +thread::
>>>> +    An ODP thread is a flow of execution that in a Linux environment
>>>> could be
>>>> +    a Linux process or thread.
>>>> +event::
>>>> +    An event is a notification that can be placed in a queue.
>>>> +queue::
>>>> +    A communication channel that holds events
>>>> --
>>>> 2.1.4
>>>>
>>>> _______________________________________________
>>>> lng-odp mailing list
>>>> lng-odp@lists.linaro.org
>>>> https://lists.linaro.org/mailman/listinfo/lng-odp
>>>>
>>>
>>>
>>>
>>> --
>>> Mike Holmes
>>> Technical Manager - Linaro Networking Group
>>> Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM
>>> SoCs
>>>
>>>
>>>
>>
>
>
> --
> Mike Holmes
> Technical Manager - Linaro Networking Group
> Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
>
>
>


-- 
Mike Holmes
Technical Manager - Linaro Networking Group
Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to