mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-27 07:02:11 +00:00
[MEDIUM] slightly optimize the scheduler for non-expirable tasks.
The non-expirable tasks are now sent to a dedicated wait-queue so that they do not pollute the other ones anymore. This is a temporary dirty hack which will go away with the new O(log(n)) scheduler.
This commit is contained in:
parent
dfece23f7d
commit
5e698ef509
52
haproxy.c
52
haproxy.c
@ -733,9 +733,15 @@ void **pool_session = NULL,
|
||||
struct proxy *proxy = NULL; /* list of all existing proxies */
|
||||
struct fdtab *fdtab = NULL; /* array of all the file descriptors */
|
||||
struct task *rq = NULL; /* global run queue */
|
||||
struct task wait_queue = { /* global wait queue */
|
||||
prev:LIST_HEAD(wait_queue),
|
||||
next:LIST_HEAD(wait_queue)
|
||||
struct task wait_queue[2] = { /* global wait queue */
|
||||
{
|
||||
prev:LIST_HEAD(wait_queue[0]), /* expirable tasks */
|
||||
next:LIST_HEAD(wait_queue[0]),
|
||||
},
|
||||
{
|
||||
prev:LIST_HEAD(wait_queue[1]), /* non-expirable tasks */
|
||||
next:LIST_HEAD(wait_queue[1]),
|
||||
},
|
||||
};
|
||||
|
||||
static int totalconn = 0; /* total # of terminated sessions */
|
||||
@ -1695,7 +1701,31 @@ struct task *task_queue(struct task *task) {
|
||||
struct task *list = task->wq;
|
||||
struct task *start_from;
|
||||
|
||||
/* first, test if the task was already in a list */
|
||||
/* This is a very dirty hack to queue non-expirable tasks in another queue
|
||||
* in order to avoid pulluting the tail of the standard queue. This will go
|
||||
* away with the new O(log(n)) scheduler anyway.
|
||||
*/
|
||||
if (tv_iseternity(&task->expire)) {
|
||||
/* if the task was queued in the standard wait queue, we must dequeue it */
|
||||
if (task->prev) {
|
||||
if (task->wq == LIST_HEAD(wait_queue[1]))
|
||||
return task;
|
||||
else {
|
||||
task_delete(task);
|
||||
task->prev = NULL;
|
||||
}
|
||||
}
|
||||
list = task->wq = LIST_HEAD(wait_queue[1]);
|
||||
} else {
|
||||
/* if the task was queued in the eternity queue, we must dequeue it */
|
||||
if (task->prev && (task->wq == LIST_HEAD(wait_queue[1]))) {
|
||||
task_delete(task);
|
||||
task->prev = NULL;
|
||||
list = task->wq = LIST_HEAD(wait_queue[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* next, test if the task was already in a list */
|
||||
if (task->prev == NULL) {
|
||||
// start_from = list;
|
||||
start_from = list->prev;
|
||||
@ -3085,7 +3115,7 @@ int event_accept(int fd) {
|
||||
setsockopt(cfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
|
||||
|
||||
t->next = t->prev = t->rqnext = NULL; /* task not in run queue yet */
|
||||
t->wq = LIST_HEAD(wait_queue); /* but already has a wait queue assigned */
|
||||
t->wq = LIST_HEAD(wait_queue[0]); /* but already has a wait queue assigned */
|
||||
t->state = TASK_IDLE;
|
||||
t->process = process_session;
|
||||
t->context = s;
|
||||
@ -5973,8 +6003,8 @@ int process_runnable_tasks() {
|
||||
|
||||
/* look for expired tasks and add them to the run queue.
|
||||
*/
|
||||
tnext = ((struct task *)LIST_HEAD(wait_queue))->next;
|
||||
while ((t = tnext) != LIST_HEAD(wait_queue)) { /* we haven't looped ? */
|
||||
tnext = ((struct task *)LIST_HEAD(wait_queue[0]))->next;
|
||||
while ((t = tnext) != LIST_HEAD(wait_queue[0])) { /* we haven't looped ? */
|
||||
tnext = t->next;
|
||||
if (t->state & TASK_RUNNING)
|
||||
continue;
|
||||
@ -6735,8 +6765,8 @@ void dump(int sig) {
|
||||
struct task *t, *tnext;
|
||||
struct session *s;
|
||||
|
||||
tnext = ((struct task *)LIST_HEAD(wait_queue))->next;
|
||||
while ((t = tnext) != LIST_HEAD(wait_queue)) { /* we haven't looped ? */
|
||||
tnext = ((struct task *)LIST_HEAD(wait_queue[0]))->next;
|
||||
while ((t = tnext) != LIST_HEAD(wait_queue[0])) { /* we haven't looped ? */
|
||||
tnext = t->next;
|
||||
s = t->context;
|
||||
qfprintf(stderr,"[dump] wq: task %p, still %ld ms, "
|
||||
@ -8532,7 +8562,7 @@ int readcfgfile(char *file) {
|
||||
}
|
||||
|
||||
t->next = t->prev = t->rqnext = NULL; /* task not in run queue yet */
|
||||
t->wq = LIST_HEAD(wait_queue); /* but already has a wait queue assigned */
|
||||
t->wq = LIST_HEAD(wait_queue[0]); /* but already has a wait queue assigned */
|
||||
t->state = TASK_IDLE;
|
||||
t->process = process_chk;
|
||||
t->context = newsrv;
|
||||
@ -9351,7 +9381,7 @@ static int appsession_task_init(void)
|
||||
if ((t = pool_alloc(task)) == NULL)
|
||||
return -1;
|
||||
t->next = t->prev = t->rqnext = NULL;
|
||||
t->wq = LIST_HEAD(wait_queue);
|
||||
t->wq = LIST_HEAD(wait_queue[0]);
|
||||
t->state = TASK_IDLE;
|
||||
t->context = NULL;
|
||||
tv_delayfrom(&t->expire, &now, TBLCHKINT);
|
||||
|
Loading…
Reference in New Issue
Block a user