Browse Source

plugins/libplugin-pay.c: Micro-optimization of plugin_is_finished.

This was checked with `gcc -S -O2` to see how an optimized build
would compile the function.
The original code completed calls into each child (and the `.s`
file showed that GCC 9.x was not smart enough to do early-out).

This modification explicitly does early-out, and avoids call-return
stack overhead for the common case where a payment is an ancestor
of a long line of single-child payments due to retrying.

Changelog-None: pointless micro-optimization
bump-pyln-proto
ZmnSCPxj jxPCSnmZ 5 years ago
committed by Christian Decker
parent
commit
05daa8e5f3
  1. 21
      plugins/libplugin-pay.c

21
plugins/libplugin-pay.c

@ -1379,13 +1379,26 @@ static void payment_finished(struct payment *p);
* child-spawning state and all of its children are in a final state. */
static bool payment_is_finished(const struct payment *p)
{
top:
if (p->step == PAYMENT_STEP_FAILED || p->step == PAYMENT_STEP_SUCCESS || p->abort)
return true;
else if (p->step == PAYMENT_STEP_SPLIT || p->step == PAYMENT_STEP_RETRY) {
bool running_children = false;
for (size_t i = 0; i < tal_count(p->children); i++)
running_children |= !payment_is_finished(p->children[i]);
return !running_children;
size_t num_children = tal_count(p->children);
/* Retry case will almost always have just one child, so avoid
* the overhead of pushing and popping off the C stack and
* tail-recurse manually. */
if (num_children == 1) {
p = p->children[0];
goto top;
}
for (size_t i = 0; i < num_children; i++)
/* In other words: if any child is unfinished,
* we are unfinished. */
if (!payment_is_finished(p->children[i]))
return false;
return true;
} else {
return false;
}

Loading…
Cancel
Save