From patchwork Tue May 3 19:28:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Fischofer X-Patchwork-Id: 67096 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp767745qge; Tue, 3 May 2016 12:28:40 -0700 (PDT) X-Received: by 10.50.38.129 with SMTP id g1mr5808817igk.34.1462303720611; Tue, 03 May 2016 12:28:40 -0700 (PDT) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id if11si73607igb.1.2016.05.03.12.28.39; Tue, 03 May 2016 12:28:40 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 9BF9461570; Tue, 3 May 2016 19:28:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id A701860073; Tue, 3 May 2016 19:28:21 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 3052A61068; Tue, 3 May 2016 19:28:17 +0000 (UTC) Received: from mail-oi0-f42.google.com (mail-oi0-f42.google.com [209.85.218.42]) by lists.linaro.org (Postfix) with ESMTPS id 41C2C60072 for ; Tue, 3 May 2016 19:28:14 +0000 (UTC) Received: by mail-oi0-f42.google.com with SMTP id x201so39287107oif.3 for ; Tue, 03 May 2016 12:28:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=PmxI3WZ1zXotRhPblKWpt8zJy4sgv1ZhW5vARFGD1fI=; b=Ti/j6VSRnE0WKr2SDPo3RPDwnRFcChJS8x6xSXB5vN4pp2DFk4FrLiExtrF1evPmRl 8x+duIfyr3J+TTVaRQkIDmG4AMJ/cT5QoCkAYTLdTQGfTdlxyXUGGD+ag+hfiNXNzejs JWbpi/i+Qku0427Ix6wwQkNuW1eGiFtwpaC8mpdpKXada5n/80cNatxwNHqZa2lY6mGp jioSrPe/pJ+cwX1OuT286+rPAkGojRxdncnaer6XHfMYgwHOGarYmAj7aDkNzvmNsOn5 d/DhMKaLM8NVI7OmvxoCvB7dv9jWI2fdGC0mp49jX0t1wcTPIpJk2j0ucztcdUf6fvPM AIMw== X-Gm-Message-State: AOPr4FVC8eCM3JmPlBMroMHK9zQkjSAdt3oO3qFs6PBESTmVQ7OKtBEfG4Bxjqyk4VGjZ/HDlU4= X-Received: by 10.202.239.87 with SMTP id n84mr2325147oih.175.1462303693297; Tue, 03 May 2016 12:28:13 -0700 (PDT) Received: from Ubuntu15.localdomain (cpe-66-68-129-43.austin.res.rr.com. [66.68.129.43]) by smtp.gmail.com with ESMTPSA id h7sm280955oej.1.2016.05.03.12.28.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 03 May 2016 12:28:12 -0700 (PDT) From: Bill Fischofer To: lng-odp@lists.linaro.org Date: Tue, 3 May 2016 14:28:07 -0500 Message-Id: <1462303687-20139-1-git-send-email-bill.fischofer@linaro.org> X-Mailer: git-send-email 2.5.0 X-Topics: patch Subject: [lng-odp] [PATCH] doc: userguide: change plus to backtick for asciidoctor X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" In asciidoc monospace characters may be indicated by enclosure in either backticks or plus signs, however asciidoctor requires the use of backticks to indicate monospace. Change all uses of plus signs to backticks so that user guide docs can format properly using either asciidoc or asciidoctor. Going forward only backticks should be used to indicate monospace font. Signed-off-by: Bill Fischofer Reviewed-by: Mike Holmes --- doc/glossary.adoc | 10 +-- doc/users-guide/users-guide-cls.adoc | 4 +- doc/users-guide/users-guide-pktio.adoc | 98 +++++++++++++------------- doc/users-guide/users-guide-tm.adoc | 2 +- doc/users-guide/users-guide.adoc | 124 ++++++++++++++++----------------- 5 files changed, 119 insertions(+), 119 deletions(-) diff --git a/doc/glossary.adoc b/doc/glossary.adoc index 3106e19..2c0de24 100644 --- a/doc/glossary.adoc +++ b/doc/glossary.adoc @@ -10,7 +10,7 @@ control thread:: operating system house keeping tasks but will be scheduled by it and may receive interrupts. ODP instantiation process:: - The process calling +odp_init_global()+, which is probably the + The process calling `odp_init_global()`, which is probably the first process which is started when an ODP application is started. There is one single such process per ODP instantiation. thread:: @@ -19,13 +19,13 @@ thread:: ODP thread:: An ODP thread is a flow of execution that belongs to ODP: Any "flow of execution" (i.e. OS process or OS thread) calling - +odp_init_global()+, or +odp_init_local()+ becomes an ODP thread. + `odp_init_global()`, or `odp_init_local()` becomes an ODP thread. This definition currently limits the number of ODP instances on a given - machine to one. In the future +odp_init_global()+ will return something - like an ODP instance reference and +odp_init_local()+ will take such + machine to one. In the future `odp_init_global()` will return something + like an ODP instance reference and `odp_init_local()` will take such a reference in parameter, allowing threads to join any running ODP instance. Note that, in a Linux environment an ODP thread can be either a Linux - process or a linux thread (i.e. a linux process calling +odp_init_local()+ + process or a linux thread (i.e. a linux process calling `odp_init_local()` will be referred as ODP thread, not ODP process). event:: An event is a notification that can be placed in a queue. diff --git a/doc/users-guide/users-guide-cls.adoc b/doc/users-guide/users-guide-cls.adoc index d306c1c..d2ba743 100644 --- a/doc/users-guide/users-guide-cls.adoc +++ b/doc/users-guide/users-guide-cls.adoc @@ -99,7 +99,7 @@ to be processed. === Default packet handling -There is a +odp_cos_t+ assigned to each port with the +There is a `odp_cos_t` assigned to each port with the odp_pktio_default_cos_set() function, which will function as the default class-of-service for all packets received from an ingress port, that do not match any of the filters defined subsequently. @@ -117,7 +117,7 @@ a packet using one of three methods: 1. The packet may be assigned a specific class-of-service based on its Layer-2 (802.1P/902.1Q VLAN tag) priority field. Since the standard field defines 8 discrete priority levels, the API allows to assign an odp_cos to each of these -priority levels with the +odp_cos_with_l2_priority()+ function. +priority levels with the `odp_cos_with_l2_priority()` function. 2. Similarly, a class-of-service may be assigned using the Layer-3 (IP DiffServ) header field. The application supplies an array of odp_cos values that covers diff --git a/doc/users-guide/users-guide-pktio.adoc b/doc/users-guide/users-guide-pktio.adoc index 2dd0b15..9ca91f7 100644 --- a/doc/users-guide/users-guide-pktio.adoc +++ b/doc/users-guide/users-guide-pktio.adoc @@ -7,23 +7,23 @@ represent a logical I/O interface that is mapped in an implementation-defined manner to an underlying integrated I/O adapter or NIC. PktIO objects are manipulated through various state transitions via -+odp_pktio_xxx()+ API calls as shown below: +`odp_pktio_xxx()` API calls as shown below: .ODP PktIO Finite State Machine image::../images/pktio_fsm.svg[align="center"] -PktIOs begin in the *Unallocated* state. From here a call +odp_pktio_open()+ +PktIOs begin in the *Unallocated* state. From here a call `odp_pktio_open()` is used to create an *odp_pktio_t* handle that is used in all subsequent calls to manipulate the object. This call puts the PktIO into the *Unconfigured* state. To become operational, a PktIO must first be *configured* for Input, Output, or both Input and Output via the -+odp_pktin_queue_config()+ and/or +odp_pktout_queue_config()+ APIs, and then -*started* via the +odp_pktio_start()+ to make it *Ready*. +`odp_pktin_queue_config()` and/or `odp_pktout_queue_config()` APIs, and then +*started* via the `odp_pktio_start()` to make it *Ready*. -Following the completion of I/O processing, the +odp_pktio_stop()+ API returns +Following the completion of I/O processing, the `odp_pktio_stop()` API returns the PktIO to the *Configured* state. From here it may be *Reconfigured* via -additional +odp_pktin_queue_config()+ and/or +odp_pktout_queue_config()+ calls, -or *Closed* via the +odp_pktio_close()+ API to return the PktIO to the +additional `odp_pktin_queue_config()` and/or `odp_pktout_queue_config()` calls, +or *Closed* via the `odp_pktio_close()` API to return the PktIO to the *Unallocated* state. === PktIO Allocation @@ -87,7 +87,7 @@ PktIO objects begin life by being _opened_ via the call: odp_pktio_t odp_pktio_open(const char *name, odp_pool_t pool, const odp_pktio_param_t *param); ----- -+odp_pktio_open()+ takes three arguments: a *name*, which is an +`odp_pktio_open()` takes three arguments: a *name*, which is an implementation-defined string that identifies the logical interface to be opened, a *pool* that identifies the ODP pool that storage for received packets should be allocated from, and a *param* structure that specifies @@ -132,20 +132,20 @@ PktIO objects support four different Input and Output modes, that may be specified independently at *open* time. .PktIO Input Modes -* +ODP_PKTIN_MODE_DIRECT+ -* +ODP_PKTIN_MODE_QUEUE+ -* +ODP_OKTIN_MODE_SCHED+ -* +ODP_PKTIN_MODE_DISABLED+ +* `ODP_PKTIN_MODE_DIRECT` +* `ODP_PKTIN_MODE_QUEUE` +* `ODP_OKTIN_MODE_SCHED` +* `ODP_PKTIN_MODE_DISABLED` .PktIO Output Modes -* +ODP_PKTOUT_MODE_DIRECT+ -* +ODP_PKTOUT_MODE_QUEUE+ -* +ODP_PKTOUT_MODE_TM+ -* +ODP_PKTOUT_MODE_DISABLED+ +* `ODP_PKTOUT_MODE_DIRECT` +* `ODP_PKTOUT_MODE_QUEUE` +* `ODP_PKTOUT_MODE_TM` +* `ODP_PKTOUT_MODE_DISABLED` The DISABLED modes indicate that either input or output is prohibited on this -PktIO. Attempts to receive packets on a PktIO whose +in_mode+ is DISABLED -return no packets while packets sent to a PktIO whose +out_mode+ is DISABLED +PktIO. Attempts to receive packets on a PktIO whose `in_mode` is DISABLED +return no packets while packets sent to a PktIO whose `out_mode` is DISABLED are discarded. ==== Direct I/O Modes @@ -163,10 +163,10 @@ image::../images/pktin_direct_recv.svg[align="center"] In DIRECT mode, received packets are stored in one or more special PktIO queues of type *odp_pktin_queue_t* and are retrieved by threads calling the -+odp_pktin_recv()+ API. +`odp_pktin_recv()` API. Once opened, setting up a DIRECT mode PktIO is performed by the -+odp_pktin_queue_config()+ API. +`odp_pktin_queue_config()` API. [source,c] ----- /** @@ -233,10 +233,10 @@ typedef struct odp_pktin_queue_param_t { } odp_pktin_queue_param_t; ----- Note that the *queue_param* field of this struct is ignored in DIRECT mode. -The purpose of +odp_pktin_queue_config()+ is to specify the number of PktIn +The purpose of `odp_pktin_queue_config()` is to specify the number of PktIn queues to be created and to set their attributes. -It is important to note that while +odp_pktio_queue_config()+ creates a +It is important to note that while `odp_pktio_queue_config()` creates a requested number of RX queues that are associated with the PktIO and accepts optimization advice as to how the application intends to use them, _i.e._, whether the queues need to be safe for concurrent use by multiple threads @@ -250,8 +250,8 @@ how those tools are used. ===== Hash Processing Another feature of DIRECT mode input is the provision of a *hash* function used to distribute incoming packets among the PktIO's PktIn queues. If the -+hash_enable+ field of the *odp_pktin_queue_param_t* is 1, -then the +hash_proto+ field is used to specify which field(s) of incoming +`hash_enable` field of the *odp_pktin_queue_param_t* is 1, +then the `hash_proto` field is used to specify which field(s) of incoming packets should be used as input to an implementation-defined packet distribution hash function. [source,c] @@ -298,7 +298,7 @@ same PktIn queue. ===== PktIn Queues A *PktIn Queue* is a special type of queue that is used internally by PktIOs operating in DIRECT mode. Applications cannot perform enqueues to these queues, -however they may obtain references to them via the +odp_pktin_queue()+ API +however they may obtain references to them via the `odp_pktin_queue()` API [source,c] ----- /** @@ -322,7 +322,7 @@ however they may obtain references to them via the +odp_pktin_queue()+ API int odp_pktin_queue(odp_pktio_t pktio, odp_pktin_queue_t queues[], int num); ----- Once configured, prior to receiving packets the PktIO must be placed into the -*Ready* state via a call to +odp_pktio_start() +*Ready* state via a call to `odp_pktio_start()` [source,c] ----- /** @@ -341,7 +341,7 @@ Once configured, prior to receiving packets the PktIO must be placed into the int odp_pktio_start(odp_pktio_t pktio); ----- Once started, the PktIn queue handles are used as arguments to -+odp_pktin_recv()+ to receive packets from the PktIO. +`odp_pktin_recv()` to receive packets from the PktIO. [source,c] ----- /** @@ -379,7 +379,7 @@ A PktIO operating in DIRECT mode performs TX processing as shown here: image::../images/pktout_direct_send.svg[align="center"] Direct TX processing operates similarly to Direct RX processing. Following -open, the +odp_pktout_queue_config()+ API is used to create and configure +open, the `odp_pktout_queue_config()` API is used to create and configure one or more *PktOut queues* to be used to support packet transmission by this PktIO [source,c] @@ -410,7 +410,7 @@ this PktIO int odp_pktout_queue_config(odp_pktio_t pktio, const odp_pktout_queue_param_t *param); ----- -As with +odp_pktin_queue_config()+, the configuration of PktOut queues +As with `odp_pktin_queue_config()`, the configuration of PktOut queues involves the use of a parameter struct: [source,c] ----- @@ -438,7 +438,7 @@ As with direct input, direct output uses one or more special output queues of type *odp_pktout_queue_t* that are created and configured by this call. As with PktIn queues, the handles for these created PktOut queues may be -retrieved by the +odp_pktout_queue()+ API: +retrieved by the `odp_pktout_queue()` API: [source,c] ----- /** @@ -462,8 +462,8 @@ retrieved by the +odp_pktout_queue()+ API: int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num); ----- Once the PktIO has been configured for output and started via -+odp_pktio_start()+, packets may be transmitted to the PktIO by calling -+odp_pktout_send()+: +`odp_pktio_start()`, packets may be transmitted to the PktIO by calling +`odp_pktout_send()`: [source,c] ----- /** @@ -506,18 +506,18 @@ image::../images/pktin_queue_recv.svg[align="center"] In QUEUE mode, received packets are stored in one or more standard ODP queues. The difference is that these queues are not created directly by the application. Instead, they are created in response to an -+odp_pktin_queue_config()+ call. +`odp_pktin_queue_config()` call. -As with DIRECT mode, the +odp_pktin_queue_param_t+ specified to this call +As with DIRECT mode, the `odp_pktin_queue_param_t` specified to this call indicates whether an input hash should be used and if so which field(s) of the packet should be considered as input to the has function. The main difference between DIRECT and QUEUE RX processing is that because the PktIO uses standard ODP event queues, other parts of the application can -use +odp_queue_enq()+ API calls to enqueue packets to these queues for +use `odp_queue_enq()` API calls to enqueue packets to these queues for "RX" processing in addition to those originating from the PktIO interface itself. To obtain the handles of these input queues, the -+odp_pktin_event_queue()+ API is used: +`odp_pktin_event_queue()` API is used: [source,c] ----- /** @@ -543,7 +543,7 @@ itself. To obtain the handles of these input queues, the int odp_pktin_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num); ----- Similarly, threads receive packets from PktIOs operating in QUEUE mode by -making standard +odp_queue_deq()+ calls to one of the event queues associated +making standard `odp_queue_deq()` calls to one of the event queues associated with the PktIO. ===== Queue TX Processing @@ -554,9 +554,9 @@ image::../images/pktout_queue_send.svg[align="center] For TX processing QUEUE mode behaves similar to DIRECT mode except that output queues are regular ODP event queues that receive packets via -+odp_queue_enq()+ calls rather than special PktOut queues that use -+odp_pktout_send()+. Again, these queues are created via a call to -+odp_pktout_queue_config()+ following +odp_pktio_open()+. +`odp_queue_enq()` calls rather than special PktOut queues that use +`odp_pktout_send()`. Again, these queues are created via a call to +`odp_pktout_queue_config()` following `odp_pktio_open()`. The main reason for selecting QUEUE mode for output is flexibility. If an application is designed to use a _pipeline model_ where packets flow through @@ -573,15 +573,15 @@ Scheduled RX Processing is further divided based on whether or not the Classifier is used. ===== Scheduled RX Processing -When a PktIO is opened with +ODP_PKTIN_MODE_SCHED+, it indicates that the -input queues created by a subsequent +odp_pktin_queue_config()+ call are to +When a PktIO is opened with `ODP_PKTIN_MODE_SCHED`, it indicates that the +input queues created by a subsequent `odp_pktin_queue_config()` call are to be used as input to the *ODP Scheduler*. .PktIO SCHED Mode Receive Processing image::../images/pktin_sched_recv.svg[align="center'] For basic use, SCHED mode simply associates the PktIO input event queues -created by +odp_pktin_queue_config()+ with the scheduler. Hashing may still be +created by `odp_pktin_queue_config()` with the scheduler. Hashing may still be employed to distribute input packets among multiple input queues. However instead of these being plain queues they are scheduled queues and have associated scheduling attributes like priority, scheduler group, and @@ -595,12 +595,12 @@ to permit fine-grained flow separation on *Class of Service (CoS)* boundaries. .PktIO SCHED Mode Receive Processing with Classification image::../images/pktin_sched_cls.svg[align="center"] -In this mode of operation, the hash function of +odp_pktin_queue_config()+ is +In this mode of operation, the hash function of `odp_pktin_queue_config()` is typically not used. Instead, the event queues created by this call, as well as any additional event queues created via separate -+odp_queue_create()+ calls are associated with classes of service via -+odp_cls_cos_create()+ calls. Classification is enabled for the PktIO as a -whole by assigning a _default_ CoS via the +odp_pktio_default_cos_set()+ +`odp_queue_create()` calls are associated with classes of service via +`odp_cls_cos_create()` calls. Classification is enabled for the PktIO as a +whole by assigning a _default_ CoS via the `odp_pktio_default_cos_set()` API. When operating in SCHED mode, applications do not call PktIn receive functions. @@ -615,9 +615,9 @@ process. ===== Scheduled TX Processing Scheduled transmit processing is performed via the *ODP Traffic Manager* and -is requested when a PktIO is opened with an +out_mode+ of +ODP_PKTOUT_MODE_TM+. +is requested when a PktIO is opened with an `out_mode` of `ODP_PKTOUT_MODE_TM`. -For TX processing via the Traffic Manager, applications use the +odp_tm_enq()+ +For TX processing via the Traffic Manager, applications use the `odp_tm_enq()` API: [source,c] ----- diff --git a/doc/users-guide/users-guide-tm.adoc b/doc/users-guide/users-guide-tm.adoc index 132fdc1..b2dbbf1 100644 --- a/doc/users-guide/users-guide-tm.adoc +++ b/doc/users-guide/users-guide-tm.adoc @@ -256,7 +256,7 @@ common to re-use the same set of parameter set over and over again, and also to be able to change the parameter set once and have it affect lots of entities with which it is associated with/applied to. -==== Absolute Limits versus +odp_tm_capability_t+ +==== Absolute Limits versus `odp_tm_capability_t` This header file defines some constants representing the absolute maximum settings for any TM system, though in most cases a TM system can (and should) diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc index a2e5058..bc4b777 100644 --- a/doc/users-guide/users-guide.adoc +++ b/doc/users-guide/users-guide.adoc @@ -36,8 +36,8 @@ embodiment that they permit innovation in how these functions can be realized on various platforms that offer implementations of ODP. To achieve this goal, ODP APIs are described using abstract data types whose definition is left up to the ODP implementer. For example, in ODP packets are referenced -by abstract handles of type +odp_packet_t+, and packet-related APIs take -arguments of this type. What an +odp_packet_t+ actually is is not part of the +by abstract handles of type `odp_packet_t`, and packet-related APIs take +arguments of this type. What an `odp_packet_t` actually is is not part of the ODP API specification--that is the responsibility of each ODP implementation. .Summary: ODP API attributes: @@ -207,7 +207,7 @@ 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 other threads--that is up to the implementation. Threads come in two "flavors": control and worker, that are represented by the abstract type -+odp_thread_type_t+. +`odp_thread_type_t`. A control thread is a supervisory thread that organizes the operation of worker threads. Worker threads, by contrast, exist to @@ -232,7 +232,7 @@ changes in various components of interest to the application. Events have an event type that describes what it represents. Threads can create new events or consume events processed by them, or they can perform some processing on an event and then pass it along to another component for further processing. -References to events are via handles of abstract type +odp_event_t+. Cast +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. @@ -246,7 +246,7 @@ have an associated context, which represents a persistent state for all events that make use of it. These states are what permit threads to perform stateful processing on events as well as stateless processing. -Queues are represented by handles of abstract type +odp_queue_t+. +Queues are represented by handles of abstract type `odp_queue_t`. === Pool A pool is a shared memory area from which elements may be drawn. Pools @@ -258,14 +258,14 @@ use may be shared between the two. Pools have an associated type that characterizes the elements that they contain. The two most important pool types are Buffer and Packet. -Pools are represented by handles of abstract type +odp_pool_t+. +Pools are represented by handles of abstract type `odp_pool_t`. === 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+. +Shared memory is represented by handles of abstract type `odp_shm_t`. === Buffer A buffer is a fixed sized block of shared storage that is used by ODP @@ -283,12 +283,12 @@ 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 represented by handles of abstract type +odp_buffer_t+. +Buffers are represented by handles of abstract type `odp_buffer_t`. === 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+. +Packets are drawn from pools of type `ODP_POOL_PACKET`. Unlike buffers, which are simple objects, ODP packets have a rich set of semantics that permit their inspection and manipulation in complex ways to be described later. Packets also support @@ -296,7 +296,7 @@ a rich set of metadata as well as user metadata. User metadata permits applications to associate an application-determined amount of side information with each packet for its own use. -Packets are represented by handles of abstract type +odp_packet_t+. +Packets are represented by handles of abstract type `odp_packet_t`. === PktIO PktIO is how ODP represents I/O interfaces. A pktio object is a logical @@ -304,7 +304,7 @@ port capable of receiving and/or transmitting packets. This may be directly supported by the underlying platform as an integrated feature, or may represent a device attached via a PCIE or other bus. -PktIOs are represented by handles of abstract type +odp_pktio_t+. +PktIOs are represented by handles of abstract type `odp_pktio_t`. === Time The time API is used to measure time intervals and track time flow of an @@ -316,29 +316,29 @@ The local time API is designed to be used within one thread and can be faster than the global time API. The local time API cannot be used between threads as time consistency is not guaranteed, and in some cases that's enough. So, local time stamps are local to the calling thread and must not be shared -with other threads. Current local time can be read with +odp_time_local()+. +with other threads. Current local time can be read with `odp_time_local()`. ==== Global time The global time API is designed to be used for tracking time between threads. So, global time stamps can be shared between threads. Current global time can -be read with +odp_time_global()+. +be read with `odp_time_global()`. Both, local and global time is not wrapped during the application life cycle. -The time API includes functions to operate with time, such as +odp_time_diff()+, -+odp_time_sum()+, +odp_time_cmp()+, conversion functions like -+odp_time_to_ns()+, +odp_time_local_from_ns()+, +odp_time_global_from_ns()+. -To get rate of time source +odp_time_local_res()+, +odp_time_global_res()+ -are used. To wait, +odp_time_wait_ns()+ and +odp_time_wait_until()+ are used, +The time API includes functions to operate with time, such as `odp_time_diff()`, +`odp_time_sum()`, `odp_time_cmp()`, conversion functions like +`odp_time_to_ns()`, `odp_time_local_from_ns()`, `odp_time_global_from_ns()`. +To get rate of time source `odp_time_local_res()`, `odp_time_global_res()` +are used. To wait, `odp_time_wait_ns()` and `odp_time_wait_until()` are used, during witch a thread potentially busy loop the entire wait time. -The +odp_time_t+ opaque type represents local or global timestamps. +The `odp_time_t` opaque type represents local or global timestamps. === 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 +own abstract type (`odp_timer_pool_t`). Applications may have many timers 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 +time. When timers expire they create events of type `odp_timeout_t`, which serve as notifications of timer expiration. === Synchronizer @@ -403,7 +403,7 @@ image::odp_scheduling.svg[align="center"] The Scheduler is responsible for selecting and dispatching one or more events to a requesting thread. Event selection is based on several factors involving both the queues containing schedulable events and the thread making an -+odp_schedule()+ or +odp_schedule_multi()+ call. +`odp_schedule()` or `odp_schedule_multi()` call. ODP queues have a _scheduling priority_ that determines how urgently events on them should be processed relative to events contained in other queues. @@ -468,7 +468,7 @@ Applications only include the 'include/odp_api.h' file, which includes the 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 +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. @@ -493,9 +493,9 @@ 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 +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 +`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. @@ -505,7 +505,7 @@ once per application. Following global initialization, each thread in turn calls 'odp_init_local()'. This establishes the local ODP thread context for that thread and MUST be called before other ODP APIs may be called by that thread. The sole argument to this call is the _thread type_, -which is either +ODP_THREAD_WORKER+ or +ODP_THREAD_CONTROL+. +which is either `ODP_THREAD_WORKER` or `ODP_THREAD_CONTROL`. === Shutdown Shutdown is the logical reverse of the initialization procedure, with @@ -522,16 +522,16 @@ 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 +_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 +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 @@ -550,9 +550,9 @@ resource. == Shared memory === Allocating shared memory -Blocks of shared memory can be created using the +odp_shm_reserve()+ API +Blocks of shared memory can be created using the `odp_shm_reserve()` API call. The call expects a shared memory block name, a block size, an alignment -requirement, and optional flags as parameters. It returns a +odp_shm_t+ +requirement, and optional flags as parameters. It returns a `odp_shm_t` handle. The size and alignment requirement are given in bytes. .creating a block of shared memory @@ -583,32 +583,32 @@ shared_data_t *shared_data; shared_data = odp_shm_addr(shm); ---- -The address returned by +odp_shm_addr()+ is valid only in the calling ODP +The address returned by `odp_shm_addr()` is valid only in the calling ODP thread space: odp_shm_t handles can be shared between ODP threads and remain -valid within any threads, whereas the address returned by +odp_shm_addr(shm)+ +valid within any threads, whereas the address returned by `odp_shm_addr(shm)` may differ from ODP threads to ODP threads (for the same 'shm' block), and should therefore not be shared between ODP threads. For instance, it would be correct to send a shm handle using IPC between two -ODP threads and let each of these thread do their own +odp_shm_addr()+ to +ODP threads and let each of these thread do their own `odp_shm_addr()` to get the block address. Directly sending the address returned by -+odp_shm_addr()+ from one ODP thread to another would however possibly fail +`odp_shm_addr()` from one ODP thread to another would however possibly fail (the address may have no sense in the receiver address space). -The address returned by +odp_shm_addr()+ is nevertheless guaranteed to be +The address returned by `odp_shm_addr()` is nevertheless guaranteed to be aligned according to the alignment requirements provided at block creation -time, even if the call to +odp_shm_addr()+ is performed by a different ODP -thread than the one which originally called +odp_shm_reserve()+. +time, even if the call to `odp_shm_addr()` is performed by a different ODP +thread than the one which originally called `odp_shm_reserve()`. All shared memory blocks are contiguous in any ODP thread addressing space: 'address' to 'address'\+'size' (where 'size' is the shared memory block size, -as provided in the +odp_shm_reserve()+ call) is read and writeable and +as provided in the `odp_shm_reserve()` call) is read and writeable and mapping the shared memory block. There is no fragmentation. === Memory behaviour By default ODP threads are assumed to behave as cache coherent systems: Any change performed on a shared memory block is guaranteed to eventually become visible to other ODP threads sharing this memory block. -(this behaviour may be altered by flags to +odp_shm_reserve()+ in the future). +(this behaviour may be altered by flags to `odp_shm_reserve()` in the future). Nevertheless, there is no implicit memory barrier associated with any action on shared memories: *When* a change performed by an ODP thread becomes visible to another ODP thread is not known: An application using shared memory @@ -619,10 +619,10 @@ validity between ODP threads. As mentioned, shared memory handles can be sent from ODP threads to ODP threads using any IPC mechanism, and then the block address retrieved. A simpler approach to get the shared memory block handle of an already created -block is to use the +odp_shm_lookup()+ API function call. +block is to use the `odp_shm_lookup()` API function call. This nevertheless requires the calling ODP thread to provide the name of the shared memory block: -+odp_shm_lookup()+ will return +ODP_SHM_INVALID+ if no shared memory block +`odp_shm_lookup()` will return `ODP_SHM_INVALID` if no shared memory block with the provided name is known by ODP. .retrieving a block handle and address from another ODP task @@ -641,11 +641,11 @@ if (shm != ODP_SHM_INVALID) { ---- === Freeing memory -Freeing shared memory is performed using the +odp_shm_free()+ API call. -+odp_shm_free()+ takes one single argument, the shared memory block handle. -Any ODP thread is allowed to perform a +odp_shm_free()+ on a shared memory -block (i.e. the thread performing the +odp_shm_free()+ may be different -from the thread which did the +odp_shm_reserve()+). Shared memory blocks should +Freeing shared memory is performed using the `odp_shm_free()` API call. +`odp_shm_free()` takes one single argument, the shared memory block handle. +Any ODP thread is allowed to perform a `odp_shm_free()` on a shared memory +block (i.e. the thread performing the `odp_shm_free()` may be different +from the thread which did the `odp_shm_reserve()`). Shared memory blocks should be freed only once, and once freed, a shared memory block should no longer be referenced by any ODP threads. @@ -674,7 +674,7 @@ This flag tells ODP that the shared memory will be used by the ODP application software only: no HW (such as DMA, or other accelerator) will ever try to access the memory. No other ODP call will be involved on this memory (as ODP calls could implicitly involve HW, depending on the ODP -implementation), except for +odp_shm_lookup()+ and +odp_shm_free()+. +implementation), except for `odp_shm_lookup()` and `odp_shm_free()`. ODP implementations may use this flag as a hint for performance optimization, or may as well ignore this flag. @@ -682,7 +682,7 @@ or may as well ignore this flag. 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 +`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 @@ -741,16 +741,16 @@ 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 +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+ +_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 +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. @@ -889,7 +889,7 @@ void worker_thread() 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 +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 @@ -914,7 +914,7 @@ Packet objects are normally created at ingress when they arrive at a source *odp_pktio_t* and are received by an application either directly or (more typically) for a scheduled receive queue. They MAY be implicitly freed when they are transmitted to an output *odp_pktio_t* via an associated transmit -queue, or freed directly via the +odp_packet_free()+ API. +queue, or freed directly via the `odp_packet_free()` API. Occasionally an application may originate a packet itself, either _de novo_ or by deriving it from an existing packet, and APIs are provided to assist in @@ -947,9 +947,9 @@ to manipulate its structure. To support packet manipulation, predefined _headroom_ and _tailroom_ areas are logically associated with a packet. Packets can be adjusted by _pulling_ and _pushing_ these areas. Typical packet processing might consist -of stripping headers from a packet via +odp_pull_head()+ calls as part of +of stripping headers from a packet via `odp_pull_head()` calls as part of receive processing and then replacing them with new headers via -+odp_push_head()+ calls as the packet is being prepared for transmit. +`odp_push_head()` calls as the packet is being prepared for transmit. === Packet Segments and Addressing ODP platforms use various methods and techniques to store and process packets @@ -993,7 +993,7 @@ additional segments may be part of the packet and contain the remaining packet payload and tailroom. The application need not concern itself with segments except that when the application requires addressability to a packet it understands that addressability is provided on a per-segment basis. So, for -example, if the application makes a call like +odp_packet_l4_ptr()+ to obtain +example, if the application makes a call like `odp_packet_l4_ptr()` to obtain addressability to the packet's Layer 4 header, the returned length from that call is the number of bytes from the start of the Layer 4 header that are contiguously addressable to the application from the returned pointer address. @@ -1016,10 +1016,10 @@ changes in the packet contents and/or structure as part of its processing of the packet. While changing this metadata may effect some ODP APIs, changing metadata is designed to _document_ application changes to the packet but does not in itself _cause_ those changes to be made. For example, if an -application changes the Layer 3 offset by using the +odp_packet_l3_offset_set()+ -API, the subsequent calls to +odp_packet_l3_ptr()+ will return an address +application changes the Layer 3 offset by using the `odp_packet_l3_offset_set()` +API, the subsequent calls to `odp_packet_l3_ptr()` will return an address starting from that changed offset, changing an attribute like -+odp_packet_has_udp_set()+ will not, by itself, turn a non-UDP packet into +`odp_packet_has_udp_set()` will not, by itself, turn a non-UDP packet into a valid UDP packet. Applications are expected to exercise appropriate care when changing packet metadata to ensure that the resulting metadata changes reflect the actual changed packet structure that the application has made.