Skip to content

Commit 467c78e

Browse files
committed
Attempt at cleaning up getting the next bucket
The code for getting the next bucket was unnecessarily complex and hard to read.
1 parent d7ec3de commit 467c78e

1 file changed

Lines changed: 24 additions & 43 deletions

File tree

src/pg_stat_monitor.c

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,65 +2452,46 @@ static uint64
24522452
get_next_wbucket(pgsmSharedState *pgsm)
24532453
{
24542454
struct timeval tv;
2455-
uint64 current_bucket_sec;
2456-
bool update_bucket = false;
2455+
uint64 new_bucket_start;
2456+
uint64 new_bucket_id;
2457+
uint64 prev_bucket_id;
24572458

24582459
gettimeofday(&tv, NULL);
2459-
current_bucket_sec = pg_atomic_read_u64(&pgsm->prev_bucket_sec);
2460+
2461+
new_bucket_start = (tv.tv_sec / pgsm_bucket_time) * (uint64) pgsm_bucket_time;
24602462

24612463
/*
24622464
* If current bucket expired we loop attempting to update prev_bucket_sec.
24632465
*
2464-
* pg_atomic_compare_exchange_u64 may fail in two possible ways: 1.
2465-
* Another thread/process updated the variable before us. 2. A spurious
2466-
* failure / hardware event.
2467-
*
2468-
* In both failure cases we read prev_bucket_sec from memory again, if it
2469-
* was a spurious failure then the value of prev_bucket_sec must be the
2470-
* same as before, which will cause the while loop to execute again.
2466+
* If another thread updated prev_bucket_sec, then use the new bucket
2467+
* created by that thread.
24712468
*
2472-
* If another thread updated prev_bucket_sec, then its current value will
2473-
* definitely make the while condition to fail, we can stop the loop as
2474-
* another thread has already updated prev_bucket_sec.
2469+
* XXX: This code looks potentially racy, especially if we skip buckets.
24752470
*/
2476-
while ((tv.tv_sec - (uint) current_bucket_sec) >= ((uint) pgsm_bucket_time))
2477-
{
2478-
if (pg_atomic_compare_exchange_u64(&pgsm->prev_bucket_sec, &current_bucket_sec, (uint64) tv.tv_sec))
2479-
{
2480-
update_bucket = true;
2481-
break;
2482-
}
2483-
2484-
current_bucket_sec = pg_atomic_read_u64(&pgsm->prev_bucket_sec);
2485-
}
2486-
2487-
if (update_bucket)
2471+
while (1)
24882472
{
2489-
uint64 new_bucket_id;
2490-
uint64 prev_bucket_id;
2473+
uint64 current_bucket_sec = pg_atomic_read_u64(&pgsm->prev_bucket_sec);
24912474

2492-
new_bucket_id = (tv.tv_sec / pgsm_bucket_time) % pgsm_max_buckets;
2475+
if (current_bucket_sec + (uint64) pgsm_bucket_time > (uint64) tv.tv_sec)
2476+
return pg_atomic_read_u64(&pgsm->current_wbucket);
24932477

2494-
/* Update bucket id and retrieve the previous one. */
2495-
prev_bucket_id = pg_atomic_exchange_u64(&pgsm->current_wbucket, new_bucket_id);
2478+
if (pg_atomic_compare_exchange_u64(&pgsm->prev_bucket_sec, &current_bucket_sec, new_bucket_start))
2479+
break;
2480+
}
24962481

2497-
pgsm_lock_aquire(pgsm, LW_EXCLUSIVE);
2498-
hash_entry_dealloc(new_bucket_id, prev_bucket_id);
2482+
new_bucket_id = (new_bucket_start / pgsm_bucket_time) % pgsm_max_buckets;
24992483

2500-
pgsm_lock_release(pgsm);
2484+
/* Update bucket id and retrieve the previous one. */
2485+
prev_bucket_id = pg_atomic_exchange_u64(&pgsm->current_wbucket, new_bucket_id);
25012486

2502-
/* Align the value in prev_bucket_sec to the bucket start time */
2503-
tv.tv_sec = (tv.tv_sec) - (tv.tv_sec % pgsm_bucket_time);
2504-
2505-
pg_atomic_exchange_u64(&pgsm->prev_bucket_sec, (uint64) tv.tv_sec);
2487+
pgsm_lock_aquire(pgsm, LW_EXCLUSIVE);
2488+
hash_entry_dealloc(new_bucket_id, prev_bucket_id);
2489+
pgsm_lock_release(pgsm);
25062490

2507-
pgsm->bucket_start_time[new_bucket_id] = (TimestampTz) tv.tv_sec -
2508-
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
2509-
pgsm->bucket_start_time[new_bucket_id] = pgsm->bucket_start_time[new_bucket_id] * USECS_PER_SEC;
2510-
return new_bucket_id;
2511-
}
2491+
pgsm->bucket_start_time[new_bucket_id] = (TimestampTz) (new_bucket_start -
2492+
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY)) * USECS_PER_SEC;
25122493

2513-
return pg_atomic_read_u64(&pgsm->current_wbucket);
2494+
return new_bucket_id;
25142495
}
25152496

25162497
/*

0 commit comments

Comments
 (0)