1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* Misc low level processor primitives */ |
3 | #ifndef _LINUX_PROCESSOR_H |
4 | #define _LINUX_PROCESSOR_H |
5 | |
6 | #include <asm/processor.h> |
7 | |
8 | /* |
9 | * spin_begin is used before beginning a busy-wait loop, and must be paired |
10 | * with spin_end when the loop is exited. spin_cpu_relax must be called |
11 | * within the loop. |
12 | * |
13 | * The loop body should be as small and fast as possible, on the order of |
14 | * tens of instructions/cycles as a guide. It should and avoid calling |
15 | * cpu_relax, or any "spin" or sleep type of primitive including nested uses |
16 | * of these primitives. It should not lock or take any other resource. |
17 | * Violations of these guidelies will not cause a bug, but may cause sub |
18 | * optimal performance. |
19 | * |
20 | * These loops are optimized to be used where wait times are expected to be |
21 | * less than the cost of a context switch (and associated overhead). |
22 | * |
23 | * Detection of resource owner and decision to spin or sleep or guest-yield |
24 | * (e.g., spin lock holder vcpu preempted, or mutex owner not on CPU) can be |
25 | * tested within the loop body. |
26 | */ |
27 | #ifndef spin_begin |
28 | #define spin_begin() |
29 | #endif |
30 | |
31 | #ifndef spin_cpu_relax |
32 | #define spin_cpu_relax() cpu_relax() |
33 | #endif |
34 | |
35 | #ifndef spin_end |
36 | #define spin_end() |
37 | #endif |
38 | |
39 | /* |
40 | * spin_until_cond can be used to wait for a condition to become true. It |
41 | * may be expected that the first iteration will true in the common case |
42 | * (no spinning), so that callers should not require a first "likely" test |
43 | * for the uncontended case before using this primitive. |
44 | * |
45 | * Usage and implementation guidelines are the same as for the spin_begin |
46 | * primitives, above. |
47 | */ |
48 | #ifndef spin_until_cond |
49 | #define spin_until_cond(cond) \ |
50 | do { \ |
51 | if (unlikely(!(cond))) { \ |
52 | spin_begin(); \ |
53 | do { \ |
54 | spin_cpu_relax(); \ |
55 | } while (!(cond)); \ |
56 | spin_end(); \ |
57 | } \ |
58 | } while (0) |
59 | |
60 | #endif |
61 | |
62 | #endif /* _LINUX_PROCESSOR_H */ |
63 | |