You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This guide is tailored for libxlio, a performance-critical networking library.
8
+
9
+
## Basic Principles
10
+
11
+
- Use English for all code and documentation.
12
+
- Create necessary types and classes.
13
+
- Use Doxygen style comments to document public classes and methods.
14
+
- Follow the one-definition rule (ODR).
15
+
- Prioritize performance without sacrificing code clarity.
16
+
17
+
## Nomenclature
18
+
19
+
- Use PascalCase for classes and structures.
20
+
- Use snake_case for variables, functions, and methods.
21
+
- Use ALL_CAPS for constants and macros.
22
+
- Use snake_case for file and directory names.
23
+
- Use UPPERCASE for environment variables.
24
+
- Private/protected data members must use `m_` prefix (e.g., `m_count`, `m_buffer`).
25
+
- Static data members must use `s_` prefix (e.g., `s_instance`).
26
+
- Global variables must use `g_` prefix (e.g., `g_tcp_seg_pool`).
27
+
- Avoid magic numbers and define constants.
28
+
- Start each function with a verb.
29
+
- Use verbs for boolean variables. Example: is_valid, has_error, can_delete, etc.
30
+
- Precede getters with the word `get` (e.g., `get_count()`).
31
+
- Precede setters with the word `set` (e.g., `set_count()`).
32
+
- Use complete words instead of abbreviations and ensure correct spelling.
33
+
- Except for standard abbreviations like api, url, etc.
34
+
- Except for well-known abbreviations:
35
+
- i, j, k for loops
36
+
- err for errors
37
+
- ctx for contexts
38
+
- req, res for request/response parameters
39
+
40
+
## Auto Keyword
41
+
42
+
Use of `auto` should be carefully considered in performance-critical code:
43
+
44
+
- **Encouraged**: For iterator declarations and inside templates where it simplifies code.
45
+
```cpp
46
+
for (auto &elem : container) { }
47
+
```
48
+
- **Allowed**: When the initializer is a class name and it doesn't complicate readability.
49
+
```cpp
50
+
auto obj = MyClass();
51
+
```
52
+
- **Discouraged**: In other situations to avoid:
53
+
- Hiding the type of variables, complicating code understanding.
54
+
- Obscuring integer promotion and bit operations.
55
+
- Hiding whether assignment uses copy or reference semantics.
56
+
- Making performance implications unclear.
57
+
- **Rationale**: Performance-critical code requires visibility into types for proper optimization and understanding of memory operations.
58
+
59
+
## Formatting
60
+
61
+
Follow the clang-format style defined in contrib/jenkins_tests/style.conf:
62
+
63
+
- Use 4 spaces for indentation (no tabs except in Makefiles).
64
+
- Maximum line length: 100 characters.
65
+
- Outermost namespace blocks should not be indented.
66
+
- Case labels align with their switch statement (not indented).
67
+
- Function definitions: place opening brace on its own line.
68
+
```cpp
69
+
int function()
70
+
{
71
+
// function body
72
+
}
73
+
```
74
+
- Other braces (classes, loops, conditionals): opening brace on same line, closing brace on its own line.
75
+
```cpp
76
+
class MyClass {
77
+
// class body
78
+
};
79
+
80
+
if (condition) {
81
+
// code
82
+
}
83
+
```
84
+
- Always use braces for control statements, even for single-line bodies.
85
+
- No blank spaces at the end of a line.
86
+
87
+
## Pointers and References
88
+
89
+
- Place `*` and `&` by the variable name, not the type.
90
+
```cpp
91
+
// Right:
92
+
int *ptr;
93
+
bool foo(char *str, std::vector<int> &result);
94
+
95
+
// Wrong:
96
+
int* ptr;
97
+
bool foo(char* str, std::vector<int>& result);
98
+
```
99
+
- Use raw pointers for performance-critical paths where necessary.
100
+
- Smart pointers (std::unique_ptr, std::shared_ptr) are acceptable for higher-level resource management.
101
+
- Custom memory pools and allocators are preferred for frequently allocated objects.
102
+
103
+
## Functions
104
+
105
+
- Write focused functions with a single purpose and clear intent.
106
+
- Keep functions readable and maintainable (avoid arbitrary instruction limits; focus on clarity).
107
+
- Name functions with a verb and something else.
108
+
- If it returns a boolean, use is_x or has_x, can_x, etc.
109
+
- If it doesn't return anything (void), use execute_x or save_x, update_x, etc.
110
+
- Avoid nesting blocks by:
111
+
- Early checks and returns.
112
+
- Extraction to utility functions.
113
+
- Use standard library algorithms (std::for_each, std::transform, std::find, etc.) to avoid function nesting.
114
+
- Reduce function parameters using structs or classes:
115
+
- Use an object to pass multiple parameters.
116
+
- Use an object to return multiple results.
117
+
- Declare necessary types for input arguments and output.
118
+
- Use a single level of abstraction.
119
+
120
+
## Data
121
+
122
+
- Don't abuse primitive types and encapsulate data in composite types.
123
+
- Avoid data validations in functions and use classes with internal validation.
124
+
- Prefer immutability for data.
125
+
- Use const for data that doesn't change.
126
+
- Use constexpr for compile-time constants.
127
+
128
+
## Classes
129
+
130
+
- Follow SOLID principles.
131
+
- Prefer composition over inheritance.
132
+
- Declare interfaces as abstract classes or concepts.
133
+
- Write small classes with a single purpose.
134
+
- Less than 200 instructions.
135
+
- Less than 10 public methods.
136
+
- Less than 10 properties.
137
+
- Use the Rule of Five (or Rule of Zero) for resource management.
138
+
- Make member variables private and provide getters/setters where necessary.
139
+
- Use const-correctness for member functions.
140
+
141
+
## Class Layout
142
+
143
+
Field layout is critical for performance optimization in libxlio:
144
+
145
+
- Group all fields together (either at top or bottom of class definition).
146
+
- Group all methods together, separately from fields.
147
+
- Do NOT mix methods and fields in the class definition.
148
+
- **Rationale**: Field layout matters for padding and cache miss optimizations. Mixing fields and methods complicates visual perception and estimation of the resulting ABI.
149
+
150
+
**Right:**
151
+
```cpp
152
+
class Foo {
153
+
public:
154
+
Foo();
155
+
void method1();
156
+
157
+
protected:
158
+
void method2();
159
+
160
+
private:
161
+
void method3();
162
+
163
+
public:
164
+
int m_field1;
165
+
166
+
protected:
167
+
int m_field2;
168
+
169
+
private:
170
+
int m_field3;
171
+
};
172
+
```
173
+
174
+
**Also acceptable (no repeated visibility):**
175
+
```cpp
176
+
class Bar {
177
+
public:
178
+
Bar();
179
+
void method1();
180
+
181
+
private:
182
+
void method2();
183
+
184
+
int m_field1;
185
+
int m_field2;
186
+
};
187
+
```
188
+
189
+
## Exceptions
190
+
191
+
libxlio has a configurable exception handling mechanism. Follow these guidelines:
192
+
193
+
- Use exceptions sparingly in performance-critical code paths.
194
+
- Prefer error codes for expected error conditions in hot paths.
195
+
- Use exceptions for truly exceptional situations during initialization/setup.
196
+
- Use custom exception classes (`xlio_exception`) when exceptions are needed.
197
+
- If you catch an exception, it should be to:
198
+
- Fix an expected problem.
199
+
- Add context with additional information.
200
+
- Otherwise, use a global handler.
201
+
- **Rationale**: Exception handling overhead is inappropriate for data path operations in a performance-critical library.
202
+
203
+
## Memory Management
204
+
205
+
Memory management in libxlio prioritizes performance:
206
+
207
+
- Use custom memory pools and allocators for performance-critical allocations.
208
+
- Raw pointers are acceptable and often preferred in hot paths.
209
+
- Smart pointers (std::unique_ptr, std::shared_ptr) for non-performance-critical resource management.
210
+
- Use RAII (Resource Acquisition Is Initialization) principles where they don't impact performance.
211
+
- Avoid memory leaks by proper resource management.
212
+
- Consider cache alignment and padding when designing data structures.
213
+
- Use `xlio_allocator` and related custom allocators for frequently allocated objects.
214
+
- Prefer stack allocation over heap allocation when possible.
215
+
216
+
## Performance-Critical Programming
217
+
218
+
libxlio is a performance-critical library. Apply these optimizations when appropriate:
219
+
220
+
- Use inline functions for hot paths where beneficial.
221
+
- Consider cache line alignment (typically 64 bytes) for frequently accessed structures.
222
+
- Use `likely`/`unlikely` compiler hints for branch prediction in hot paths.
223
+
- Minimize allocations in the data path; prefer object pools and pre-allocation.
224
+
- Prefer stack allocation over heap allocation when object lifetime allows.
225
+
- Use `const` and `constexpr` aggressively to enable compiler optimizations.
226
+
- Be mindful of false sharing in multi-threaded code.
227
+
- Profile before optimizing; measure the impact of changes.
228
+
- Document performance-critical sections and the reasoning behind optimizations.
229
+
230
+
## Include Order
231
+
232
+
Organize includes to minimize dependencies and reduce compile time:
233
+
234
+
1. `config.h` (if applicable)
235
+
2. Related header (for .cpp files, include the corresponding .h)
236
+
3. C system headers (e.g., `<sys/types.h>`, `<unistd.h>`)
237
+
4. C++ standard library headers (e.g., `<string>`, `<vector>`)
238
+
5. Other libraries' headers (e.g., `<json-c/json.h>`)
239
+
6. Your project's headers (e.g., `"core/util/utils.h"`)
240
+
241
+
**Example:**
242
+
```cpp
243
+
#include "config.h"
244
+
245
+
#include "foo/server/fooserver.h"
246
+
247
+
#include <sys/types.h>
248
+
#include <unistd.h>
249
+
250
+
#include <string>
251
+
#include <vector>
252
+
253
+
#include "base/basictypes.h"
254
+
#include "foo/server/bar.h"
255
+
```
256
+
257
+
- Keep dependencies minimal to reduce compile time.
258
+
- Use forward declarations when possible to avoid unnecessary includes.
259
+
260
+
## Comments
261
+
262
+
- Use Doxygen style comments to document public classes, methods, and APIs.
263
+
```cpp
264
+
/**
265
+
* @brief Brief description of the function
266
+
* @param arg1 Description of first parameter
267
+
* @return Description of return value
268
+
*/
269
+
int my_function(int arg1);
270
+
```
271
+
- Use C++ style (`//`) for single-line comments.
272
+
- Use C style (`/* */`) for multi-line comments with proper alignment:
273
+
```cpp
274
+
/* The preferred comment style for multi-line comments
275
+
* looks like this.
276
+
*/
277
+
```
278
+
- Comments should explain **WHAT** your code does and **WHY**, not **HOW**.
279
+
- Write comments as English prose with proper capitalization and punctuation.
280
+
- Comments are important for readability and maintainability in complex, performance-critical code.
281
+
282
+
## Testing
283
+
284
+
- Follow the Arrange-Act-Assert convention for tests.
285
+
- Name test variables clearly.
286
+
- Write unit tests for each public function.
287
+
- Follow the Given-When-Then convention.
288
+
- All features or bug fixes **must be tested** by unit tests.
289
+
290
+
## Project Structure
291
+
292
+
- Use modular architecture.
293
+
- Organize code into logical directories.
294
+
- Use automake and autotools.
295
+
- Separate interface (.h) from implementation (.cpp).
296
+
- Use namespaces to organize code logically.
297
+
298
+
## Standard Library
299
+
300
+
- Use the C++ Standard Library when it doesn't compromise performance.
301
+
- Use std::vector, std::map, std::unordered_map, etc. for collections (except in hot paths).
302
+
- Use std::chrono for time-related operations.
303
+
- Consider custom implementations for performance-critical data structures.
304
+
305
+
## Concurrency
306
+
307
+
libxlio is a multi-threaded library. Thread safety is critical:
308
+
309
+
- Use std::thread, std::mutex, std::lock_guard for thread safety.
310
+
- Use std::atomic for atomic operations.
311
+
- Avoid data races by proper synchronization.
312
+
- Use thread-safe data structures when necessary.
313
+
- Be mindful of lock contention in hot paths.
314
+
- Consider lock-free algorithms for performance-critical sections.
315
+
- Document thread-safety guarantees for all public APIs.
0 commit comments