@@ -41,43 +41,71 @@ log_pipe_forward_msg(LogPipe *self, LogMessage *msg, const LogPathOptions *path_
41
41
}
42
42
}
43
43
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 )
46
50
{
47
51
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 ))
60
53
filterx_eval_sync_message (path_options -> filterx_context , & msg , path_options );
61
54
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 )))
63
56
{
64
57
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 )
66
59
{
67
60
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 ));
69
62
}
70
- if (s -> flags & PIF_JUNCTION_END )
63
+ if (self -> flags & PIF_JUNCTION_END )
71
64
{
72
65
log_path_options_pop_junction (& local_path_options );
73
66
}
74
- if (s -> flags & PIF_CONDITIONAL_MIDPOINT )
67
+ if (self -> flags & PIF_CONDITIONAL_MIDPOINT )
75
68
{
76
69
log_path_options_pop_conditional (& local_path_options );
77
70
}
78
71
}
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;
79
80
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 );
81
109
}
82
110
83
111
0 commit comments