@@ -15,13 +15,7 @@ extern "C" {
1515
1616
1717typedef struct {
18- union {
19- struct {
20- uint16_t backoff : 4 ;
21- uint16_t value : 12 ;
22- };
23- uint16_t as_counter ; // For printf("%#x", ...)
24- };
18+ uint16_t value_and_backoff ;
2519} _Py_BackoffCounter ;
2620
2721
@@ -38,17 +32,19 @@ typedef struct {
3832 and a 4-bit 'backoff' field. When resetting the counter, the
3933 backoff field is incremented (until it reaches a limit) and the
4034 value is set to a bit mask representing the value 2**backoff - 1.
41- The maximum backoff is 12 (the number of value bits).
35+ The maximum backoff is 12 (the number of bits in the value ).
4236
4337 There is an exceptional value which must not be updated, 0xFFFF.
4438*/
4539
46- #define UNREACHABLE_BACKOFF 0xFFFF
40+ #define BACKOFF_BITS 4
41+ #define MAX_BACKOFF 12
42+ #define UNREACHABLE_BACKOFF 15
4743
4844static inline bool
4945is_unreachable_backoff_counter (_Py_BackoffCounter counter )
5046{
51- return counter .as_counter == UNREACHABLE_BACKOFF ;
47+ return counter .value_and_backoff == UNREACHABLE_BACKOFF ;
5248}
5349
5450static inline _Py_BackoffCounter
@@ -57,52 +53,52 @@ make_backoff_counter(uint16_t value, uint16_t backoff)
5753 assert (backoff <= 15 );
5854 assert (value <= 0xFFF );
5955 _Py_BackoffCounter result ;
60- result .value = value ;
61- result .backoff = backoff ;
56+ result .value_and_backoff = (value << BACKOFF_BITS ) | backoff ;
6257 return result ;
6358}
6459
6560static inline _Py_BackoffCounter
6661forge_backoff_counter (uint16_t counter )
6762{
6863 _Py_BackoffCounter result ;
69- result .as_counter = counter ;
64+ result .value_and_backoff = counter ;
7065 return result ;
7166}
7267
7368static inline _Py_BackoffCounter
7469restart_backoff_counter (_Py_BackoffCounter counter )
7570{
7671 assert (!is_unreachable_backoff_counter (counter ));
77- if (counter .backoff < 12 ) {
78- return make_backoff_counter ((1 << (counter .backoff + 1 )) - 1 , counter .backoff + 1 );
72+ int backoff = counter .value_and_backoff & 15 ;
73+ if (backoff < MAX_BACKOFF ) {
74+ return make_backoff_counter ((1 << (backoff + 1 )) - 1 , backoff + 1 );
7975 }
8076 else {
81- return make_backoff_counter ((1 << 12 ) - 1 , 12 );
77+ return make_backoff_counter ((1 << MAX_BACKOFF ) - 1 , MAX_BACKOFF );
8278 }
8379}
8480
8581static inline _Py_BackoffCounter
8682pause_backoff_counter (_Py_BackoffCounter counter )
8783{
88- return make_backoff_counter (counter .value | 1 , counter .backoff );
84+ _Py_BackoffCounter result ;
85+ result .value_and_backoff = counter .value_and_backoff | (1 << BACKOFF_BITS );
86+ return result ;
8987}
9088
9189static inline _Py_BackoffCounter
9290advance_backoff_counter (_Py_BackoffCounter counter )
9391{
94- if (!is_unreachable_backoff_counter (counter )) {
95- return make_backoff_counter ((counter .value - 1 ) & 0xFFF , counter .backoff );
96- }
97- else {
98- return counter ;
99- }
92+ _Py_BackoffCounter result ;
93+ result .value_and_backoff = counter .value_and_backoff - (1 << BACKOFF_BITS );
94+ return result ;
10095}
10196
10297static inline bool
10398backoff_counter_triggers (_Py_BackoffCounter counter )
10499{
105- return counter .value == 0 ;
100+ /* Test whether the value is zero and the backoff is not UNREACHABLE_BACKOFF */
101+ return counter .value_and_backoff < UNREACHABLE_BACKOFF ;
106102}
107103
108104/* Initial JUMP_BACKWARD counter.
@@ -136,7 +132,7 @@ initial_temperature_backoff_counter(void)
136132static inline _Py_BackoffCounter
137133initial_unreachable_backoff_counter (void )
138134{
139- return forge_backoff_counter ( UNREACHABLE_BACKOFF );
135+ return make_backoff_counter ( 0 , UNREACHABLE_BACKOFF );
140136}
141137
142138#ifdef __cplusplus
0 commit comments