From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 650113237 for ; Wed, 8 Apr 2015 12:43:57 +0200 (CEST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP; 08 Apr 2015 03:43:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,544,1422950400"; d="scan'208";a="478251457" Received: from irsmsx107.ger.corp.intel.com ([163.33.3.99]) by FMSMGA003.fm.intel.com with ESMTP; 08 Apr 2015 03:43:55 -0700 Received: from irsmsx155.ger.corp.intel.com (163.33.192.3) by IRSMSX107.ger.corp.intel.com (163.33.3.99) with Microsoft SMTP Server (TLS) id 14.3.224.2; Wed, 8 Apr 2015 11:43:54 +0100 Received: from irsmsx109.ger.corp.intel.com ([169.254.13.95]) by irsmsx155.ger.corp.intel.com ([169.254.14.178]) with mapi id 14.03.0224.002; Wed, 8 Apr 2015 11:43:53 +0100 From: "Butler, Siobhan A" To: Thomas Monjalon , "dev@dpdk.org" Thread-Topic: [dpdk-dev] tools brainstorming Thread-Index: AQHQYx105wa2dYsDE0GLqygeszi7351DCqJg Date: Wed, 8 Apr 2015 10:43:53 +0000 Message-ID: <0C5AFCA4B3408848ADF2A3073F7D8CC86D58F9C2@IRSMSX109.ger.corp.intel.com> References: <3571725.20GtF5MAnU@xps13> In-Reply-To: <3571725.20GtF5MAnU@xps13> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [163.33.239.182] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] tools brainstorming X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Apr 2015 10:43:58 -0000 Hi all, To add to the tools brainstorming - I propose we use the following Coding S= tandards as the basis of guidelines on coding style going forward. The style outlined below is in alignment with the current convention used f= or the majority of the project. Any thoughts/suggestions or feedback welcome. Thanks Siobhan :) Coding Style ~~~~~~~~~~ Description ----------- This document specifies the preferred style for source files in the DPDK so= urce tree.=20 It is based on the Linux Kernel coding guidelines and the FreeBSD 7.2 Kerne= l Developer's Manual (see man style(9)),=20 but was heavily modified for the needs of the DPDK. Many of the style rules= are implicit in the examples.=20 Be careful to check the examples before assuming that style is silent on an= issue.=20 General Guidelines ------------------ The rules and guidelines given in this document cannot cover every situatio= n, so the following general guidelines should be used as a fallback:=20 The code style should be consistent within each individual file, and within= each file in a given directory or module - in the case of creating new fil= es=20 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.=20 The following more specific recommendations apply to all sections, both for= C and assembly code:=20 Line length is recommended to be not more than 80 characters, including com= ments. [Tab stop size should be assumed to be at least 4-characters wide]=20 Indentation should be to no more than 3 levels deep.=20 NOTE The above are recommendations, and not hard limits. However, it is exp= ected that the recommendations should be followed in all but the rarest sit= uations.=20 C Comment Style Usual Comments -------------- These comments should be used in normal cases. To document a public API, a = doxygen-like format must be used: refer to Doxygen Documentation.=20 /* * VERY important single-line comments look like this. */ =20 /* Most single-line comments look like this. */ =20 /* * Multi-line comments look like this. Make them real sentences. Fill * them so they look like real paragraphs. */ License Header -------------- Each file should begin with a special comment tag which will contain the ap= propriate copyright and license for the file (Generally BSD License).=20 After any copyright header, a blank line should be left before any other co= ntents, e.g. include statements in a C file.=20 C Preprocessor Directives ------------------------- Header Includes In DPDK sources, the include files should be ordered as following:=20 libc includes (system includes first)=20 DPDK EAL includes=20 DPDK misc libraries includes=20 application-specific includes=20 Example:=20 #include #include =20 #include =20 #include #include =20 #include "application.h" Global pathnames are defined in . Pathnames local to the program g= o in "pathnames.h" in the local directory.=20 #include Leave another blank line before the user include files.=20 #include "pathnames.h" /* Local includes in double quotes. */ NOTE Please avoid, as much as possible, including headers from other header= s file. Doing so should be properly explained and justified.=20 Headers should be protected against multiple inclusion with the usual:=20 #ifndef _FILE_H_ #define _FILE_H_ =20 /* Code */ =20 #endif /* _FILE_H_ */ Macros Do not ``#define`` or declare names in the implementation namespace except = for implementing application interfaces.=20 The names of ``unsafe`` macros (ones that have side effects), and the names= of macros for manifest constants, are all in uppercase.=20 The expansions of expression-like macros are either a single token or have = outer parentheses. If a macro is an inline expansion of a function,=20 the function name is all in lowercase and the macro has the same name all i= n uppercase. Right-justify the backslashes;=20 it makes it easier to read. If the macro encapsulates a compound statement,= enclose it in a do loop, so that it can be used safely in if statements.=20 Any final statement-terminating semicolon should be supplied by the macro i= nvocation rather than the macro, to make parsing easier for pretty-printers= and editors.=20 #define MACRO(x, y) do { \ variable =3D (x) + (y); \ (y) +=3D 2; \ }while (0) NOTE Wherever possible, enums and typedefs should be preferred to macros, s= ince they provide additional degrees=20 of type-safety and can allow compilers to emit extra warnings about unsafe = code.=20 Conditional Compilation ----------------------- When code is conditionally compiled using #ifdef or #if, a comment may be a= dded following the matching #endif or #else to=20 permit the reader to easily discern where conditionally compiled code regio= ns end. This comment should be used only for=20 (subjectively) long regions, regions greater than 20 lines, or where a seri= es of nested #ifdef 's may be confusing to the reader.=20 Exceptions may be made for cases where code is conditionally not compiled f= or the purposes of lint(1), even though the uncompiled=20 region may be small. The comment should be separated from the #endif or #el= se by a single space. For short conditionally compiled regions,=20 a closing comment should not be used.=20 The comment for #endif should match the expression used in the correspondin= g #if or #ifdef. The comment for #else and #elif=20 should match the inverse of the expression(s) used in the preceding #if and= /or #elif statements. In the comments,=20 the subexpression defined(FOO) is abbreviated as FOO. For the purposes of c= omments, #ifndef FOO is treated as #if !defined(FOO).=20 #ifdef KTRACE #include #endif =20 #ifdef COMPAT_43 /* A large region here, or other conditional code. */ #else /* !COMPAT_43 */ /* Or here. */ #endif /* COMPAT_43 */ =20 #ifndef COMPAT_43 /* Yet another large region here, or other conditional code. */ #else /* COMPAT_43 */ /* Or here. */ #endif /* !COMPAT_43 */ NOTE Conditional compilation should be used only when absolutely necessary,= as it increases the number of target binaries that need to be built and te= sted.=20 C Types Integers For 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.=20 Enumerations ------------ Enumeration values are all uppercase.=20 enum enumtype { ONE, TWO } et; Bitfields --------- The developer should group bitfields that are included in the same integer,= as follows:=20 struct grehdr { uint16_t rec:3, srr:1, seq:1, key:1, routing:1, csum:1, version:3, reserved:4, ack:1; /* ... */ } Variable Declarations --------------------- In declarations, do not put any whitespace between asterisks and adjacent t= okens, except for tokens that are identifiers related to types.=20 (These identifiers are the names of basic types, type qualifiers, and typed= ef-names other than the one being declared.)=20 Separate these identifiers from asterisks using a single space.=20 Structure Declarations When declaring variables in structures, declare them sorted by use, then by= size (largest to smallest), and then in alphabetical order.=20 Alignment constraints may override the previous rules. The first category n= ormally does not apply, but there are exceptions.=20 Each structure element gets its own line. Try to make the structure readabl= e by aligning the member names using spaces as shown below.=20 Names following extremely long types, which therefore cannot be easily alig= ned with the rest, should be separated by a single space.=20 struct foo { struct foo *next; /* List of active foo. */ struct mumble amumble; /* Comment for mumble. */ int bar; /* Try to align the comments. */ struct verylongtypename *baz; /* Won't fit with other members */ }; Major structures should be declared at the top of the file in which they ar= e used, or in separate header files if they are used=20 in multiple source files. Use of the structures should be by separate decla= rations and should be extern if they are declared in a header file.=20 Queues Use queue(3) macros rather than rolling your own lists, whenever possible. = Thus, the previous example would be better written:=20 #include =20 struct foo { LIST_ENTRY(foo) link; /* Use queue macros for foo lists. */ struct mumble amumble; /* Comment for mumble. */ int bar; /* Try to align the comments. */ struct verylongtypename *baz; /* Won't fit with other members */ }; LIST_HEAD(, foo) foohead; /* Head of global foo list. */ DPDK also provides an optimized way to store elements in lockless rings. Th= is should be used in all data-path code, when there are several=20 consumer and/or producers to avoid locking for concurrent access.=20 Typedefs Avoid using typedefs for structure types. For example, use:=20 struct my_struct_type { /* ... */ }; =20 struct my_struct_type my_var; rather than:=20 typedef struct my_struct_type { /* ... */ } my_struct_type; =20 my_struct_type my_var Typedefs are problematic because they do not properly hide their underlying= type; for example, you need to know if the typedef is=20 the structure itself, as shown above, or a pointer to the structure. In add= ition, they must be declared exactly once, whereas an=20 incomplete structure type can be mentioned as many times as necessary. Type= defs are difficult to use in stand-alone header files.=20 The 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),= =20 or there must be a back-door mechanism for obtaining the typedef.=20 NOTE #defines used instead of typedefs also are problematic (since they do = not propagate the pointer type correctly due to direct text replacement).=20 For example, ``#define pint int *`` does not work as expected, while ``type= def int *pint`` does work. As stated when discussing macros, typedefs=20 should be preferred to macros in cases like this.=20 When convention requires a typedef; make its name match the struct tag. Avo= id typedefs ending in ``_t``, except as specified in Standard C or by POSIX= .=20 /* Make the structure name match the typedef. */ typedef struct bar { int level; } BAR; typedef int foo; /* This is foo. */ typedef const long baz; /* This is baz. */ C Function Definition, Declaration and Use Prototypes It is recommended, but not required that all functions are prototyped somew= here.=20 Any function prototypes for private functions (that is, functions not used = elsewhere) go at the top of the first source module. Functions=20 local to one source module should be declared static.=20 Functions used from other parts of code (external API) must be prototyped i= n the relevant include file.=20 Function prototypes should be listed in a logical order, preferably alphabe= tical unless there is a compelling reason to use a different ordering.=20 Functions that are used locally in more than one module go into a separate = header file, for example, "extern.h".=20 Do not use the ``__P`` macro.=20 Functions that are part of an external API should be documented using Doxyg= en-like comments above declarations. See the Doxgen documentation topic for= details.=20 Associate names with parameter types, for example:=20 void function(int fd); Short function prototypes should be contained on a single line. Longer prot= otypes, e.g. those with many parameters,=20 can be split across multiple lines. Multi-line prototypes should use space-= indentation to enable function parameters to line up:=20 static char *function1(int _arg, const char *_arg2,=20 struct foo *_arg3, struct bar *_arg4, struct baz *_arg5); static void usage(void); Definitions ----------- The function type should be on a line by itself preceding the function. The= opening brace of the function body should be on a line by itself.=20 static char * function(int a1, int a2, float fl, int a4) { Do not declare functions inside other functions. ANSI C states that such de= clarations have file scope regardless of the nesting of the declaration.=20 Hiding file declarations in what appears to be a local scope is undesirable= and will elicit complaints from a good compiler.=20 Old-style (K&R) function declaration should not be used, use ANSI function = declarations instead as shown below. Long argument lists=20 should be wrapped as described above in the function prototypes section.=20 /* * All major routines should have a comment briefly describing what * they do. The comment before the "main" routine should describe * what the program does. */ int main(int argc, char *argv[]) { char *ep; long num; int ch; C Command Line Parsing ---------------------- For consistency, getopt(3) should be used to parse options. Options should = be sorted in the getopt(3) call and the switch statement,=20 unless parts of the switch cascade. Elements in a switch statement that cas= cade should have a FALLTHROUGH comment.=20 Numerical arguments should be checked for accuracy. Code that cannot be rea= ched should have a NOTREACHED comment.=20 while ((ch =3D getopt(argc, argv, "abNn:")) !=3D -1) switch (ch) { /* Indent the switch. */ case 'a': /* Don't indent the case. */ aflag =3D 1; /* Indent case body one tab. */ /* FALLTHROUGH */ case 'b': bflag =3D 1; break; case 'N': Nflag =3D 1; break; case 'n': num =3D strtol(optarg, &ep, 10); if (num <=3D 0 || *ep !=3D '\0') { warnx("illegal number, -n argument -- %s", optarg); usage(); } break; case '?': default: usage(); /* NOTREACHED */ } argc -=3D optind; argv +=3D optind; C Indentation ------------- Control Statements and Loops Include a space after keywords (if, while, for, return, switch). Do not use= braces (``{`` and ``}``) for control statements with zero or just a=20 single statement, unless that statement is more than a single line in which= case the braces are permitted. Forever loops are done with for statements,= not while statements.=20 for (p =3D buf; *p !=3D '\0'; ++p) ; /* nothing */ for (;;) stmt; for (;;) { z =3D a + really + long + statement + that + needs + two + lines + gets + indented + on + the +=20 second + and + subsequent + lines; } for (;;) { if (cond) stmt; } if (val !=3D NULL) val =3D realloc(val, newsize); Parts of a for loop may be left empty. It is recommended that you do not pu= t declarations inside blocks unless the routine is unusually complicated.=20 for (; cnt < 15; cnt++) { stmt1; stmt2; } Indentation is a hard tab, that is, a tab character, not a sequence of spac= es.=20 NOTE General rule in DPDK, use tabs for indentation, spaces for alignment.= =20 If you have to wrap a long statement, put the operator at the end of the li= ne, and indent again. For control statements (if, while, etc.),=20 it is recommended that the next line be indented by two tabs, rather than o= ne, to prevent confusion as to whether the second line of the=20 control statement forms part of the statement body or not. For non-control = statements, this issue does not apply, so they can be indented=20 by a single tab. However, a two-tab indent is recommended in this case also= to keep consistency across all statement types.=20 while (really_long_variable_name_1 =3D=3D really_long_variable_name_2 && var3 =3D=3D var4){ x =3D y + z; /* control stmt body lines up with second line of */ a =3D b + c; /* control statement itself if single indent used */ } =20 if (really_long_variable_name_1 =3D=3D really_long_variable_name_2 && var3 =3D=3D var4){ /* two tabs used */ x =3D y + z; /* statement body no longer lines up */ a =3D b + c; } =20 z =3D a + really + long + statement + that + needs + two + lines + gets + indented + on + the +=20 second + and + subsequent + lines; Do not add whitespace at the end of a line.=20 Closing and opening braces go on the same line as the else keyword. Braces = that are not necessary should be left out.=20 if (test) stmt; else if (bar) { stmt; stmt; } else stmt; Function Calls -------------- Do not use spaces after function names. Commas should have a space after th= em. No spaces after ``(`` or ``[`` or preceding the ``]`` or ``)`` characte= rs.=20 error =3D function(a1, a2); if (error !=3D 0) exit(error); Operators --------- Unary operators do not require spaces, binary operators do. Do not use pare= ntheses unless they are required for precedence or unless the=20 statement is confusing without them. Remember that other people may be more= easily confused than you.=20 Exit Exits should be 0 on success, or 1 on failure.=20 exit(0); /* * Avoid obvious comments such as * "Exit 0 on success." */ } Local Variables --------------- When declaring variables in functions, declare them sorted by size, then in= alphabetical order. Multiple variables per line are OK.=20 If a line overflows reuse the type keyword.=20 Be careful to not obfuscate the code by initializing variables in the decla= rations, only the last variable on a line should be initialized.=20 If multiple variables are to be initialised when defined, put one per line.= Do not use function calls in initializers.=20 int i =3D 0, j =3D 0, k =3D 0; /* bad, too many initializer */ =20 char a =3D 0; /* OK, one variable per line with initializer */ char b =3D 0; =20 float x, y =3D 0.0; /* OK, only last variable has initializer */ Casts and sizeof Casts and sizeof statements are not followed by a space. Always write sizeo= f statements with parenthesis.=20 The redundant parenthesis rules do not apply to sizeof(var) instances.=20 C Style and Conventions NULL Pointers NULL is the preferred null pointer constant. Use NULL instead of ``(type *)= 0`` or ``(type *)NULL`` in contexts where the compiler knows the type,=20 for example, in assignments. Use ``(type *)NULL`` in other contexts, in par= ticular for all function args.=20 (Casting is essential for variadic args and is necessary for other args if = the function prototype might not be in scope.) Test pointers against NULL, = for example, use::=20 (p =3D f()) =3D=3D NULL not::=20 !(p =3D f()) Do not use ! for tests unless it is a boolean, for example, use::=20 if (*p =3D=3D '\0') not::=20 if (!*p) Return Value ------------ If possible, functions should return 0 on success and a negative value on e= rror. The negative value should be ``-errno`` if relevant, for example, ``-= EINVAL``.=20 Routines returning ``void *`` should not have their return values cast to a= ny pointer type.=20 (Typecasting can prevent the compiler from warning about missing prototypes= as any implicit definition of a function returns int - which, unlike "void= *" needs a typecast to assign to a pointer variable.)=20 NOTE The above rule applies to malloc, as well as to DPDK functions.=20 Values in return statements should be enclosed in parentheses.=20 Logging and Errors ------------------ In the DPDK environment, use the logging interface provided::=20 #define RTE_LOGTYPE_TESTAPP1 RTE_LOGTYPE_USER1 #define RTE_LOGTYPE_TESTAPP2 RTE_LOGTYPE_USER2 =20 /* enable these logs type */ rte_set_log_type(RTE_LOGTYPE_TESTAPP1, 1); rte_set_log_type(RTE_LOGTYPE_TESTAPP2, 1); =20 /* log in debug level */ rte_set_log_level(RTE_LOG_DEBUG); RTE_LOG(DEBUG, TESTAPP1, "this is is a debug level message\n"); RTE_LOG(INFO, TESTAPP1, "this is is a info level message\n"); RTE_LOG(WARNING, TESTAPP1, "this is is a warning level message\n"); =20 /* log in info level */ rte_set_log_level(RTE_LOG_INFO); RTE_LOG(DEBUG, TESTAPP2, "debug level message (not displayed)\n"); In a userland program that is not a DPDK application, use err(3) or warn(3)= . Do not create your own variant.=20 if ((four =3D malloc(sizeof(struct foo))) =3D=3D NULL) err(1, (char *)NULL); if ((six =3D (int *)overflow()) =3D=3D NULL) errx(1, "number overflowed"); return (eight); } Variable Arguments List ----------------------- Variable numbers of arguments should look like this:=20 #include =20 void vaf(const char *fmt, ...) { va_list ap; =20 va_start(ap, fmt); STUFF; va_end(ap); /* No return needed for void functions. */ } =20 static void usage() { /* Insert an empty line if the function has no local variables. */ Printf ------ Use printf(3), not fputs(3), puts(3), putchar(3) or whatever. It is faster = and usually cleaner, and helps to avoid unnecessary bugs. However, be aware= of format string bugs::=20 int main(int argc, char **argv) { if(argc !=3D 2) exit(1); printf(argv[1]); /* bad ! */ printf("%s", argv[1]); /* correct */ Usage ----- Usage statements should look like the manual pages SYNOPSIS. The usage stat= ement should be structured in the following order:=20 1. Options without operands come first, in alphabetical order, inside a sin= gle set of brackets (``[`` and ``]``).=20 2. Options with operands come next, also in alphabetical order, with each o= ption and its argument inside its own pair of brackets.=20 3. Required arguments (if any) are next, listed in the order they should be= specified on the command line.=20 4. Finally, any optional arguments, listed in the order they should be spec= ified, and all inside brackets.=20 A bar (`|') separates ``either-or`` options/arguments, and multiple options= /arguments, which are specified together, are placed in a single set of bra= ckets.=20 "usage: f [-aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\n" "usage: f [-a | -b] [-c [-dEe] [-n number]]\n" =20 (void)fprintf(stderr, "usage: f [-ab]\n"); exit(1); } Note that the manual page options description should list the options in pu= re alphabetical order. That is, without regard to=20 whether an option takes arguments or not. The alphabetical ordering should = take into account the case ordering shown above.=20 Branch Prediction ----------------- When a test is done in a critical zone (called often or in a data path) use= the ``likely()`` and ``unlikely()`` macros. They are expanded=20 as a compiler builtin and allow the developer to indicate if the branch is = likely to be taken or not. Example:=20 #include if (likely(x > 1)) do_stuff(); Static Variables and Functions ------------------------------ All functions and variables that are local to a file must be declared as ``= static`` because it can often help the compiler to do=20 some optimizations (such as, inlining the code).=20 Functions that must be inlined have to be declared as ``static inline`` and= can be defined in a .c or a .h file.=20 Const Attribute --------------- Particular care must be taken with the use of the ``const`` attribute. It s= hould be used as often as possible when a variable is read-only.=20 ASM Coding Rules ---------------- Assembly Syntax NASM is used for assembly, with the syntax, therefore guidelines given here= are appropriate to this target.=20 [GNU as is intended to support both syntax variants, but that is not docume= nted here]. The following general guidelines are valid in any case.=20 globals, extern and macros are to be defined at the top of the file=20 labels should stay explicit, and are left aligned=20 code is indented with a tabulation, no spaces=20 instruction and operands should be separated by a tab too=20 code should be separated in blocks=20 blocks, when possible, should start with a comment explanation=20 Sample code:=20 ; comment header =20 ; export this symbol [GLOBAL entry] =20 ; external variables and functions [EXTERN variable] =20 ; 16 bits code [BITS 16] =20 ; macros like BIOS_START EQU 0x7C00 =20 entry: =20 ; Clear interrupt flag cli =20 ; Set segment registers to 0 xor bx, bx mov es, bx mov fs, bx mov gs, bx mov ds, bx mov ss, bx mov sp, 0x7C00 sti =20 ;; [...] snip [...] Use of C-style macros is allowed. When compiling ASM code, a file is parsed= by the C preprocessor. It is then allowed to share some constants between = C and assembly code, in a ``.h`` file.=20 Inline ASM in C code The ``asm`` and ``volatile`` keywords do not have underscores. The AT&T syn= tax should be used. Input and output operands should be named to avoid conf= usion,=20 as shown in the following example::=20 asm volatile("outb %[val], %[port]" : : [port] "dN" (port), [val] "a" (val)); Environment or Architecture-specific Sources In DPDK and DPDK applications, some code is specific to an architecture (i6= 86, x86_64) or to an executive environment (bare-metal or linuxapp) and so = on.=20 There are several ways to handle specific code:=20 Use a ``#ifdef`` with the CONFIG option in the C code. This can be done wh= en the differences are small and they can be embedded in the same C file::= =20 #ifdef RTE_ARCH_I686 toto(); #else titi(); #endif Use the CONFIG option in the Makefile. This is done when the differences ar= e more significant. In this case, the code is split into two separate files that are architecture or environment specific.=20 The same logic applies to header files.=20 By convention, a file is common if it is not located in a directory indicat= ing that it is specific. For instance, a file located in a=20 subdir of "x86_64" directory is specific to this architecture. A file locat= ed in a subdir of "linuxapp" is specific to this execution environment.=20 NOTE As in the linux kernel, the "CONFIG_" prefix is not used in C code. Th= is is only needed in Makefiles or shell scripts.=20 Per Architecture Sources The following config options can be used:=20 CONFIG_RTE_ARCH is a string that contains the name of the architecture.=20 CONFIG_RTE_ARCH_I686, CONFIG_RTE_ARCH_X86_64 or CONFIG_RTE_ARCH_X86_64_32 = are defined only if we are building for those architectures.=20 Per Execution Environment Sources The following config options can be used:=20 CONFIG_RTE_EXEC_ENV is a string that contains the name of the executive en= vironment.=20 CONFIG_RTE_EXEC_ENV_BAREMETAL or CONFIG_RTE_EXEC_ENV_LINUXAPP are defined = only if we are building for this execution environment.=20 Per Driver Sources RTE_LIBRTE_IGB_PMD or RTE_LIBRTE_IXGBE_PMD are defined only if we are usin= g this driver.=20 Doxygen Documentation --------------------- The API documentation is automatically generated in the DPDK framework. Tha= t is why all files that are part of the public=20 API must be documented using Doxygen syntax.=20 The public API comprises functions of DPDK that can be used by an external = application that will use the SDK. Only the Doxygen=20 syntax described in the coding rules (this document) should be used in the = code. All the Doxygen features are described in the Doxygen manual online.= =20 Documenting a Function All public functions must be documented. The documentation is placed in the= header file, above the declaration of the function.=20 The definition of the function may be documented, but using standard commen= ts (not in doxygen format).=20 Private functions can be documented using Doxygen. The following is an exam= ple of function documentation:=20 /** * Summary here; one sentence on one line (should not exceed 80 chars). * * A more detailed description goes here. * * A blank line forms a paragraph. There should be no trailing white-space * anywhere. * * @param first * "@param" is a Doxygen directive to describe a function parameter. Lik= e * some other directives, it takes a term/summary on the same line and a * description (this text) indented by 2 spaces on the next line. All * descriptive text should wrap at 80 chars, without going over. * Newlines are NOT supported within directives; if a newline would be * before this text, it would be appended to the general description abo= ve. * @param second * There should be no newline between multiple directives (of the same * type). * * @return * "@return" is a different Doxygen directive to describe the return val= ue * of a function, if there is any. */ int rte_foo(int first, int second) Documenting Files Each public file may start with a comment describing what the file does. Fo= r example:=20 /** * @file * This file describes the coding rules of RTE. * * It contains the coding rules of C code, ASM code, reStructured * Text documentation, and of course how to use doxygen to document * public API. */ Documenting Constants and Variables /** * The definition of a funny TRUE. */ #define TRUE 0 #define TRUE 1 /**< another way to document a macro */ /** * Frequency of the HPET counter in Hz * * @see rte_eal_hpet_init() */ extern uint64_t eal_hpet_resolution_hz; Documenting Structures Public structures should also be documented. The ``/**<`` sequence can be u= sed to documented the fields of the structure, as shown in the following ex= ample:=20 /** * Structure describing a memzone, which is a contiguous portions of * physical memory identified by a name. */ struct rte_memzone { =20 #define MEMZONE_NAMESIZE 32 char name[MEMZONE_NAMESIZE]; /**< name of the memory zone */ =20 phys_addr_t phys_addr; /**< start physical address */ void *addr; /**< start virtual address */ uint64_t len; /**< len of the memzone */ =20 int socket_id; /**< NUMA socket id */ }; Using Lists Using the minus character, it is possible to generate a bullet list. The mi= nus signs must be column-aligned. If the minus sign is followed by a hash,= =20 then it generates an enumerated list. Refer to the official Doxygen documen= tation for more information.=20 /** * A list of events: * - mouse events * -# mouse move event * -# mouse click event\n * More info about the click event. * -# mouse double click event * - keyboard events * -# key down event * -# key up event * * More text here. */ See Also Sections The @see keyword can be used to highlight a link to an existing function, f= ile, or URL. This directive should be placed on one line, without anything = else, at the bottom of the documentation header.=20 /** * (documentation of function, file, ...) * * @see rte_foo() * @see eal_memzone.c */ =20