@@ -3376,20 +3376,32 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
3376
3376
}
3377
3377
}
3378
3378
3379
+ /*
3380
+ * The invariant for DCH cache entry management is that DCHCounter is equal
3381
+ * to the maximum age value among the existing entries, and we increment it
3382
+ * whenever an access occurs. If we approach overflow, deal with that by
3383
+ * halving all the age values, so that we retain a fairly accurate idea of
3384
+ * which entries are oldest.
3385
+ */
3386
+ static inline void
3387
+ DCH_prevent_counter_overflow (void )
3388
+ {
3389
+ if (DCHCounter >= (INT_MAX - 1 ))
3390
+ {
3391
+ for (int i = 0 ; i < n_DCHCache ; i ++ )
3392
+ DCHCache [i ]-> age >>= 1 ;
3393
+ DCHCounter >>= 1 ;
3394
+ }
3395
+ }
3396
+
3379
3397
/* select a DCHCacheEntry to hold the given format picture */
3380
3398
static DCHCacheEntry *
3381
3399
DCH_cache_getnew (const char * str )
3382
3400
{
3383
3401
DCHCacheEntry * ent ;
3384
3402
3385
- /* handle counter overflow by resetting all ages */
3386
- if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES ))
3387
- {
3388
- DCHCounter = 0 ;
3389
-
3390
- for (int i = 0 ; i < n_DCHCache ; i ++ )
3391
- DCHCache [i ]-> age = (++ DCHCounter );
3392
- }
3403
+ /* Ensure we can advance DCHCounter below */
3404
+ DCH_prevent_counter_overflow ();
3393
3405
3394
3406
/*
3395
3407
* If cache is full, remove oldest entry (or recycle first not-valid one)
@@ -3445,14 +3457,8 @@ DCH_cache_getnew(const char *str)
3445
3457
static DCHCacheEntry *
3446
3458
DCH_cache_search (const char * str )
3447
3459
{
3448
- /* handle counter overflow by resetting all ages */
3449
- if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES ))
3450
- {
3451
- DCHCounter = 0 ;
3452
-
3453
- for (int i = 0 ; i < n_DCHCache ; i ++ )
3454
- DCHCache [i ]-> age = (++ DCHCounter );
3455
- }
3460
+ /* Ensure we can advance DCHCounter below */
3461
+ DCH_prevent_counter_overflow ();
3456
3462
3457
3463
for (int i = 0 ; i < n_DCHCache ; i ++ )
3458
3464
{
@@ -4057,20 +4063,26 @@ do { \
4057
4063
(_n)->zero_end = 0; \
4058
4064
} while(0)
4059
4065
4066
+ /* This works the same as DCH_prevent_counter_overflow */
4067
+ static inline void
4068
+ NUM_prevent_counter_overflow (void )
4069
+ {
4070
+ if (NUMCounter >= (INT_MAX - 1 ))
4071
+ {
4072
+ for (int i = 0 ; i < n_NUMCache ; i ++ )
4073
+ NUMCache [i ]-> age >>= 1 ;
4074
+ NUMCounter >>= 1 ;
4075
+ }
4076
+ }
4077
+
4060
4078
/* select a NUMCacheEntry to hold the given format picture */
4061
4079
static NUMCacheEntry *
4062
4080
NUM_cache_getnew (const char * str )
4063
4081
{
4064
4082
NUMCacheEntry * ent ;
4065
4083
4066
- /* handle counter overflow by resetting all ages */
4067
- if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES ))
4068
- {
4069
- NUMCounter = 0 ;
4070
-
4071
- for (int i = 0 ; i < n_NUMCache ; i ++ )
4072
- NUMCache [i ]-> age = (++ NUMCounter );
4073
- }
4084
+ /* Ensure we can advance NUMCounter below */
4085
+ NUM_prevent_counter_overflow ();
4074
4086
4075
4087
/*
4076
4088
* If cache is full, remove oldest entry (or recycle first not-valid one)
@@ -4126,14 +4138,8 @@ NUM_cache_getnew(const char *str)
4126
4138
static NUMCacheEntry *
4127
4139
NUM_cache_search (const char * str )
4128
4140
{
4129
- /* handle counter overflow by resetting all ages */
4130
- if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES ))
4131
- {
4132
- NUMCounter = 0 ;
4133
-
4134
- for (int i = 0 ; i < n_NUMCache ; i ++ )
4135
- NUMCache [i ]-> age = (++ NUMCounter );
4136
- }
4141
+ /* Ensure we can advance NUMCounter below */
4142
+ NUM_prevent_counter_overflow ();
4137
4143
4138
4144
for (int i = 0 ; i < n_NUMCache ; i ++ )
4139
4145
{
0 commit comments