Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/python3.14/internal/pycore_backoff.h
1 2 #ifndef Py_INTERNAL_BACKOFF_H 3 #define Py_INTERNAL_BACKOFF_H 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 #ifndef Py_BUILD_CORE 9 # error "this header requires Py_BUILD_CORE define" 10 #endif 11 12 #include <assert.h> 13 #include <stdbool.h> 14 #include "pycore_structs.h" // _Py_BackoffCounter 15 16 /* 16-bit countdown counters using exponential backoff. 17 18 These are used by the adaptive specializer to count down until 19 it is time to specialize an instruction. If specialization fails 20 the counter is reset using exponential backoff. 21 22 Another use is for the Tier 2 optimizer to decide when to create 23 a new Tier 2 trace (executor). Again, exponential backoff is used. 24 25 The 16-bit counter is structured as a 12-bit unsigned 'value' 26 and a 4-bit 'backoff' field. When resetting the counter, the 27 backoff field is incremented (until it reaches a limit) and the 28 value is set to a bit mask representing the value 2**backoff - 1. 29 The maximum backoff is 12 (the number of bits in the value). 30 31 There is an exceptional value which must not be updated, 0xFFFF. 32 */ 33 34 #define BACKOFF_BITS 4 35 #define MAX_BACKOFF 12 36 #define UNREACHABLE_BACKOFF 15 37 38 static inline bool 39 is_unreachable_backoff_counter(_Py_BackoffCounter counter) 40 { 41 return counter.value_and_backoff == UNREACHABLE_BACKOFF; 42 } 43 44 static inline _Py_BackoffCounter 45 make_backoff_counter(uint16_t value, uint16_t backoff) 46 { 47 assert(backoff <= 15); 48 assert(value <= 0xFFF); 49 _Py_BackoffCounter result; 50 result.value_and_backoff = (value << BACKOFF_BITS) | backoff; 51 return result; 52 } 53 54 static inline _Py_BackoffCounter 55 forge_backoff_counter(uint16_t counter) 56 { 57 _Py_BackoffCounter result; 58 result.value_and_backoff = counter; 59 return result; 60 } 61 62 static inline _Py_BackoffCounter 63 restart_backoff_counter(_Py_BackoffCounter counter) 64 { 65 assert(!is_unreachable_backoff_counter(counter)); 66 int backoff = counter.value_and_backoff & 15; 67 if (backoff < MAX_BACKOFF) { 68 return make_backoff_counter((1 << (backoff + 1)) - 1, backoff + 1); 69 } 70 else { 71 return make_backoff_counter((1 << MAX_BACKOFF) - 1, MAX_BACKOFF); 72 } 73 } 74 75 static inline _Py_BackoffCounter 76 pause_backoff_counter(_Py_BackoffCounter counter) 77 { 78 _Py_BackoffCounter result; 79 result.value_and_backoff = counter.value_and_backoff | (1 << BACKOFF_BITS); 80 return result; 81 } 82 83 static inline _Py_BackoffCounter 84 advance_backoff_counter(_Py_BackoffCounter counter) 85 { 86 _Py_BackoffCounter result; 87 result.value_and_backoff = counter.value_and_backoff - (1 << BACKOFF_BITS); 88 return result; 89 } 90 91 static inline bool 92 backoff_counter_triggers(_Py_BackoffCounter counter) 93 { 94 /* Test whether the value is zero and the backoff is not UNREACHABLE_BACKOFF */ 95 return counter.value_and_backoff < UNREACHABLE_BACKOFF; 96 } 97 98 /* Initial JUMP_BACKWARD counter. 99 * This determines when we create a trace for a loop. */ 100 #define JUMP_BACKWARD_INITIAL_VALUE 4095 101 #define JUMP_BACKWARD_INITIAL_BACKOFF 12 102 static inline _Py_BackoffCounter 103 initial_jump_backoff_counter(void) 104 { 105 return make_backoff_counter(JUMP_BACKWARD_INITIAL_VALUE, 106 JUMP_BACKWARD_INITIAL_BACKOFF); 107 } 108 109 /* Initial exit temperature. 110 * Must be larger than ADAPTIVE_COOLDOWN_VALUE, 111 * otherwise when a side exit warms up we may construct 112 * a new trace before the Tier 1 code has properly re-specialized. */ 113 #define SIDE_EXIT_INITIAL_VALUE 4095 114 #define SIDE_EXIT_INITIAL_BACKOFF 12 115 116 static inline _Py_BackoffCounter 117 initial_temperature_backoff_counter(void) 118 { 119 return make_backoff_counter(SIDE_EXIT_INITIAL_VALUE, 120 SIDE_EXIT_INITIAL_BACKOFF); 121 } 122 123 /* Unreachable backoff counter. */ 124 static inline _Py_BackoffCounter 125 initial_unreachable_backoff_counter(void) 126 { 127 return make_backoff_counter(0, UNREACHABLE_BACKOFF); 128 } 129 130 #ifdef __cplusplus 131 } 132 #endif 133 #endif /* !Py_INTERNAL_BACKOFF_H */