Skip to content

Commit 1a76519

Browse files
authored
Merge pull request #426 from bazsi/log-pipe-queue-enable-tail-call-optimization
logpipe: allow log_pipe_queue() to be tail-call-optimized
2 parents 010230d + 1c809d8 commit 1a76519

File tree

1 file changed

+48
-20
lines changed

1 file changed

+48
-20
lines changed

lib/logpipe.c

+48-20
Original file line numberDiff line numberDiff line change
@@ -41,43 +41,71 @@ log_pipe_forward_msg(LogPipe *self, LogMessage *msg, const LogPathOptions *path_
4141
}
4242
}
4343

44-
void
45-
log_pipe_queue(LogPipe *s, LogMessage *msg, const LogPathOptions *path_options)
44+
/*
45+
* LogPipeQueue slow path that can potentially change "msg" and
46+
* "path_options", causing tail call optimization to be disabled.
47+
*/
48+
static void
49+
log_pipe_queue_slow_path(LogPipe *self, LogMessage *msg, const LogPathOptions *path_options)
4650
{
4751
LogPathOptions local_path_options;
48-
g_assert((s->flags & PIF_INITIALIZED) != 0);
49-
50-
if (G_UNLIKELY((s->flags & PIF_CONFIG_RELATED) != 0 && pipe_single_step_hook))
51-
{
52-
if (!pipe_single_step_hook(s, msg, path_options))
53-
{
54-
log_msg_drop(msg, path_options, AT_PROCESSED);
55-
return;
56-
}
57-
}
58-
59-
if ((s->flags & PIF_SYNC_FILTERX_TO_MSG))
52+
if ((self->flags & PIF_SYNC_FILTERX_TO_MSG))
6053
filterx_eval_sync_message(path_options->filterx_context, &msg, path_options);
6154

62-
if (G_UNLIKELY(s->flags & (PIF_HARD_FLOW_CONTROL | PIF_JUNCTION_END | PIF_CONDITIONAL_MIDPOINT)))
55+
if (G_UNLIKELY(self->flags & (PIF_HARD_FLOW_CONTROL | PIF_JUNCTION_END | PIF_CONDITIONAL_MIDPOINT)))
6356
{
6457
path_options = log_path_options_chain(&local_path_options, path_options);
65-
if (s->flags & PIF_HARD_FLOW_CONTROL)
58+
if (self->flags & PIF_HARD_FLOW_CONTROL)
6659
{
6760
local_path_options.flow_control_requested = 1;
68-
msg_trace("Requesting flow control", log_pipe_location_tag(s));
61+
msg_trace("Requesting flow control", log_pipe_location_tag(self));
6962
}
70-
if (s->flags & PIF_JUNCTION_END)
63+
if (self->flags & PIF_JUNCTION_END)
7164
{
7265
log_path_options_pop_junction(&local_path_options);
7366
}
74-
if (s->flags & PIF_CONDITIONAL_MIDPOINT)
67+
if (self->flags & PIF_CONDITIONAL_MIDPOINT)
7568
{
7669
log_path_options_pop_conditional(&local_path_options);
7770
}
7871
}
72+
self->queue(self, msg, path_options);
73+
}
74+
75+
static inline gboolean
76+
_is_fastpath(LogPipe *self)
77+
{
78+
if (self->flags & PIF_SYNC_FILTERX_TO_MSG)
79+
return FALSE;
7980

80-
s->queue(s, msg, path_options);
81+
if (self->flags & (PIF_HARD_FLOW_CONTROL | PIF_JUNCTION_END | PIF_CONDITIONAL_MIDPOINT))
82+
return FALSE;
83+
84+
return TRUE;
85+
}
86+
87+
void
88+
log_pipe_queue(LogPipe *self, LogMessage *msg, const LogPathOptions *path_options)
89+
{
90+
g_assert((self->flags & PIF_INITIALIZED) != 0);
91+
92+
if (G_UNLIKELY((self->flags & PIF_CONFIG_RELATED) != 0 && pipe_single_step_hook))
93+
{
94+
if (!pipe_single_step_hook(self, msg, path_options))
95+
{
96+
log_msg_drop(msg, path_options, AT_PROCESSED);
97+
return;
98+
}
99+
}
100+
101+
/* on the fastpath we can use tail call optimization, so we won't have a
102+
* series of log_pipe_queue() calls on the stack, it improves perf traces
103+
* if nothing else, but I believe it also helps locality by using a lot
104+
* less stack space */
105+
if (_is_fastpath(self))
106+
self->queue(self, msg, path_options);
107+
else
108+
log_pipe_queue_slow_path(self, msg, path_options);
81109
}
82110

83111

0 commit comments

Comments
 (0)