From 9bd816ea4da2ccafe11f1d54f12c9326c9a61a48 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 2 Dec 2014 20:00:28 +0100 Subject: OPTIM: session: inline the fast code of session_offer_buffers() The part which checks if buffers are available and if tasks are waiting is better inlined as it's cheap and avoids a function call. Performance increases by about 2% both on a memory-constrained system and a normal one. --- include/proto/session.h | 27 ++++++++++++++++++++++++++- src/session.c | 22 +++++----------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/include/proto/session.h b/include/proto/session.h index 13544c1..eccacdf 100644 --- a/include/proto/session.h +++ b/include/proto/session.h @@ -25,8 +25,10 @@ #include #include #include +#include #include #include +#include extern struct pool_head *pool2_session; extern struct list sessions; @@ -54,7 +56,8 @@ int parse_track_counters(char **args, int *arg, /* Update the session's backend and server time stats */ void session_update_time_stats(struct session *s); -void session_offer_buffers(); +void __session_offer_buffers(int rqlimit); +static inline void session_offer_buffers(); int session_alloc_buffers(struct session *s); void session_release_buffers(struct session *s); int session_alloc_one_buffer(struct session *s, struct buffer **buf); @@ -272,6 +275,28 @@ static void inline session_init_srv_conn(struct session *sess) LIST_INIT(&sess->by_srv); } +static inline void session_offer_buffers() +{ + int avail; + + if (LIST_ISEMPTY(&buffer_wq)) + return; + + /* all sessions will need 1 or 2 buffers, so we can stop + * waking up sessions once we have enough of them to eat + * all the buffers. Note that we don't really know if they + * are sessions or just other tasks, but that's a rough + * estimate. Similarly, for each cached event we'll need + * 1 or 2 buffers, so we set this limit as well. + */ + avail = pool2_buffer->allocated - pool2_buffer->used; + avail /= 2; + avail -= fd_cache_num; + + if (avail > (int)run_queue) + __session_offer_buffers(avail); +} + #endif /* _PROTO_SESSION_H */ /* diff --git a/src/session.c b/src/session.c index adc2cbe..be824be 100644 --- a/src/session.c +++ b/src/session.c @@ -739,28 +739,16 @@ void session_release_buffers(struct session *s) session_offer_buffers(); } -/* run across the list of pending sessions waiting for a buffer and wake - * one up if buffers are available. +/* Runs across the list of pending sessions waiting for a buffer and wakes one + * up if buffers are available. Will stop when the run queue reaches . + * Should not be called directly, use session_offer_buffers() instead. */ -void session_offer_buffers() +void __session_offer_buffers(int rqlimit) { struct session *sess, *bak; - int avail; - - /* all sessions will need 1 or 2 buffers, so we can stop - * waking up sessions once we have enough of them to eat - * all the buffers. Note that we don't really know if they - * are sessions or just other tasks, but that's a rough - * estimate. Similarly, for each cached event we'll need - * 1 or 2 buffers, so we set this limit as well. - */ - - avail = pool2_buffer->allocated - pool2_buffer->used; - avail /= 2; - avail -= fd_cache_num; list_for_each_entry_safe(sess, bak, &buffer_wq, buffer_wait) { - if (avail <= (int)(run_queue)) + if (rqlimit <= run_queue) break; if (sess->task->state & TASK_RUNNING) -- 1.7.12.1