177c79de0SHemant Agrawal.. SPDX-License-Identifier: BSD-3-Clause 277c79de0SHemant Agrawal Copyright 2018 The DPDK contributors 377c79de0SHemant Agrawal 46bdae907SThomas Monjalon.. _coding_style: 56bdae907SThomas Monjalon 66bdae907SThomas MonjalonDPDK Coding Style 76bdae907SThomas Monjalon================= 86bdae907SThomas Monjalon 96bdae907SThomas MonjalonDescription 106bdae907SThomas Monjalon----------- 116bdae907SThomas Monjalon 126bdae907SThomas MonjalonThis document specifies the preferred style for source files in the DPDK source tree. 136bdae907SThomas MonjalonIt is based on the Linux Kernel coding guidelines and the FreeBSD 7.2 Kernel Developer's Manual (see man style(9)), but was heavily modified for the needs of the DPDK. 146bdae907SThomas Monjalon 156bdae907SThomas MonjalonGeneral Guidelines 166bdae907SThomas Monjalon------------------ 176bdae907SThomas Monjalon 186bdae907SThomas MonjalonThe rules and guidelines given in this document cannot cover every situation, so the following general guidelines should be used as a fallback: 196bdae907SThomas Monjalon 206bdae907SThomas Monjalon* The code style should be consistent within each individual file. 216bdae907SThomas Monjalon* In the case of creating new files, the style should be consistent within each file in a given directory or module. 226bdae907SThomas Monjalon* The primary reason for coding standards is to increase code readability and comprehensibility, therefore always use whatever option will make the code easiest to read. 236bdae907SThomas Monjalon 246bdae907SThomas MonjalonLine length is recommended to be not more than 80 characters, including comments. 256bdae907SThomas Monjalon[Tab stop size should be assumed to be 8-characters wide]. 266bdae907SThomas Monjalon 276bdae907SThomas Monjalon.. note:: 286bdae907SThomas Monjalon 296bdae907SThomas Monjalon The above is recommendation, and not a hard limit. 306bdae907SThomas Monjalon However, it is expected that the recommendations should be followed in all but the rarest situations. 316bdae907SThomas Monjalon 326bdae907SThomas MonjalonC Comment Style 336bdae907SThomas Monjalon--------------- 346bdae907SThomas Monjalon 356bdae907SThomas MonjalonUsual Comments 366bdae907SThomas Monjalon~~~~~~~~~~~~~~ 376bdae907SThomas Monjalon 386bdae907SThomas MonjalonThese comments should be used in normal cases. 396bdae907SThomas MonjalonTo document a public API, a doxygen-like format must be used: refer to :ref:`doxygen_guidelines`. 406bdae907SThomas Monjalon 416bdae907SThomas Monjalon.. code-block:: c 426bdae907SThomas Monjalon 436bdae907SThomas Monjalon /* 446bdae907SThomas Monjalon * VERY important single-line comments look like this. 456bdae907SThomas Monjalon */ 466bdae907SThomas Monjalon 476bdae907SThomas Monjalon /* Most single-line comments look like this. */ 486bdae907SThomas Monjalon 496bdae907SThomas Monjalon /* 506bdae907SThomas Monjalon * Multi-line comments look like this. Make them real sentences. Fill 516bdae907SThomas Monjalon * them so they look like real paragraphs. 526bdae907SThomas Monjalon */ 536bdae907SThomas Monjalon 546bdae907SThomas MonjalonLicense Header 556bdae907SThomas Monjalon~~~~~~~~~~~~~~ 566bdae907SThomas Monjalon 57525d8031SStephen HemmingerEach file must begin with a special comment containing the 58525d8031SStephen Hemminger`Software Package Data Exchange (SPDX) License Identfier <https://spdx.org/using-spdx-license-identifier>`_. 59525d8031SStephen Hemminger 60525d8031SStephen HemmingerGenerally this is the BSD License, except for code granted special exceptions. 61525d8031SStephen HemmingerThe SPDX licences identifier is sufficient, a file should not contain 62525d8031SStephen Hemmingeran additional text version of the license (boilerplate). 63525d8031SStephen Hemminger 646bdae907SThomas MonjalonAfter any copyright header, a blank line should be left before any other contents, e.g. include statements in a C file. 656bdae907SThomas Monjalon 666bdae907SThomas MonjalonC Preprocessor Directives 676bdae907SThomas Monjalon------------------------- 686bdae907SThomas Monjalon 696bdae907SThomas MonjalonHeader Includes 706bdae907SThomas Monjalon~~~~~~~~~~~~~~~ 716bdae907SThomas Monjalon 726bdae907SThomas MonjalonIn DPDK sources, the include files should be ordered as following: 736bdae907SThomas Monjalon 746bdae907SThomas Monjalon#. libc includes (system includes first) 756bdae907SThomas Monjalon#. DPDK EAL includes 766bdae907SThomas Monjalon#. DPDK misc libraries includes 776bdae907SThomas Monjalon#. application-specific includes 786bdae907SThomas Monjalon 796bdae907SThomas MonjalonInclude files from the local application directory are included using quotes, while includes from other paths are included using angle brackets: "<>". 806bdae907SThomas Monjalon 816bdae907SThomas MonjalonExample: 826bdae907SThomas Monjalon 836bdae907SThomas Monjalon.. code-block:: c 846bdae907SThomas Monjalon 856bdae907SThomas Monjalon #include <stdio.h> 866bdae907SThomas Monjalon #include <stdlib.h> 876bdae907SThomas Monjalon 886bdae907SThomas Monjalon #include <rte_eal.h> 896bdae907SThomas Monjalon 906bdae907SThomas Monjalon #include <rte_ring.h> 916bdae907SThomas Monjalon #include <rte_mempool.h> 926bdae907SThomas Monjalon 936bdae907SThomas Monjalon #include "application.h" 946bdae907SThomas Monjalon 956bdae907SThomas MonjalonHeader File Guards 966bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~ 976bdae907SThomas Monjalon 986bdae907SThomas MonjalonHeaders should be protected against multiple inclusion with the usual: 996bdae907SThomas Monjalon 1006bdae907SThomas Monjalon.. code-block:: c 1016bdae907SThomas Monjalon 1026bdae907SThomas Monjalon #ifndef _FILE_H_ 1036bdae907SThomas Monjalon #define _FILE_H_ 1046bdae907SThomas Monjalon 1056bdae907SThomas Monjalon /* Code */ 1066bdae907SThomas Monjalon 1076bdae907SThomas Monjalon #endif /* _FILE_H_ */ 1086bdae907SThomas Monjalon 1096bdae907SThomas Monjalon 1106bdae907SThomas MonjalonMacros 1116bdae907SThomas Monjalon~~~~~~ 1126bdae907SThomas Monjalon 1136bdae907SThomas MonjalonDo not ``#define`` or declare names except with the standard DPDK prefix: ``RTE_``. 1146bdae907SThomas MonjalonThis is to ensure there are no collisions with definitions in the application itself. 1156bdae907SThomas Monjalon 1166bdae907SThomas MonjalonThe names of "unsafe" macros (ones that have side effects), and the names of macros for manifest constants, are all in uppercase. 1176bdae907SThomas Monjalon 1186bdae907SThomas MonjalonThe expansions of expression-like macros are either a single token or have outer parentheses. 1196bdae907SThomas MonjalonIf a macro is an inline expansion of a function, the function name is all in lowercase and the macro has the same name all in uppercase. 1206bdae907SThomas MonjalonIf the macro encapsulates a compound statement, enclose it in a do-while loop, so that it can be used safely in if statements. 1216bdae907SThomas MonjalonAny final statement-terminating semicolon should be supplied by the macro invocation rather than the macro, to make parsing easier for pretty-printers and editors. 1226bdae907SThomas Monjalon 1236bdae907SThomas MonjalonFor example: 1246bdae907SThomas Monjalon 1256bdae907SThomas Monjalon.. code-block:: c 1266bdae907SThomas Monjalon 1276bdae907SThomas Monjalon #define MACRO(x, y) do { \ 1286bdae907SThomas Monjalon variable = (x) + (y); \ 1296bdae907SThomas Monjalon (y) += 2; \ 1306bdae907SThomas Monjalon } while(0) 1316bdae907SThomas Monjalon 1326bdae907SThomas Monjalon.. note:: 1336bdae907SThomas Monjalon 1346bdae907SThomas Monjalon Wherever possible, enums and inline functions should be preferred to macros, since they provide additional degrees of type-safety and can allow compilers to emit extra warnings about unsafe code. 1356bdae907SThomas Monjalon 1366bdae907SThomas MonjalonConditional Compilation 1376bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~~~ 1386bdae907SThomas Monjalon 1396bdae907SThomas Monjalon* When code is conditionally compiled using ``#ifdef`` or ``#if``, a comment may be added following the matching 1406bdae907SThomas Monjalon ``#endif`` or ``#else`` to permit the reader to easily discern where conditionally compiled code regions end. 1416bdae907SThomas Monjalon* This comment should be used only for (subjectively) long regions, regions greater than 20 lines, or where a series of nested ``#ifdef``'s may be confusing to the reader. 1426bdae907SThomas Monjalon Exceptions may be made for cases where code is conditionally not compiled for the purposes of lint(1), or other tools, even though the uncompiled region may be small. 1436bdae907SThomas Monjalon* The comment should be separated from the ``#endif`` or ``#else`` by a single space. 1446bdae907SThomas Monjalon* For short conditionally compiled regions, a closing comment should not be used. 1456bdae907SThomas Monjalon* The comment for ``#endif`` should match the expression used in the corresponding ``#if`` or ``#ifdef``. 1466bdae907SThomas Monjalon* The comment for ``#else`` and ``#elif`` should match the inverse of the expression(s) used in the preceding ``#if`` and/or ``#elif`` statements. 1476bdae907SThomas Monjalon* In the comments, the subexpression ``defined(FOO)`` is abbreviated as "FOO". 1486bdae907SThomas Monjalon For the purposes of comments, ``#ifndef FOO`` is treated as ``#if !defined(FOO)``. 1496bdae907SThomas Monjalon 1506bdae907SThomas Monjalon.. code-block:: c 1516bdae907SThomas Monjalon 1526bdae907SThomas Monjalon #ifdef KTRACE 1536bdae907SThomas Monjalon #include <sys/ktrace.h> 1546bdae907SThomas Monjalon #endif 1556bdae907SThomas Monjalon 1566bdae907SThomas Monjalon #ifdef COMPAT_43 1576bdae907SThomas Monjalon /* A large region here, or other conditional code. */ 1586bdae907SThomas Monjalon #else /* !COMPAT_43 */ 1596bdae907SThomas Monjalon /* Or here. */ 1606bdae907SThomas Monjalon #endif /* COMPAT_43 */ 1616bdae907SThomas Monjalon 1626bdae907SThomas Monjalon #ifndef COMPAT_43 1636bdae907SThomas Monjalon /* Yet another large region here, or other conditional code. */ 1646bdae907SThomas Monjalon #else /* COMPAT_43 */ 1656bdae907SThomas Monjalon /* Or here. */ 1666bdae907SThomas Monjalon #endif /* !COMPAT_43 */ 1676bdae907SThomas Monjalon 1686bdae907SThomas Monjalon.. note:: 1696bdae907SThomas Monjalon 1706bdae907SThomas Monjalon Conditional compilation should be used only when absolutely necessary, as it increases the number of target binaries that need to be built and tested. 1716bdae907SThomas Monjalon 1726bdae907SThomas MonjalonC Types 1736bdae907SThomas Monjalon------- 1746bdae907SThomas Monjalon 1756bdae907SThomas MonjalonIntegers 1766bdae907SThomas Monjalon~~~~~~~~ 1776bdae907SThomas Monjalon 1786bdae907SThomas MonjalonFor fixed/minimum-size integer values, the project uses the form uintXX_t (from stdint.h) instead of older BSD-style integer identifiers of the form u_intXX_t. 1796bdae907SThomas Monjalon 1806bdae907SThomas MonjalonEnumerations 1816bdae907SThomas Monjalon~~~~~~~~~~~~ 1826bdae907SThomas Monjalon 1836bdae907SThomas Monjalon* Enumeration values are all uppercase. 1846bdae907SThomas Monjalon 1856bdae907SThomas Monjalon.. code-block:: c 1866bdae907SThomas Monjalon 1876bdae907SThomas Monjalon enum enumtype { ONE, TWO } et; 1886bdae907SThomas Monjalon 1896bdae907SThomas Monjalon* Enum types should be used in preference to macros #defining a set of (sequential) values. 1906bdae907SThomas Monjalon* Enum types should be prefixed with ``rte_`` and the elements by a suitable prefix [generally starting ``RTE_<enum>_`` - where <enum> is a shortname for the enum type] to avoid namespace collisions. 1916bdae907SThomas Monjalon 1926bdae907SThomas MonjalonBitfields 1936bdae907SThomas Monjalon~~~~~~~~~ 1946bdae907SThomas Monjalon 1956bdae907SThomas MonjalonThe developer should group bitfields that are included in the same integer, as follows: 1966bdae907SThomas Monjalon 1976bdae907SThomas Monjalon.. code-block:: c 1986bdae907SThomas Monjalon 1996bdae907SThomas Monjalon struct grehdr { 2006bdae907SThomas Monjalon uint16_t rec:3, 2016bdae907SThomas Monjalon srr:1, 2026bdae907SThomas Monjalon seq:1, 2036bdae907SThomas Monjalon key:1, 2046bdae907SThomas Monjalon routing:1, 2056bdae907SThomas Monjalon csum:1, 2066bdae907SThomas Monjalon version:3, 2076bdae907SThomas Monjalon reserved:4, 2086bdae907SThomas Monjalon ack:1; 2096bdae907SThomas Monjalon /* ... */ 2106bdae907SThomas Monjalon } 2116bdae907SThomas Monjalon 2126bdae907SThomas MonjalonVariable Declarations 2136bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~ 2146bdae907SThomas Monjalon 2156bdae907SThomas MonjalonIn declarations, do not put any whitespace between asterisks and adjacent tokens, except for tokens that are identifiers related to types. 2166bdae907SThomas Monjalon(These identifiers are the names of basic types, type qualifiers, and typedef-names other than the one being declared.) 2176bdae907SThomas MonjalonSeparate these identifiers from asterisks using a single space. 2186bdae907SThomas Monjalon 2196bdae907SThomas MonjalonFor example: 2206bdae907SThomas Monjalon 2216bdae907SThomas Monjalon.. code-block:: c 2226bdae907SThomas Monjalon 2236bdae907SThomas Monjalon int *x; /* no space after asterisk */ 2246bdae907SThomas Monjalon int * const x; /* space after asterisk when using a type qualifier */ 2256bdae907SThomas Monjalon 2266bdae907SThomas Monjalon* All externally-visible variables should have an ``rte_`` prefix in the name to avoid namespace collisions. 2276bdae907SThomas Monjalon* Do not use uppercase letters - either in the form of ALL_UPPERCASE, or CamelCase - in variable names. 2286bdae907SThomas Monjalon Lower-case letters and underscores only. 2296bdae907SThomas Monjalon 2306bdae907SThomas MonjalonStructure Declarations 2316bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~~ 2326bdae907SThomas Monjalon 2336bdae907SThomas Monjalon* In general, when declaring variables in new structures, declare them sorted by use, then by size (largest to smallest), and then in alphabetical order. 2346bdae907SThomas Monjalon Sorting by use means that commonly used variables are used together and that the structure layout makes logical sense. 2356bdae907SThomas Monjalon Ordering by size then ensures that as little padding is added to the structure as possible. 2366bdae907SThomas Monjalon* For existing structures, additions to structures should be added to the end so for backward compatibility reasons. 2376bdae907SThomas Monjalon* Each structure element gets its own line. 2386bdae907SThomas Monjalon* Try to make the structure readable by aligning the member names using spaces as shown below. 2396bdae907SThomas Monjalon* Names following extremely long types, which therefore cannot be easily aligned with the rest, should be separated by a single space. 2406bdae907SThomas Monjalon 2416bdae907SThomas Monjalon.. code-block:: c 2426bdae907SThomas Monjalon 2436bdae907SThomas Monjalon struct foo { 2446bdae907SThomas Monjalon struct foo *next; /* List of active foo. */ 2456bdae907SThomas Monjalon struct mumble amumble; /* Comment for mumble. */ 2466bdae907SThomas Monjalon int bar; /* Try to align the comments. */ 2476bdae907SThomas Monjalon struct verylongtypename *baz; /* Won't fit with other members */ 2486bdae907SThomas Monjalon }; 2496bdae907SThomas Monjalon 2506bdae907SThomas Monjalon 2516bdae907SThomas Monjalon* Major structures should be declared at the top of the file in which they are used, or in separate header files if they are used in multiple source files. 2526bdae907SThomas Monjalon* Use of the structures should be by separate variable declarations and those declarations must be extern if they are declared in a header file. 2536bdae907SThomas Monjalon* Externally visible structure definitions should have the structure name prefixed by ``rte_`` to avoid namespace collisions. 2546bdae907SThomas Monjalon 255904ffb2eSMarko Kovacevic.. note:: 256904ffb2eSMarko Kovacevic 257904ffb2eSMarko Kovacevic Uses of ``bool`` in structures are not preferred as is wastes space and 258904ffb2eSMarko Kovacevic it's also not clear as to what type size the bool is. A preferred use of 259904ffb2eSMarko Kovacevic ``bool`` is mainly as a return type from functions that return true/false, 260904ffb2eSMarko Kovacevic and maybe local variable functions. 261904ffb2eSMarko Kovacevic 262904ffb2eSMarko Kovacevic Ref: `LKML <https://lkml.org/lkml/2017/11/21/384>`_ 263904ffb2eSMarko Kovacevic 2646bdae907SThomas MonjalonQueues 2656bdae907SThomas Monjalon~~~~~~ 2666bdae907SThomas Monjalon 2676bdae907SThomas MonjalonUse queue(3) macros rather than rolling your own lists, whenever possible. 2686bdae907SThomas MonjalonThus, the previous example would be better written: 2696bdae907SThomas Monjalon 2706bdae907SThomas Monjalon.. code-block:: c 2716bdae907SThomas Monjalon 2726bdae907SThomas Monjalon #include <sys/queue.h> 2736bdae907SThomas Monjalon 2746bdae907SThomas Monjalon struct foo { 2756bdae907SThomas Monjalon LIST_ENTRY(foo) link; /* Use queue macros for foo lists. */ 2766bdae907SThomas Monjalon struct mumble amumble; /* Comment for mumble. */ 2776bdae907SThomas Monjalon int bar; /* Try to align the comments. */ 2786bdae907SThomas Monjalon struct verylongtypename *baz; /* Won't fit with other members */ 2796bdae907SThomas Monjalon }; 2806bdae907SThomas Monjalon LIST_HEAD(, foo) foohead; /* Head of global foo list. */ 2816bdae907SThomas Monjalon 2826bdae907SThomas Monjalon 2836bdae907SThomas MonjalonDPDK also provides an optimized way to store elements in lockless rings. 2846bdae907SThomas MonjalonThis should be used in all data-path code, when there are several consumer and/or producers to avoid locking for concurrent access. 2856bdae907SThomas Monjalon 28657c789fdSStephen HemmingerNaming 28757c789fdSStephen Hemminger------ 28857c789fdSStephen Hemminger 28957c789fdSStephen HemmingerFor symbol names and documentation, new usage of 29057c789fdSStephen Hemminger'master / slave' (or 'slave' independent of 'master') and 'blacklist / 29157c789fdSStephen Hemmingerwhitelist' is not allowed. 29257c789fdSStephen Hemminger 29357c789fdSStephen HemmingerRecommended replacements for 'master / slave' are: 29457c789fdSStephen Hemminger '{primary,main} / {secondary,replica,subordinate}' 29557c789fdSStephen Hemminger '{initiator,requester} / {target,responder}' 29657c789fdSStephen Hemminger '{controller,host} / {device,worker,proxy}' 29757c789fdSStephen Hemminger 'leader / follower' 29857c789fdSStephen Hemminger 'director / performer' 29957c789fdSStephen Hemminger 30057c789fdSStephen HemmingerRecommended replacements for 'blacklist/whitelist' are: 30157c789fdSStephen Hemminger 'denylist / allowlist' 30257c789fdSStephen Hemminger 'blocklist / passlist' 30357c789fdSStephen Hemminger 30457c789fdSStephen HemmingerExceptions for introducing new usage is to maintain compatibility 30557c789fdSStephen Hemmingerwith an existing (as of 2020) hardware or protocol 30657c789fdSStephen Hemmingerspecification that mandates those terms. 30757c789fdSStephen Hemminger 30857c789fdSStephen Hemminger 3096bdae907SThomas MonjalonTypedefs 3106bdae907SThomas Monjalon~~~~~~~~ 3116bdae907SThomas Monjalon 3126bdae907SThomas MonjalonAvoid using typedefs for structure types. 3136bdae907SThomas Monjalon 3146bdae907SThomas MonjalonFor example, use: 3156bdae907SThomas Monjalon 3166bdae907SThomas Monjalon.. code-block:: c 3176bdae907SThomas Monjalon 3186bdae907SThomas Monjalon struct my_struct_type { 3196bdae907SThomas Monjalon /* ... */ 3206bdae907SThomas Monjalon }; 3216bdae907SThomas Monjalon 3226bdae907SThomas Monjalon struct my_struct_type my_var; 3236bdae907SThomas Monjalon 3246bdae907SThomas Monjalon 3256bdae907SThomas Monjalonrather than: 3266bdae907SThomas Monjalon 3276bdae907SThomas Monjalon.. code-block:: c 3286bdae907SThomas Monjalon 3296bdae907SThomas Monjalon typedef struct my_struct_type { 3306bdae907SThomas Monjalon /* ... */ 3316bdae907SThomas Monjalon } my_struct_type; 3326bdae907SThomas Monjalon 3336bdae907SThomas Monjalon my_struct_type my_var 3346bdae907SThomas Monjalon 3356bdae907SThomas Monjalon 3366bdae907SThomas MonjalonTypedefs are problematic because they do not properly hide their underlying type; 3376bdae907SThomas Monjalonfor example, you need to know if the typedef is the structure itself, as shown above, or a pointer to the structure. 3386bdae907SThomas MonjalonIn addition, they must be declared exactly once, whereas an incomplete structure type can be mentioned as many times as necessary. 3396bdae907SThomas MonjalonTypedefs are difficult to use in stand-alone header files. 3406bdae907SThomas MonjalonThe header that defines the typedef must be included before the header that uses it, or by the header that uses it (which causes namespace pollution), 3416bdae907SThomas Monjalonor there must be a back-door mechanism for obtaining the typedef. 3426bdae907SThomas Monjalon 3436bdae907SThomas MonjalonNote that #defines used instead of typedefs also are problematic (since they do not propagate the pointer type correctly due to direct text replacement). 3446bdae907SThomas MonjalonFor example, ``#define pint int *`` does not work as expected, while ``typedef int *pint`` does work. 3456bdae907SThomas MonjalonAs stated when discussing macros, typedefs should be preferred to macros in cases like this. 3466bdae907SThomas Monjalon 3476bdae907SThomas MonjalonWhen convention requires a typedef; make its name match the struct tag. 3486bdae907SThomas MonjalonAvoid typedefs ending in ``_t``, except as specified in Standard C or by POSIX. 3496bdae907SThomas Monjalon 3506bdae907SThomas Monjalon.. note:: 3516bdae907SThomas Monjalon 3526bdae907SThomas Monjalon It is recommended to use typedefs to define function pointer types, for reasons of code readability. 3536bdae907SThomas Monjalon This is especially true when the function type is used as a parameter to another function. 3546bdae907SThomas Monjalon 3556bdae907SThomas MonjalonFor example: 3566bdae907SThomas Monjalon 3576bdae907SThomas Monjalon.. code-block:: c 3586bdae907SThomas Monjalon 3596bdae907SThomas Monjalon /** 3606bdae907SThomas Monjalon * Definition of a remote launch function. 3616bdae907SThomas Monjalon */ 3626bdae907SThomas Monjalon typedef int (lcore_function_t)(void *); 3636bdae907SThomas Monjalon 3646bdae907SThomas Monjalon /* launch a function of lcore_function_t type */ 365cb056611SStephen Hemminger int rte_eal_remote_launch(lcore_function_t *f, void *arg, unsigned worker_id); 3666bdae907SThomas Monjalon 3676bdae907SThomas Monjalon 3686bdae907SThomas MonjalonC Indentation 3696bdae907SThomas Monjalon------------- 3706bdae907SThomas Monjalon 3716bdae907SThomas MonjalonGeneral 3726bdae907SThomas Monjalon~~~~~~~ 3736bdae907SThomas Monjalon 3746bdae907SThomas Monjalon* Indentation is a hard tab, that is, a tab character, not a sequence of spaces, 3756bdae907SThomas Monjalon 3766bdae907SThomas Monjalon.. note:: 3776bdae907SThomas Monjalon 3786bdae907SThomas Monjalon Global whitespace rule in DPDK, use tabs for indentation, spaces for alignment. 3796bdae907SThomas Monjalon 3806bdae907SThomas Monjalon* Do not put any spaces before a tab for indentation. 3816bdae907SThomas Monjalon* If you have to wrap a long statement, put the operator at the end of the line, and indent again. 3826bdae907SThomas Monjalon* For control statements (if, while, etc.), continuation it is recommended that the next line be indented by two tabs, rather than one, 3836bdae907SThomas Monjalon to prevent confusion as to whether the second line of the control statement forms part of the statement body or not. 3846bdae907SThomas Monjalon Alternatively, the line continuation may use additional spaces to line up to an appropriately point on the preceding line, for example, to align to an opening brace. 3856bdae907SThomas Monjalon 3866bdae907SThomas Monjalon.. note:: 3876bdae907SThomas Monjalon 3886bdae907SThomas Monjalon As with all style guidelines, code should match style already in use in an existing file. 3896bdae907SThomas Monjalon 3906bdae907SThomas Monjalon.. code-block:: c 3916bdae907SThomas Monjalon 3926bdae907SThomas Monjalon while (really_long_variable_name_1 == really_long_variable_name_2 && 3936bdae907SThomas Monjalon var3 == var4){ /* confusing to read as */ 3946bdae907SThomas Monjalon x = y + z; /* control stmt body lines up with second line of */ 3956bdae907SThomas Monjalon a = b + c; /* control statement itself if single indent used */ 3966bdae907SThomas Monjalon } 3976bdae907SThomas Monjalon 3986bdae907SThomas Monjalon if (really_long_variable_name_1 == really_long_variable_name_2 && 3996bdae907SThomas Monjalon var3 == var4){ /* two tabs used */ 4006bdae907SThomas Monjalon x = y + z; /* statement body no longer lines up */ 4016bdae907SThomas Monjalon a = b + c; 4026bdae907SThomas Monjalon } 4036bdae907SThomas Monjalon 4046bdae907SThomas Monjalon z = a + really + long + statement + that + needs + 4056bdae907SThomas Monjalon two + lines + gets + indented + on + the + 4066bdae907SThomas Monjalon second + and + subsequent + lines; 4076bdae907SThomas Monjalon 4086bdae907SThomas Monjalon 4096bdae907SThomas Monjalon* Do not add whitespace at the end of a line. 4106bdae907SThomas Monjalon 4116bdae907SThomas Monjalon* Do not add whitespace or a blank line at the end of a file. 4126bdae907SThomas Monjalon 4136bdae907SThomas Monjalon 4146bdae907SThomas MonjalonControl Statements and Loops 4156bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4166bdae907SThomas Monjalon 4176bdae907SThomas Monjalon* Include a space after keywords (if, while, for, return, switch). 4186bdae907SThomas Monjalon* Do not use braces (``{`` and ``}``) for control statements with zero or just a single statement, unless that statement is more than a single line in which case the braces are permitted. 4196bdae907SThomas Monjalon 4206bdae907SThomas Monjalon.. code-block:: c 4216bdae907SThomas Monjalon 4226bdae907SThomas Monjalon for (p = buf; *p != '\0'; ++p) 4236bdae907SThomas Monjalon ; /* nothing */ 4246bdae907SThomas Monjalon for (;;) 4256bdae907SThomas Monjalon stmt; 4266bdae907SThomas Monjalon for (;;) { 4276bdae907SThomas Monjalon z = a + really + long + statement + that + needs + 4286bdae907SThomas Monjalon two + lines + gets + indented + on + the + 4296bdae907SThomas Monjalon second + and + subsequent + lines; 4306bdae907SThomas Monjalon } 4316bdae907SThomas Monjalon for (;;) { 4326bdae907SThomas Monjalon if (cond) 4336bdae907SThomas Monjalon stmt; 4346bdae907SThomas Monjalon } 4356bdae907SThomas Monjalon if (val != NULL) 4366bdae907SThomas Monjalon val = realloc(val, newsize); 4376bdae907SThomas Monjalon 4386bdae907SThomas Monjalon 4396bdae907SThomas Monjalon* Parts of a for loop may be left empty. 4406bdae907SThomas Monjalon 4416bdae907SThomas Monjalon.. code-block:: c 4426bdae907SThomas Monjalon 4436bdae907SThomas Monjalon for (; cnt < 15; cnt++) { 4446bdae907SThomas Monjalon stmt1; 4456bdae907SThomas Monjalon stmt2; 4466bdae907SThomas Monjalon } 4476bdae907SThomas Monjalon 4486bdae907SThomas Monjalon* Closing and opening braces go on the same line as the else keyword. 4496bdae907SThomas Monjalon* Braces that are not necessary should be left out. 4506bdae907SThomas Monjalon 4516bdae907SThomas Monjalon.. code-block:: c 4526bdae907SThomas Monjalon 4536bdae907SThomas Monjalon if (test) 4546bdae907SThomas Monjalon stmt; 4556bdae907SThomas Monjalon else if (bar) { 4566bdae907SThomas Monjalon stmt; 4576bdae907SThomas Monjalon stmt; 4586bdae907SThomas Monjalon } else 4596bdae907SThomas Monjalon stmt; 4606bdae907SThomas Monjalon 4616bdae907SThomas Monjalon 4626bdae907SThomas MonjalonFunction Calls 4636bdae907SThomas Monjalon~~~~~~~~~~~~~~ 4646bdae907SThomas Monjalon 4656bdae907SThomas Monjalon* Do not use spaces after function names. 4666bdae907SThomas Monjalon* Commas should have a space after them. 4676bdae907SThomas Monjalon* No spaces after ``(`` or ``[`` or preceding the ``]`` or ``)`` characters. 4686bdae907SThomas Monjalon 4696bdae907SThomas Monjalon.. code-block:: c 4706bdae907SThomas Monjalon 4716bdae907SThomas Monjalon error = function(a1, a2); 4726bdae907SThomas Monjalon if (error != 0) 4736bdae907SThomas Monjalon exit(error); 4746bdae907SThomas Monjalon 4756bdae907SThomas Monjalon 4766bdae907SThomas MonjalonOperators 4776bdae907SThomas Monjalon~~~~~~~~~ 4786bdae907SThomas Monjalon 4796bdae907SThomas Monjalon* Unary operators do not require spaces, binary operators do. 4806bdae907SThomas Monjalon* Do not use parentheses unless they are required for precedence or unless the statement is confusing without them. 4816bdae907SThomas Monjalon However, remember that other people may be more easily confused than you. 4826bdae907SThomas Monjalon 4836bdae907SThomas MonjalonExit 4846bdae907SThomas Monjalon~~~~ 4856bdae907SThomas Monjalon 4866bdae907SThomas MonjalonExits should be 0 on success, or 1 on failure. 4876bdae907SThomas Monjalon 4886bdae907SThomas Monjalon.. code-block:: c 4896bdae907SThomas Monjalon 4906bdae907SThomas Monjalon exit(0); /* 4916bdae907SThomas Monjalon * Avoid obvious comments such as 4926bdae907SThomas Monjalon * "Exit 0 on success." 4936bdae907SThomas Monjalon */ 4946bdae907SThomas Monjalon } 4956bdae907SThomas Monjalon 4966bdae907SThomas MonjalonLocal Variables 4976bdae907SThomas Monjalon~~~~~~~~~~~~~~~ 4986bdae907SThomas Monjalon 4996bdae907SThomas Monjalon* Variables should be declared at the start of a block of code rather than in the middle. 5006bdae907SThomas Monjalon The exception to this is when the variable is ``const`` in which case the declaration must be at the point of first use/assignment. 5016bdae907SThomas Monjalon* When declaring variables in functions, multiple variables per line are OK. 5026bdae907SThomas Monjalon However, if multiple declarations would cause the line to exceed a reasonable line length, begin a new set of declarations on the next line rather than using a line continuation. 5036bdae907SThomas Monjalon* Be careful to not obfuscate the code by initializing variables in the declarations, only the last variable on a line should be initialized. 5042fe68f32SJohn McNamara If multiple variables are to be initialized when defined, put one per line. 5056bdae907SThomas Monjalon* Do not use function calls in initializers, except for ``const`` variables. 5066bdae907SThomas Monjalon 5076bdae907SThomas Monjalon.. code-block:: c 5086bdae907SThomas Monjalon 5096bdae907SThomas Monjalon int i = 0, j = 0, k = 0; /* bad, too many initializer */ 5106bdae907SThomas Monjalon 5116bdae907SThomas Monjalon char a = 0; /* OK, one variable per line with initializer */ 5126bdae907SThomas Monjalon char b = 0; 5136bdae907SThomas Monjalon 5146bdae907SThomas Monjalon float x, y = 0.0; /* OK, only last variable has initializer */ 5156bdae907SThomas Monjalon 5166bdae907SThomas Monjalon 5176bdae907SThomas MonjalonCasts and sizeof 5186bdae907SThomas Monjalon~~~~~~~~~~~~~~~~ 5196bdae907SThomas Monjalon 5206bdae907SThomas Monjalon* Casts and sizeof statements are not followed by a space. 5216bdae907SThomas Monjalon* Always write sizeof statements with parenthesis. 5226bdae907SThomas Monjalon The redundant parenthesis rules do not apply to sizeof(var) instances. 5236bdae907SThomas Monjalon 5246bdae907SThomas MonjalonC Function Definition, Declaration and Use 5256bdae907SThomas Monjalon------------------------------------------- 5266bdae907SThomas Monjalon 5276bdae907SThomas MonjalonPrototypes 5286bdae907SThomas Monjalon~~~~~~~~~~ 5296bdae907SThomas Monjalon 5306bdae907SThomas Monjalon* It is recommended (and generally required by the compiler) that all non-static functions are prototyped somewhere. 5316bdae907SThomas Monjalon* Functions local to one source module should be declared static, and should not be prototyped unless absolutely necessary. 5326bdae907SThomas Monjalon* Functions used from other parts of code (external API) must be prototyped in the relevant include file. 5336bdae907SThomas Monjalon* Function prototypes should be listed in a logical order, preferably alphabetical unless there is a compelling reason to use a different ordering. 5346bdae907SThomas Monjalon* Functions that are used locally in more than one module go into a separate header file, for example, "extern.h". 5356bdae907SThomas Monjalon* Do not use the ``__P`` macro. 5366bdae907SThomas Monjalon* Functions that are part of an external API should be documented using Doxygen-like comments above declarations. See :ref:`doxygen_guidelines` for details. 5376bdae907SThomas Monjalon* Functions that are part of the external API must have an ``rte_`` prefix on the function name. 5386bdae907SThomas Monjalon* Do not use uppercase letters - either in the form of ALL_UPPERCASE, or CamelCase - in function names. Lower-case letters and underscores only. 5396bdae907SThomas Monjalon* When prototyping functions, associate names with parameter types, for example: 5406bdae907SThomas Monjalon 5416bdae907SThomas Monjalon.. code-block:: c 5426bdae907SThomas Monjalon 5436bdae907SThomas Monjalon void function1(int fd); /* good */ 5446bdae907SThomas Monjalon void function2(int); /* bad */ 5456bdae907SThomas Monjalon 5466bdae907SThomas Monjalon* Short function prototypes should be contained on a single line. 5476bdae907SThomas Monjalon Longer prototypes, e.g. those with many parameters, can be split across multiple lines. 5486bdae907SThomas Monjalon The second and subsequent lines should be further indented as for line statement continuations as described in the previous section. 5496bdae907SThomas Monjalon 5506bdae907SThomas Monjalon.. code-block:: c 5516bdae907SThomas Monjalon 5526bdae907SThomas Monjalon static char *function1(int _arg, const char *_arg2, 5536bdae907SThomas Monjalon struct foo *_arg3, 5546bdae907SThomas Monjalon struct bar *_arg4, 5556bdae907SThomas Monjalon struct baz *_arg5); 5566bdae907SThomas Monjalon static void usage(void); 5576bdae907SThomas Monjalon 5586bdae907SThomas Monjalon.. note:: 5596bdae907SThomas Monjalon 5606bdae907SThomas Monjalon Unlike function definitions, the function prototypes do not need to place the function return type on a separate line. 5616bdae907SThomas Monjalon 5626bdae907SThomas MonjalonDefinitions 5636bdae907SThomas Monjalon~~~~~~~~~~~ 5646bdae907SThomas Monjalon 5656bdae907SThomas Monjalon* The function type should be on a line by itself preceding the function. 5666bdae907SThomas Monjalon* The opening brace of the function body should be on a line by itself. 5676bdae907SThomas Monjalon 5686bdae907SThomas Monjalon.. code-block:: c 5696bdae907SThomas Monjalon 5706bdae907SThomas Monjalon static char * 5716bdae907SThomas Monjalon function(int a1, int a2, float fl, int a4) 5726bdae907SThomas Monjalon { 5736bdae907SThomas Monjalon 5746bdae907SThomas Monjalon 5756bdae907SThomas Monjalon* Do not declare functions inside other functions. 5766bdae907SThomas Monjalon ANSI C states that such declarations have file scope regardless of the nesting of the declaration. 5776bdae907SThomas Monjalon Hiding file declarations in what appears to be a local scope is undesirable and will elicit complaints from a good compiler. 5786bdae907SThomas Monjalon* Old-style (K&R) function declaration should not be used, use ANSI function declarations instead as shown below. 5796bdae907SThomas Monjalon* Long argument lists should be wrapped as described above in the function prototypes section. 5806bdae907SThomas Monjalon 5816bdae907SThomas Monjalon.. code-block:: c 5826bdae907SThomas Monjalon 5836bdae907SThomas Monjalon /* 5846bdae907SThomas Monjalon * All major routines should have a comment briefly describing what 5856bdae907SThomas Monjalon * they do. The comment before the "main" routine should describe 5866bdae907SThomas Monjalon * what the program does. 5876bdae907SThomas Monjalon */ 5886bdae907SThomas Monjalon int 5896bdae907SThomas Monjalon main(int argc, char *argv[]) 5906bdae907SThomas Monjalon { 5916bdae907SThomas Monjalon char *ep; 5926bdae907SThomas Monjalon long num; 5936bdae907SThomas Monjalon int ch; 5946bdae907SThomas Monjalon 5956bdae907SThomas MonjalonC Statement Style and Conventions 5966bdae907SThomas Monjalon--------------------------------- 5976bdae907SThomas Monjalon 5986bdae907SThomas MonjalonNULL Pointers 5996bdae907SThomas Monjalon~~~~~~~~~~~~~ 6006bdae907SThomas Monjalon 6016bdae907SThomas Monjalon* NULL is the preferred null pointer constant. 6026bdae907SThomas Monjalon Use NULL instead of ``(type *)0`` or ``(type *)NULL``, except where the compiler does not know the destination type e.g. for variadic args to a function. 6036bdae907SThomas Monjalon* Test pointers against NULL, for example, use: 6046bdae907SThomas Monjalon 6056bdae907SThomas Monjalon.. code-block:: c 6066bdae907SThomas Monjalon 6076bdae907SThomas Monjalon if (p == NULL) /* Good, compare pointer to NULL */ 6086bdae907SThomas Monjalon 6096bdae907SThomas Monjalon if (!p) /* Bad, using ! on pointer */ 6106bdae907SThomas Monjalon 6116bdae907SThomas Monjalon 6126bdae907SThomas Monjalon* Do not use ! for tests unless it is a boolean, for example, use: 6136bdae907SThomas Monjalon 6146bdae907SThomas Monjalon.. code-block:: c 6156bdae907SThomas Monjalon 6166bdae907SThomas Monjalon if (*p == '\0') /* check character against (char)0 */ 6176bdae907SThomas Monjalon 6186bdae907SThomas MonjalonReturn Value 6196bdae907SThomas Monjalon~~~~~~~~~~~~ 6206bdae907SThomas Monjalon 6216bdae907SThomas Monjalon* Functions which create objects, or allocate memory, should return pointer types, and NULL on error. 6226bdae907SThomas Monjalon The error type should be indicated may setting the variable ``rte_errno`` appropriately. 6236bdae907SThomas Monjalon* Functions which work on bursts of packets, such as RX-like or TX-like functions, should return the number of packets handled. 6246bdae907SThomas Monjalon* Other functions returning int should generally behave like system calls: 6256bdae907SThomas Monjalon returning 0 on success and -1 on error, setting ``rte_errno`` to indicate the specific type of error. 6266bdae907SThomas Monjalon* Where already standard in a given library, the alternative error approach may be used where the negative value is not -1 but is instead ``-errno`` if relevant, for example, ``-EINVAL``. 6276bdae907SThomas Monjalon Note, however, to allow consistency across functions returning integer or pointer types, the previous approach is preferred for any new libraries. 6286bdae907SThomas Monjalon* For functions where no error is possible, the function type should be ``void`` not ``int``. 6296bdae907SThomas Monjalon* Routines returning ``void *`` should not have their return values cast to any pointer type. 6306bdae907SThomas Monjalon (Typecasting can prevent the compiler from warning about missing prototypes as any implicit definition of a function returns int, 6316bdae907SThomas Monjalon which, unlike ``void *``, needs a typecast to assign to a pointer variable.) 6326bdae907SThomas Monjalon 6336bdae907SThomas Monjalon.. note:: 6346bdae907SThomas Monjalon 6356bdae907SThomas Monjalon The above rule about not typecasting ``void *`` applies to malloc, as well as to DPDK functions. 6366bdae907SThomas Monjalon 6376bdae907SThomas Monjalon* Values in return statements should not be enclosed in parentheses. 6386bdae907SThomas Monjalon 6396bdae907SThomas MonjalonLogging and Errors 6406bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~ 6416bdae907SThomas Monjalon 6426bdae907SThomas MonjalonIn the DPDK environment, use the logging interface provided: 6436bdae907SThomas Monjalon 6446bdae907SThomas Monjalon.. code-block:: c 6456bdae907SThomas Monjalon 646c1b5fa94SOlivier Matz /* register log types for this application */ 647c1b5fa94SOlivier Matz int my_logtype1 = rte_log_register("myapp.log1"); 648c1b5fa94SOlivier Matz int my_logtype2 = rte_log_register("myapp.log2"); 6496bdae907SThomas Monjalon 650c1b5fa94SOlivier Matz /* set global log level to INFO */ 651c1b5fa94SOlivier Matz rte_log_set_global_level(RTE_LOG_INFO); 652c1b5fa94SOlivier Matz 653c1b5fa94SOlivier Matz /* only display messages higher than NOTICE for log2 (default 654c1b5fa94SOlivier Matz * is DEBUG) */ 655c1b5fa94SOlivier Matz rte_log_set_level(my_logtype2, RTE_LOG_NOTICE); 656c1b5fa94SOlivier Matz 6577f0bb634SStephen Hemminger /* enable all PMD logs (whose identifier string starts with "pmd.") */ 6587f0bb634SStephen Hemminger rte_log_set_level_pattern("pmd.*", RTE_LOG_DEBUG); 6596bdae907SThomas Monjalon 6606bdae907SThomas Monjalon /* log in debug level */ 661c1b5fa94SOlivier Matz rte_log_set_global_level(RTE_LOG_DEBUG); 662f43d3dbbSDavid Marchand RTE_LOG(DEBUG, my_logtype1, "this is a debug level message\n"); 663f43d3dbbSDavid Marchand RTE_LOG(INFO, my_logtype1, "this is a info level message\n"); 664f43d3dbbSDavid Marchand RTE_LOG(WARNING, my_logtype1, "this is a warning level message\n"); 665f43d3dbbSDavid Marchand RTE_LOG(WARNING, my_logtype2, "this is a debug level message (not displayed)\n"); 6666bdae907SThomas Monjalon 6676bdae907SThomas Monjalon /* log in info level */ 668c1b5fa94SOlivier Matz rte_log_set_global_level(RTE_LOG_INFO); 669c1b5fa94SOlivier Matz RTE_LOG(DEBUG, my_logtype1, "debug level message (not displayed)\n"); 6706bdae907SThomas Monjalon 6716bdae907SThomas MonjalonBranch Prediction 6726bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~ 6736bdae907SThomas Monjalon 6746bdae907SThomas Monjalon* When a test is done in a critical zone (called often or in a data path) the code can use the ``likely()`` and ``unlikely()`` macros to indicate the expected, or preferred fast path. 6756bdae907SThomas Monjalon They are expanded as a compiler builtin and allow the developer to indicate if the branch is likely to be taken or not. Example: 6766bdae907SThomas Monjalon 6776bdae907SThomas Monjalon.. code-block:: c 6786bdae907SThomas Monjalon 6796bdae907SThomas Monjalon #include <rte_branch_prediction.h> 6806bdae907SThomas Monjalon if (likely(x > 1)) 6816bdae907SThomas Monjalon do_stuff(); 6826bdae907SThomas Monjalon 6836bdae907SThomas Monjalon.. note:: 6846bdae907SThomas Monjalon 6856bdae907SThomas Monjalon The use of ``likely()`` and ``unlikely()`` should only be done in performance critical paths, 6866bdae907SThomas Monjalon and only when there is a clearly preferred path, or a measured performance increase gained from doing so. 6876bdae907SThomas Monjalon These macros should be avoided in non-performance-critical code. 6886bdae907SThomas Monjalon 6896bdae907SThomas MonjalonStatic Variables and Functions 6906bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6916bdae907SThomas Monjalon 6926bdae907SThomas Monjalon* All functions and variables that are local to a file must be declared as ``static`` because it can often help the compiler to do some optimizations (such as, inlining the code). 6936bdae907SThomas Monjalon* Functions that should be inlined should to be declared as ``static inline`` and can be defined in a .c or a .h file. 6946bdae907SThomas Monjalon 6956bdae907SThomas Monjalon.. note:: 6966bdae907SThomas Monjalon Static functions defined in a header file must be declared as ``static inline`` in order to prevent compiler warnings about the function being unused. 6976bdae907SThomas Monjalon 6986bdae907SThomas MonjalonConst Attribute 6996bdae907SThomas Monjalon~~~~~~~~~~~~~~~ 7006bdae907SThomas Monjalon 7016bdae907SThomas MonjalonThe ``const`` attribute should be used as often as possible when a variable is read-only. 7026bdae907SThomas Monjalon 7036bdae907SThomas MonjalonInline ASM in C code 7046bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~~~ 7056bdae907SThomas Monjalon 7066bdae907SThomas MonjalonThe ``asm`` and ``volatile`` keywords do not have underscores. The AT&T syntax should be used. 7076bdae907SThomas MonjalonInput and output operands should be named to avoid confusion, as shown in the following example: 7086bdae907SThomas Monjalon 7096bdae907SThomas Monjalon.. code-block:: c 7106bdae907SThomas Monjalon 7116bdae907SThomas Monjalon asm volatile("outb %[val], %[port]" 7126bdae907SThomas Monjalon : : 7136bdae907SThomas Monjalon [port] "dN" (port), 7146bdae907SThomas Monjalon [val] "a" (val)); 7156bdae907SThomas Monjalon 7166bdae907SThomas MonjalonControl Statements 7176bdae907SThomas Monjalon~~~~~~~~~~~~~~~~~~ 7186bdae907SThomas Monjalon 7196bdae907SThomas Monjalon* Forever loops are done with for statements, not while statements. 7206bdae907SThomas Monjalon* Elements in a switch statement that cascade should have a FALLTHROUGH comment. For example: 7216bdae907SThomas Monjalon 7226bdae907SThomas Monjalon.. code-block:: c 7236bdae907SThomas Monjalon 7246bdae907SThomas Monjalon switch (ch) { /* Indent the switch. */ 7256bdae907SThomas Monjalon case 'a': /* Don't indent the case. */ 7266bdae907SThomas Monjalon aflag = 1; /* Indent case body one tab. */ 7276bdae907SThomas Monjalon /* FALLTHROUGH */ 7286bdae907SThomas Monjalon case 'b': 7296bdae907SThomas Monjalon bflag = 1; 7306bdae907SThomas Monjalon break; 7316bdae907SThomas Monjalon case '?': 7326bdae907SThomas Monjalon default: 7336bdae907SThomas Monjalon usage(); 7346bdae907SThomas Monjalon /* NOTREACHED */ 7356bdae907SThomas Monjalon } 736d1a22085SJohn McNamara 7377db274b9SHarry van HaarenDynamic Logging 7387db274b9SHarry van Haaren--------------- 7397db274b9SHarry van Haaren 7407db274b9SHarry van HaarenDPDK provides infrastructure to perform logging during runtime. This is very 7417db274b9SHarry van Haarenuseful for enabling debug output without recompilation. To enable or disable 7427db274b9SHarry van Haarenlogging of a particular topic, the ``--log-level`` parameter can be provided 7437db274b9SHarry van Haarento EAL, which will change the log level. DPDK code can register topics, 7447db274b9SHarry van Haarenwhich allows the user to adjust the log verbosity for that specific topic. 7457db274b9SHarry van Haaren 7467db274b9SHarry van HaarenIn general, the naming scheme is as follows: ``type.section.name`` 7477db274b9SHarry van Haaren 7487db274b9SHarry van Haaren * Type is the type of component, where ``lib``, ``pmd``, ``bus`` and ``user`` 7497db274b9SHarry van Haaren are the common options. 7507db274b9SHarry van Haaren * Section refers to a specific area, for example a poll-mode-driver for an 7517db274b9SHarry van Haaren ethernet device would use ``pmd.net``, while an eventdev PMD uses 7527db274b9SHarry van Haaren ``pmd.event``. 7537db274b9SHarry van Haaren * The name identifies the individual item that the log applies to. 7547db274b9SHarry van Haaren The name section must align with 7557db274b9SHarry van Haaren the directory that the PMD code resides. See examples below for clarity. 7567db274b9SHarry van Haaren 7577db274b9SHarry van HaarenExamples: 7587db274b9SHarry van Haaren 7597db274b9SHarry van Haaren * The virtio network PMD in ``drivers/net/virtio`` uses ``pmd.net.virtio`` 7607db274b9SHarry van Haaren * The eventdev software poll mode driver in ``drivers/event/sw`` uses ``pmd.event.sw`` 7617db274b9SHarry van Haaren * The octeontx mempool driver in ``drivers/mempool/octeontx`` uses ``pmd.mempool.octeontx`` 7627db274b9SHarry van Haaren * The DPDK hash library in ``lib/librte_hash`` uses ``lib.hash`` 7637db274b9SHarry van Haaren 7647db274b9SHarry van HaarenSpecializations 7657db274b9SHarry van Haaren~~~~~~~~~~~~~~~ 7667db274b9SHarry van Haaren 7677db274b9SHarry van HaarenIn addition to the above logging topic, any PMD or library can further split 7687db274b9SHarry van Haarenlogging output by using "specializations". A specialization could be the 7697db274b9SHarry van Haarendifference between initialization code, and logs of events that occur at runtime. 7707db274b9SHarry van Haaren 7717db274b9SHarry van HaarenAn example could be the initialization log messages getting one 7727db274b9SHarry van Haarenspecialization, while another specialization handles mailbox command logging. 7737db274b9SHarry van HaarenEach PMD, library or component can create as many specializations as required. 7747db274b9SHarry van Haaren 7757db274b9SHarry van HaarenA specialization looks like this: 7767db274b9SHarry van Haaren 7777db274b9SHarry van Haaren * Initialization output: ``type.section.name.init`` 7787db274b9SHarry van Haaren * PF/VF mailbox output: ``type.section.name.mbox`` 7797db274b9SHarry van Haaren 7807db274b9SHarry van HaarenA real world example is the i40e poll mode driver which exposes two 7819631253fSFerruh Yigitspecializations, one for initialization ``pmd.net.i40e.init`` and the other for 7829631253fSFerruh Yigitthe remaining driver logs ``pmd.net.i40e.driver``. 7837db274b9SHarry van Haaren 7847db274b9SHarry van HaarenNote that specializations have no formatting rules, but please follow 7857db274b9SHarry van Haarena precedent if one exists. In order to see all current log topics and 7867db274b9SHarry van Haarenspecializations, run the ``app/test`` binary, and use the ``dump_log_types`` 787d1a22085SJohn McNamara 788d1a22085SJohn McNamaraPython Code 789d1a22085SJohn McNamara----------- 790d1a22085SJohn McNamara 7913f6f8362SLouise KilheeneyAll Python code should be compliant with 792d76a5927SJohn McNamara`PEP8 (Style Guide for Python Code) <https://www.python.org/dev/peps/pep-0008/>`_. 793d1a22085SJohn McNamara 794d1a22085SJohn McNamaraThe ``pep8`` tool can be used for testing compliance with the guidelines. 79544a6dfacSBruce Richardson 79644a6dfacSBruce RichardsonIntegrating with the Build System 79744a6dfacSBruce Richardson--------------------------------- 79844a6dfacSBruce Richardson 7993cc6ecfdSCiara PowerDPDK is built using the tools ``meson`` and ``ninja``. 80044a6dfacSBruce Richardson 801bc461743SBruce Richardson.. note:: 802bc461743SBruce Richardson 803bc461743SBruce Richardson In order to catch possible issues as soon as possible, 804bc461743SBruce Richardson it is recommended that developers build DPDK in "developer mode" to enable additional checks. 805bc461743SBruce Richardson By default, this mode is enabled if the build is being done from a git checkout, 806bc461743SBruce Richardson but the mode can be manually enabled/disabled using the 807bc461743SBruce Richardson ``developer_mode`` meson configuration option. 808bc461743SBruce Richardson 8093cc6ecfdSCiara PowerTherefore all new component additions should include a ``meson.build`` file, 8103cc6ecfdSCiara Powerand should be added to the component lists in the ``meson.build`` files in the 8113cc6ecfdSCiara Powerrelevant top-level directory: 81244a6dfacSBruce Richardsoneither ``lib`` directory or a ``driver`` subdirectory. 81344a6dfacSBruce Richardson 81444a6dfacSBruce RichardsonMeson Build File Contents - Libraries 81544a6dfacSBruce Richardson~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 81644a6dfacSBruce Richardson 81744a6dfacSBruce RichardsonThe ``meson.build`` file for a new DPDK library should be of the following basic 81844a6dfacSBruce Richardsonformat. 81944a6dfacSBruce Richardson 82044a6dfacSBruce Richardson.. code-block:: python 82144a6dfacSBruce Richardson 82244a6dfacSBruce Richardson sources = files('file1.c', ...) 823eeafaf40SRami Rosen headers = files('file1.h', ...) 82444a6dfacSBruce Richardson 82544a6dfacSBruce Richardson 826eeafaf40SRami RosenThis will build based on a number of conventions and assumptions within the DPDK 82744a6dfacSBruce Richardsonitself, for example, that the library name is the same as the directory name in 82844a6dfacSBruce Richardsonwhich the files are stored. 82944a6dfacSBruce Richardson 83044a6dfacSBruce RichardsonFor a library ``meson.build`` file, there are number of variables which can be 83144a6dfacSBruce Richardsonset, some mandatory, others optional. The mandatory fields are: 83244a6dfacSBruce Richardson 83344a6dfacSBruce Richardsonsources 83444a6dfacSBruce Richardson **Default Value = []**. 83544a6dfacSBruce Richardson This variable should list out the files to be compiled up to create the 83644a6dfacSBruce Richardson library. Files must be specified using the meson ``files()`` function. 83744a6dfacSBruce Richardson 83844a6dfacSBruce Richardson 83944a6dfacSBruce RichardsonThe optional fields are: 84044a6dfacSBruce Richardson 84144a6dfacSBruce Richardsonbuild 84244a6dfacSBruce Richardson **Default Value = true** 84344a6dfacSBruce Richardson Used to optionally compile a library, based on its dependencies or 8448baad6f8SBruce Richardson environment. When set to "false" the ``reason`` value, explained below, should 8458baad6f8SBruce Richardson also be set to explain to the user why the component is not being built. 8468baad6f8SBruce Richardson A simple example of use would be: 84744a6dfacSBruce Richardson 84844a6dfacSBruce Richardson.. code-block:: python 84944a6dfacSBruce Richardson 850adf93ca5SBruce Richardson if not is_linux 85144a6dfacSBruce Richardson build = false 8528baad6f8SBruce Richardson reason = 'only supported on Linux' 85344a6dfacSBruce Richardson endif 85444a6dfacSBruce Richardson 85544a6dfacSBruce Richardson 85644a6dfacSBruce Richardsoncflags 857b114af16SBruce Richardson **Default Value = [<-march/-mcpu flags>]**. 85844a6dfacSBruce Richardson Used to specify any additional cflags that need to be passed to compile 85944a6dfacSBruce Richardson the sources in the library. 86044a6dfacSBruce Richardson 86144a6dfacSBruce Richardsondeps 86244a6dfacSBruce Richardson **Default Value = ['eal']**. 86344a6dfacSBruce Richardson Used to list the internal library dependencies of the library. It should 86444a6dfacSBruce Richardson be assigned to using ``+=`` rather than overwriting using ``=``. The 86544a6dfacSBruce Richardson dependencies should be specified as strings, each one giving the name of 86644a6dfacSBruce Richardson a DPDK library, without the ``librte_`` prefix. Dependencies are handled 86744a6dfacSBruce Richardson recursively, so specifying e.g. ``mempool``, will automatically also 86844a6dfacSBruce Richardson make the library depend upon the mempool library's dependencies too - 86944a6dfacSBruce Richardson ``ring`` and ``eal``. For libraries that only depend upon EAL, this 87044a6dfacSBruce Richardson variable may be omitted from the ``meson.build`` file. For example: 87144a6dfacSBruce Richardson 87244a6dfacSBruce Richardson.. code-block:: python 87344a6dfacSBruce Richardson 87444a6dfacSBruce Richardson deps += ['ethdev'] 87544a6dfacSBruce Richardson 87644a6dfacSBruce Richardson 87744a6dfacSBruce Richardsonext_deps 87844a6dfacSBruce Richardson **Default Value = []**. 87944a6dfacSBruce Richardson Used to specify external dependencies of this library. They should be 88044a6dfacSBruce Richardson returned as dependency objects, as returned from the meson 88144a6dfacSBruce Richardson ``dependency()`` or ``find_library()`` functions. Before returning 88244a6dfacSBruce Richardson these, they should be checked to ensure the dependencies have been 88344a6dfacSBruce Richardson found, and, if not, the ``build`` variable should be set to ``false``. 88444a6dfacSBruce Richardson For example: 88544a6dfacSBruce Richardson 88644a6dfacSBruce Richardson.. code-block:: python 88744a6dfacSBruce Richardson 88844a6dfacSBruce Richardson my_dep = dependency('libX', required: 'false') 88944a6dfacSBruce Richardson if my_dep.found() 89044a6dfacSBruce Richardson ext_deps += my_dep 89144a6dfacSBruce Richardson else 89244a6dfacSBruce Richardson build = false 89344a6dfacSBruce Richardson endif 89444a6dfacSBruce Richardson 89544a6dfacSBruce Richardson 89644a6dfacSBruce Richardsonheaders 89744a6dfacSBruce Richardson **Default Value = []**. 89844a6dfacSBruce Richardson Used to return the list of header files for the library that should be 89944a6dfacSBruce Richardson installed to $PREFIX/include when ``ninja install`` is run. As with 90044a6dfacSBruce Richardson source files, these should be specified using the meson ``files()`` 90144a6dfacSBruce Richardson function. 90205050ac4SBruce Richardson When ``check_includes`` build option is set to ``true``, each header file 90305050ac4SBruce Richardson has additional checks performed on it, for example to ensure that it is 90405050ac4SBruce Richardson not missing any include statements for dependent headers. 90505050ac4SBruce Richardson For header files which are public, but only included indirectly in 90605050ac4SBruce Richardson applications, these checks can be skipped by using the ``indirect_headers`` 90705050ac4SBruce Richardson variable rather than ``headers``. 90805050ac4SBruce Richardson 90905050ac4SBruce Richardsonindirect_headers 91005050ac4SBruce Richardson **Default Value = []**. 91105050ac4SBruce Richardson As with ``headers`` option above, except that the files are not checked 91205050ac4SBruce Richardson for all needed include files as part of a DPDK build when 91305050ac4SBruce Richardson ``check_includes`` is set to ``true``. 91444a6dfacSBruce Richardson 915610beca4SBruce Richardsonincludes: 916610beca4SBruce Richardson **Default Value = []**. 917610beca4SBruce Richardson Used to indicate any additional header file paths which should be 918610beca4SBruce Richardson added to the header search path for other libs depending on this 919610beca4SBruce Richardson library. EAL uses this so that other libraries building against it 920610beca4SBruce Richardson can find the headers in subdirectories of the main EAL directory. The 921610beca4SBruce Richardson base directory of each library is always given in the include path, 922610beca4SBruce Richardson it does not need to be specified here. 923610beca4SBruce Richardson 92444a6dfacSBruce Richardsonname 92544a6dfacSBruce Richardson **Default Value = library name derived from the directory name**. 92644a6dfacSBruce Richardson If a library's .so or .a file differs from that given in the directory 92744a6dfacSBruce Richardson name, the name should be specified using this variable. In practice, 92844a6dfacSBruce Richardson since the convention is that for a library called ``librte_xyz.so``, the 92944a6dfacSBruce Richardson sources are stored in a directory ``lib/librte_xyz``, this value should 93044a6dfacSBruce Richardson never be needed for new libraries. 93144a6dfacSBruce Richardson 93244a6dfacSBruce Richardson.. note:: 93344a6dfacSBruce Richardson 93444a6dfacSBruce Richardson The name value also provides the name used to find the function version 93544a6dfacSBruce Richardson map file, as part of the build process, so if the directory name and 93644a6dfacSBruce Richardson library names differ, the ``version.map`` file should be named 93744a6dfacSBruce Richardson consistently with the library, not the directory 93844a6dfacSBruce Richardson 93944a6dfacSBruce Richardsonobjs 94044a6dfacSBruce Richardson **Default Value = []**. 94144a6dfacSBruce Richardson This variable can be used to pass to the library build some pre-built 94244a6dfacSBruce Richardson objects that were compiled up as part of another target given in the 94344a6dfacSBruce Richardson included library ``meson.build`` file. 94444a6dfacSBruce Richardson 9458baad6f8SBruce Richardsonreason 9468baad6f8SBruce Richardson **Default Value = '<unknown reason>'**. 9478baad6f8SBruce Richardson This variable should be used when a library is not to be built i.e. when 9488baad6f8SBruce Richardson ``build`` is set to "false", to specify the reason why a library will not be 9498baad6f8SBruce Richardson built. For missing dependencies this should be of the form 9508baad6f8SBruce Richardson ``'missing dependency, "libname"'``. 9518baad6f8SBruce Richardson 952a5d4ea59SBruce Richardsonuse_function_versioning 953a5d4ea59SBruce Richardson **Default Value = false**. 954a5d4ea59SBruce Richardson Specifies if the library in question has ABI versioned functions. If it 955a5d4ea59SBruce Richardson has, this value should be set to ensure that the C files are compiled 956a5d4ea59SBruce Richardson twice with suitable parameters for each of shared or static library 957a5d4ea59SBruce Richardson builds. 958a5d4ea59SBruce Richardson 95944a6dfacSBruce RichardsonMeson Build File Contents - Drivers 96044a6dfacSBruce Richardson~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 96144a6dfacSBruce Richardson 96244a6dfacSBruce RichardsonFor drivers, the values are largely the same as for libraries. The variables 96344a6dfacSBruce Richardsonsupported are: 96444a6dfacSBruce Richardson 96544a6dfacSBruce Richardsonbuild 96644a6dfacSBruce Richardson As above. 96744a6dfacSBruce Richardson 96844a6dfacSBruce Richardsoncflags 96944a6dfacSBruce Richardson As above. 97044a6dfacSBruce Richardson 97144a6dfacSBruce Richardsondeps 97244a6dfacSBruce Richardson As above. 97344a6dfacSBruce Richardson 97444a6dfacSBruce Richardsonext_deps 97544a6dfacSBruce Richardson As above. 97644a6dfacSBruce Richardson 97744a6dfacSBruce Richardsonincludes 97844a6dfacSBruce Richardson **Default Value = <driver directory>** Some drivers include a base 97944a6dfacSBruce Richardson directory for additional source files and headers, so we have this 98044a6dfacSBruce Richardson variable to allow the headers from that base directory to be found when 98144a6dfacSBruce Richardson compiling driver sources. Should be appended to using ``+=`` rather than 98244a6dfacSBruce Richardson overwritten using ``=``. The values appended should be meson include 98344a6dfacSBruce Richardson objects got using the ``include_directories()`` function. For example: 98444a6dfacSBruce Richardson 98544a6dfacSBruce Richardson.. code-block:: python 98644a6dfacSBruce Richardson 98744a6dfacSBruce Richardson includes += include_directories('base') 98844a6dfacSBruce Richardson 98944a6dfacSBruce Richardsonname 99044a6dfacSBruce Richardson As above, though note that each driver class can define it's own naming 99144a6dfacSBruce Richardson scheme for the resulting ``.so`` files. 99244a6dfacSBruce Richardson 99344a6dfacSBruce Richardsonobjs 99444a6dfacSBruce Richardson As above, generally used for the contents of the ``base`` directory. 99544a6dfacSBruce Richardson 99644a6dfacSBruce Richardsonpkgconfig_extra_libs 99744a6dfacSBruce Richardson **Default Value = []** 99844a6dfacSBruce Richardson This variable is used to pass additional library link flags through to 99944a6dfacSBruce Richardson the DPDK pkgconfig file generated, for example, to track any additional 100044a6dfacSBruce Richardson libraries that may need to be linked into the build - especially when 100144a6dfacSBruce Richardson using static libraries. Anything added here will be appended to the end 100244a6dfacSBruce Richardson of the ``pkgconfig --libs`` output. 100344a6dfacSBruce Richardson 10048baad6f8SBruce Richardsonreason 10058baad6f8SBruce Richardson As above. 10068baad6f8SBruce Richardson 100744a6dfacSBruce Richardsonsources [mandatory] 100844a6dfacSBruce Richardson As above 100944a6dfacSBruce Richardson 101030105f66SDavid Marchandheaders 101130105f66SDavid Marchand As above 101230105f66SDavid Marchand 101344a6dfacSBruce Richardsonversion 101444a6dfacSBruce Richardson As above 1015*f2cdd95fSBruce Richardson 1016*f2cdd95fSBruce Richardson 1017*f2cdd95fSBruce RichardsonMeson Coding Style 1018*f2cdd95fSBruce Richardson------------------ 1019*f2cdd95fSBruce Richardson 1020*f2cdd95fSBruce RichardsonThe following guidelines apply to the build system code in meson.build files in DPDK. 1021*f2cdd95fSBruce Richardson 1022*f2cdd95fSBruce Richardson* Indentation should be using 4 spaces, no hard tabs. 1023*f2cdd95fSBruce Richardson 1024*f2cdd95fSBruce Richardson* Line continuations should be doubly-indented to ensure visible difference from normal indentation. 1025*f2cdd95fSBruce Richardson Any line continuations beyond the first may be singly indented to avoid large amounts of indentation. 1026*f2cdd95fSBruce Richardson 1027*f2cdd95fSBruce Richardson* Lists of files or components must be alphabetical unless doing so would cause errors. 1028*f2cdd95fSBruce Richardson 1029*f2cdd95fSBruce Richardson* Two formats are supported for lists of files or list of components: 1030*f2cdd95fSBruce Richardson 1031*f2cdd95fSBruce Richardson * For a small number of list entries, generally 3 or fewer, all elements may be put on a single line. 1032*f2cdd95fSBruce Richardson In this case, the opening and closing braces of the list must be on the same line as the list items. 1033*f2cdd95fSBruce Richardson No trailing comma is put on the final list entry. 1034*f2cdd95fSBruce Richardson * For lists with more than 3 items, 1035*f2cdd95fSBruce Richardson it is recommended that the lists be put in the files with a *single* entry per line. 1036*f2cdd95fSBruce Richardson In this case, the opening brace, or ``files`` function call must be on a line on its own, 1037*f2cdd95fSBruce Richardson and the closing brace must similarly be on a line on its own at the end. 1038*f2cdd95fSBruce Richardson To help with readability of nested sublists, the closing brace should be dedented to appear 1039*f2cdd95fSBruce Richardson at the same level as the opening braced statement. 1040*f2cdd95fSBruce Richardson The final list entry must have a trailing comma, 1041*f2cdd95fSBruce Richardson so that adding a new entry to the list never modifies any other line in the list. 1042*f2cdd95fSBruce Richardson 1043*f2cdd95fSBruce RichardsonExamples:: 1044*f2cdd95fSBruce Richardson 1045*f2cdd95fSBruce Richardson sources = files('file1.c', 'file2.c') 1046*f2cdd95fSBruce Richardson 1047*f2cdd95fSBruce Richardson subdirs = ['dir1', 'dir2'] 1048*f2cdd95fSBruce Richardson 1049*f2cdd95fSBruce Richardson headers = files( 1050*f2cdd95fSBruce Richardson 'header1.c', 1051*f2cdd95fSBruce Richardson 'header2.c', 1052*f2cdd95fSBruce Richardson 'header3.c', # always include trailing comma 1053*f2cdd95fSBruce Richardson ) # closing brace at indent level of opening brace 1054*f2cdd95fSBruce Richardson 1055*f2cdd95fSBruce Richardson components = [ 1056*f2cdd95fSBruce Richardson 'comp1', 1057*f2cdd95fSBruce Richardson 'comp2', 1058*f2cdd95fSBruce Richardson ... 1059*f2cdd95fSBruce Richardson 'compN', 1060*f2cdd95fSBruce Richardson ] 1061