time-keeping: keep timestamp in multi, always update

Always use curlx_now() when calling Curl_pgrs_now(data). Tests with the
"manual" updates to now proved differ more then 100ms in parallel testing.

Add `curlx_nowp()` to set current time into a struct curltime.
Add `curlx_ptimediff_ms() and friends, passing pointers.

Update documentation.

Closes #19998
This commit is contained in:
Stefan Eissing 2025-12-18 13:55:07 +01:00 committed by Daniel Stenberg
parent 308c347c8b
commit b4be1f271e
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
61 changed files with 471 additions and 502 deletions

View file

@ -34,13 +34,13 @@
* zero : when i is equal to j
* positive when : when i is larger than j
*/
#define compare(i, j) curlx_timediff_us(i, j)
#define splay_compare(i, j) curlx_ptimediff_us(i, j)
/*
* Splay using the key i (which may or may not be in the tree.) The starting
* root is t.
*/
struct Curl_tree *Curl_splay(struct curltime i,
struct Curl_tree *Curl_splay(const struct curltime *pkey,
struct Curl_tree *t)
{
struct Curl_tree N, *l, *r, *y;
@ -51,11 +51,11 @@ struct Curl_tree *Curl_splay(struct curltime i,
l = r = &N;
for(;;) {
timediff_t comp = compare(i, t->key);
timediff_t comp = splay_compare(pkey, &t->key);
if(comp < 0) {
if(!t->smaller)
break;
if(compare(i, t->smaller->key) < 0) {
if(splay_compare(pkey, &t->smaller->key) < 0) {
y = t->smaller; /* rotate smaller */
t->smaller = y->larger;
y->larger = t;
@ -70,7 +70,7 @@ struct Curl_tree *Curl_splay(struct curltime i,
else if(comp > 0) {
if(!t->larger)
break;
if(compare(i, t->larger->key) > 0) {
if(splay_compare(pkey, &t->larger->key) > 0) {
y = t->larger; /* rotate larger */
t->larger = y->smaller;
y->smaller = t;
@ -103,16 +103,16 @@ static const struct curltime SPLAY_SUBNODE = {
*
* @unittest: 1309
*/
struct Curl_tree *Curl_splayinsert(struct curltime i,
struct Curl_tree *Curl_splayinsert(const struct curltime *pkey,
struct Curl_tree *t,
struct Curl_tree *node)
{
DEBUGASSERT(node);
if(t) {
t = Curl_splay(i, t);
t = Curl_splay(pkey, t);
DEBUGASSERT(t);
if(compare(i, t->key) == 0) {
if(splay_compare(pkey, &t->key) == 0) {
/* There already exists a node in the tree with the same key. Build a
doubly-linked circular list of nodes. We add the new 'node' struct to
the end of this list. */
@ -130,7 +130,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i,
if(!t) {
node->smaller = node->larger = NULL;
}
else if(compare(i, t->key) < 0) {
else if(splay_compare(pkey, &t->key) < 0) {
node->smaller = t->smaller;
node->larger = t;
t->smaller = NULL;
@ -140,7 +140,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i,
node->smaller = t;
t->larger = NULL;
}
node->key = i;
node->key = *pkey;
/* no identical nodes (yet), we are the only one in the list of nodes */
node->samen = node;
@ -151,7 +151,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i,
/* Finds and deletes the best-fit node from the tree. Return a pointer to the
resulting tree. best-fit means the smallest node if it is not larger than
the key */
struct Curl_tree *Curl_splaygetbest(struct curltime i,
struct Curl_tree *Curl_splaygetbest(const struct curltime *pkey,
struct Curl_tree *t,
struct Curl_tree **removed)
{
@ -164,9 +164,9 @@ struct Curl_tree *Curl_splaygetbest(struct curltime i,
}
/* find smallest */
t = Curl_splay(tv_zero, t);
t = Curl_splay(&tv_zero, t);
DEBUGASSERT(t);
if(compare(i, t->key) < 0) {
if(splay_compare(pkey, &t->key) < 0) {
/* even the smallest is too big */
*removed = NULL;
return t;
@ -218,7 +218,7 @@ int Curl_splayremove(struct Curl_tree *t,
DEBUGASSERT(removenode);
if(compare(SPLAY_SUBNODE, removenode->key) == 0) {
if(splay_compare(&SPLAY_SUBNODE, &removenode->key) == 0) {
/* It is a subnode within a 'same' linked list and thus we can unlink it
easily. */
DEBUGASSERT(removenode->samen != removenode);
@ -236,7 +236,7 @@ int Curl_splayremove(struct Curl_tree *t,
return 0;
}
t = Curl_splay(removenode->key, t);
t = Curl_splay(&removenode->key, t);
DEBUGASSERT(t);
/* First make sure that we got the same root node as the one we want
@ -268,7 +268,7 @@ int Curl_splayremove(struct Curl_tree *t,
if(!t->smaller)
x = t->larger;
else {
x = Curl_splay(removenode->key, t->smaller);
x = Curl_splay(&removenode->key, t->smaller);
DEBUGASSERT(x);
x->larger = t->larger;
}