From c6ca1a02aaffc6fbb6dbd98bcd33bfe3cf835892 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 13 May 2007 19:43:47 +0200 Subject: [PATCH] [MAJOR] migrated task, tree64 and session to pool2 task and tree64 are already very close in size and are merged together. Overall performance gained slightly by this simple change. --- include/import/tree.h | 37 +++++++++++++++++++------------------ include/proto/session.h | 7 ++++++- include/proto/task.h | 6 +++++- include/types/session.h | 6 +----- include/types/task.h | 3 --- src/appsession.c | 2 +- src/cfgparse.c | 4 ++-- src/client.c | 37 +++++++++++++++++++------------------ src/haproxy.c | 10 ++++++++-- src/session.c | 14 +++++++++++--- src/task.c | 14 +++++++++++--- 11 files changed, 83 insertions(+), 57 deletions(-) diff --git a/include/import/tree.h b/include/import/tree.h index 7c375e7ab3..11ca6e00f2 100644 --- a/include/import/tree.h +++ b/include/import/tree.h @@ -2,6 +2,8 @@ * tree.h : tree manipulation macros and structures. * (C) 2002 - Willy Tarreau - willy@ant-computing.com * + * 2007/05/13: adapted to mempools v2. + * */ #ifndef __TREE_H__ @@ -51,8 +53,7 @@ struct tree64 { struct tree64 *up; /* parent node. NULL = root */ }; -#define sizeof_tree64 (sizeof (struct tree64)) -extern void **pool_tree64; +extern struct pool_head *pool2_tree64; #define ULTREE_HEAD(l) struct ultree (l) = { .left=NULL, .right=NULL, .up=NULL, .low=0, .level=LONGBITS, .data=NULL } #define ULTREE_INIT(l) { (l)->data = (l)->left = (l)->right = NULL; } @@ -96,7 +97,7 @@ inline static struct ulltree *__ulltree_insert(struct ulltree *root, unsigned lo if (next == NULL) { /* we'll have to insert our node here */ - *branch = new = (struct ulltree *)pool_alloc(tree64); + *branch = new = (struct ulltree *)pool_alloc2(pool2_tree64); ULLTREE_INIT(new); new->up = root; new->value = x; @@ -111,7 +112,7 @@ inline static struct ulltree *__ulltree_insert(struct ulltree *root, unsigned lo /* ok, now we know that we must insert between both. */ /* the new interconnect node */ - *branch = node = (struct ulltree *)pool_alloc(tree64); /* was */ + *branch = node = (struct ulltree *)pool_alloc2(pool2_tree64); /* was */ ULLTREE_INIT(node); node->up = root; next->up = node; @@ -139,7 +140,7 @@ inline static struct ulltree *__ulltree_insert(struct ulltree *root, unsigned lo /* the new leaf now */ node->level = m; /* set the level to the lowest common bit */ - new = (struct ulltree *)pool_alloc(tree64); + new = (struct ulltree *)pool_alloc2(pool2_tree64); ULLTREE_INIT(new); new->value = x; new->level = ffs; @@ -186,7 +187,7 @@ inline static struct ultree *__ultree_insert(struct ultree *root, unsigned long if (next == NULL) { /* we'll have to insert our node here */ - *branch = new = (struct ultree *)pool_alloc(tree64); + *branch = new = (struct ultree *)pool_alloc2(pool2_tree64); ULTREE_INIT(new); new->up = root; new->low = x; @@ -200,7 +201,7 @@ inline static struct ultree *__ultree_insert(struct ultree *root, unsigned long /* ok, now we know that we must insert between both. */ /* the new interconnect node */ - *branch = node = (struct ultree *)pool_alloc(tree64); /* was */ + *branch = node = (struct ultree *)pool_alloc2(pool2_tree64); /* was */ ULTREE_INIT(node); node->up = root; next->up = node; @@ -228,7 +229,7 @@ inline static struct ultree *__ultree_insert(struct ultree *root, unsigned long /* the new leaf now */ node->level = m; /* set the level to the lowest common bit */ - new = (struct ultree *)pool_alloc(tree64); + new = (struct ultree *)pool_alloc2(pool2_tree64); ULTREE_INIT(new); new->low = x; new->level = ffs; @@ -279,7 +280,7 @@ inline static struct ultree *__ul2tree_insert(struct ultree *root, unsigned long if (next == NULL) { /* we'll have to insert our node here */ - *branch = new =(struct ultree *)pool_alloc(tree64); + *branch = new =(struct ultree *)pool_alloc2(pool2_tree64); UL2TREE_INIT(new); new->up = root; new->high = h; @@ -308,7 +309,7 @@ inline static struct ultree *__ul2tree_insert(struct ultree *root, unsigned long /* ok, now we know that we must insert between both. */ /* the new interconnect node */ - *branch = node = (struct ultree *)pool_alloc(tree64); /* was */ + *branch = node = (struct ultree *)pool_alloc2(pool2_tree64); /* was */ UL2TREE_INIT(node); node->up = root; next->up = node; @@ -352,7 +353,7 @@ inline static struct ultree *__ul2tree_insert(struct ultree *root, unsigned long /* the new leaf now */ node->level = m; /* set the level to the lowest common bit */ - new = (struct ultree *)pool_alloc(tree64); + new = (struct ultree *)pool_alloc2(pool2_tree64); UL2TREE_INIT(new); new->high = h; new->low = l; @@ -456,7 +457,7 @@ __right: \ goto __end; /* nothing left, don't delete the root node */ \ else { \ typeof (__root) __old; \ - pool_free(tree64, __ptr); \ + pool_free2(pool2_tree64, __ptr); \ __old = __ptr; \ __ptr = __stack[__slen]; \ if (__ptr->left == __old) { \ @@ -506,7 +507,7 @@ __right: \ goto __end; /* nothing left, don't delete the root node */ \ else { \ typeof (__root) __old; \ - pool_free(__type, __ptr); \ + pool_free2(pool##__type, __ptr); \ __old = __ptr; \ __ptr = __stack[__slen]; \ if (__ptr->left == __old) { \ @@ -561,7 +562,7 @@ __right: \ goto __end; /* nothing left, don't delete the root node */ \ else { \ typeof (__root) __old; \ - pool_free(tree64, __ptr); \ + pool_free2(pool2_tree64, __ptr); \ __old = __ptr; \ __ptr = __stack[__slen]; \ if (__ptr->left == __old) { \ @@ -617,7 +618,7 @@ __right: \ goto __end; /* nothing left, don't delete the root node */ \ else { \ typeof (__root) __old; \ - pool_free(tree64, __ptr); \ + pool_free2(pool2_tree64, __ptr); \ __old = __ptr; \ __ptr = __stack[__slen]; \ if (__ptr->left == __old) { \ @@ -671,7 +672,7 @@ inline static void *__tree_delete_only_one(void *firstnode) { */ down = node; node = node->up; - pool_free(tree64, down); + pool_free2(pool2_tree64, down); if (node->data || node->up == NULL) return node; /* now we're sure we were sharing this empty node with another branch, let's find it */ @@ -684,7 +685,7 @@ inline static void *__tree_delete_only_one(void *firstnode) { down->up = node->up; } /* free the last node */ - pool_free(tree64, node); + pool_free2(pool2_tree64, node); return down->up; } @@ -716,7 +717,7 @@ inline static void *__tree_delete(void *firstnode) { uplink = &up->right; *uplink = down; /* we relink the lower branch above us or simply cut it */ - pool_free(tree64, node); + pool_free2(pool2_tree64, node); node = up; if (down) down->up = node; diff --git a/include/proto/session.h b/include/proto/session.h index e3e5234097..a18669e1d5 100644 --- a/include/proto/session.h +++ b/include/proto/session.h @@ -2,7 +2,7 @@ include/proto/session.h This file defines everything related to sessions. - Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu + Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -23,10 +23,15 @@ #define _PROTO_SESSION_H #include +#include #include +extern struct pool_head *pool2_session; + void session_free(struct session *s); +/* perform minimal intializations, report 0 in case of error, 1 if OK. */ +int init_session(); #endif /* _PROTO_SESSION_H */ diff --git a/include/proto/task.h b/include/proto/task.h index c594d525ed..6bee1b2f19 100644 --- a/include/proto/task.h +++ b/include/proto/task.h @@ -33,6 +33,10 @@ #include extern void *run_queue; +extern struct pool_head *pool2_task; + +/* perform minimal intializations, report 0 in case of error, 1 if OK. */ +int init_task(); /* needed later */ void *tree_delete(void *node); @@ -97,7 +101,7 @@ static inline struct task *task_delete(struct task *t) */ static inline void task_free(struct task *t) { - pool_free(task, t); + pool_free2(pool2_task, t); } /* inserts into its assigned wait queue, where it may already be. In this case, it diff --git a/include/types/session.h b/include/types/session.h index 7ef138f105..819acfd74a 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -2,7 +2,7 @@ include/types/session.h This file defines everything related to sessions. - Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu + Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -123,10 +123,6 @@ struct session { }; -#define sizeof_session sizeof(struct session) -extern void **pool_session; - - #endif /* _TYPES_SESSION_H */ /* diff --git a/include/types/task.h b/include/types/task.h index 42699dbfff..e0bbd6dac8 100644 --- a/include/types/task.h +++ b/include/types/task.h @@ -42,9 +42,6 @@ struct task { void *context; /* the task's context */ }; -#define sizeof_task sizeof(struct task) -extern void **pool_task; - #endif /* _TYPES_TASK_H */ /* diff --git a/src/appsession.c b/src/appsession.c index 72b7e403fa..bf26510e40 100644 --- a/src/appsession.c +++ b/src/appsession.c @@ -111,7 +111,7 @@ int appsession_task_init(void) static int initialized = 0; struct task *t; if (!initialized) { - if ((t = pool_alloc(task)) == NULL) + if ((t = pool_alloc2(pool2_task)) == NULL) return -1; t->wq = NULL; t->qlist.p = NULL; diff --git a/src/cfgparse.c b/src/cfgparse.c index 1edaa8fc0b..6dd7ab6173 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2488,7 +2488,7 @@ int readcfgfile(const char *file) if (newsrv->maxconn > 0) { struct task *t; - if ((t = pool_alloc(task)) == NULL) { + if ((t = pool_alloc2(pool2_task)) == NULL) { Alert("parsing [%s:%d] : out of memory.\n", file, linenum); return -1; } @@ -2535,7 +2535,7 @@ int readcfgfile(const char *file) while (newsrv != NULL) { /* should this server be checked ? */ if (newsrv->state & SRV_CHECKED) { - if ((t = pool_alloc(task)) == NULL) { + if ((t = pool_alloc2(pool2_task)) == NULL) { Alert("parsing [%s:%d] : out of memory.\n", file, linenum); return -1; } diff --git a/src/client.c b/src/client.c index 52b281bded..6afb206365 100644 --- a/src/client.c +++ b/src/client.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -110,7 +111,7 @@ int event_accept(int fd) { } } - if ((s = pool_alloc(session)) == NULL) { /* disable this proxy for a while */ + if ((s = pool_alloc2(pool2_session)) == NULL) { /* disable this proxy for a while */ Alert("out of memory in event_accept().\n"); EV_FD_CLR(fd, DIR_RD); p->state = PR_STIDLE; @@ -127,18 +128,18 @@ int event_accept(int fd) { (((struct sockaddr_in *)&addr)->sin_addr.s_addr & p->mon_mask.s_addr) == p->mon_net.s_addr) { if (p->mode == PR_MODE_TCP) { close(cfd); - pool_free(session, s); + pool_free2(pool2_session, s); continue; } s->flags |= SN_MONITOR; } - if ((t = pool_alloc(task)) == NULL) { /* disable this proxy for a while */ + if ((t = pool_alloc2(pool2_task)) == NULL) { /* disable this proxy for a while */ Alert("out of memory in event_accept().\n"); EV_FD_CLR(fd, DIR_RD); p->state = PR_STIDLE; close(cfd); - pool_free(session, s); + pool_free2(pool2_session, s); return 0; } @@ -146,8 +147,8 @@ int event_accept(int fd) { if (cfd >= global.maxsock) { Alert("accept(): not enough free sockets. Raise -n argument. Giving up.\n"); close(cfd); - pool_free(task, t); - pool_free(session, s); + pool_free2(pool2_task, t); + pool_free2(pool2_session, s); return 0; } @@ -156,8 +157,8 @@ int event_accept(int fd) { (char *) &one, sizeof(one)) == -1)) { Alert("accept(): cannot set the socket in non blocking mode. Giving up\n"); close(cfd); - pool_free(task, t); - pool_free(session, s); + pool_free2(pool2_task, t); + pool_free2(pool2_session, s); return 0; } @@ -236,8 +237,8 @@ int event_accept(int fd) { pool_alloc_from(p->req_cap_pool, p->nb_req_cap*sizeof(char *))) == NULL) { /* no memory */ close(cfd); /* nothing can be done for this fd without memory */ - pool_free(task, t); - pool_free(session, s); + pool_free2(pool2_task, t); + pool_free2(pool2_session, s); return 0; } memset(txn->req.cap, 0, p->nb_req_cap*sizeof(char *)); @@ -251,8 +252,8 @@ int event_accept(int fd) { if (txn->req.cap != NULL) pool_free_to(p->req_cap_pool, txn->req.cap); close(cfd); /* nothing can be done for this fd without memory */ - pool_free(task, t); - pool_free(session, s); + pool_free2(pool2_task, t); + pool_free2(pool2_session, s); return 0; } memset(txn->rsp.cap, 0, p->nb_rsp_cap*sizeof(char *)); @@ -267,8 +268,8 @@ int event_accept(int fd) { if (txn->req.cap != NULL) pool_free_to(p->req_cap_pool, txn->req.cap); close(cfd); /* nothing can be done for this fd without memory */ - pool_free(task, t); - pool_free(session, s); + pool_free2(pool2_task, t); + pool_free2(pool2_session, s); return 0; } hdr_idx_init(&txn->hdr_idx); @@ -354,8 +355,8 @@ int event_accept(int fd) { if (txn->req.cap != NULL) pool_free_to(p->req_cap_pool, txn->req.cap); close(cfd); /* nothing can be done for this fd without memory */ - pool_free(task, t); - pool_free(session, s); + pool_free2(pool2_task, t); + pool_free2(pool2_session, s); return 0; } @@ -377,8 +378,8 @@ int event_accept(int fd) { if (txn->req.cap != NULL) pool_free_to(p->req_cap_pool, txn->req.cap); close(cfd); /* nothing can be done for this fd without memory */ - pool_free(task, t); - pool_free(session, s); + pool_free2(pool2_task, t); + pool_free2(pool2_session, s); return 0; } diff --git a/src/haproxy.c b/src/haproxy.c index 0acf75fb5d..18bef85147 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -87,6 +87,7 @@ #include #include #include +#include #include #include @@ -292,6 +293,9 @@ void dump(int sig) ); } #endif + /* dump memory usage then free everything possible */ + dump_pools(); + pool_gc2(); } #ifdef DEBUG_MEMORY @@ -370,6 +374,8 @@ void init(int argc, char **argv) localtime((time_t *)&now.tv_sec); start_date = now; + init_task(); + init_session(); init_proto_http(); cfg_polling_mechanism = POLL_USE_SELECT; /* select() is always available */ @@ -654,10 +660,10 @@ void deinit(void) if (fdtab) free(fdtab); - pool_destroy(pool_session); + pool_destroy2(pool2_session); pool_destroy(pool_buffer); pool_destroy(pool_requri); - pool_destroy(pool_task); + pool_destroy2(pool2_task); pool_destroy(pool_capture); pool_destroy(pool_appsess); diff --git a/src/session.c b/src/session.c index 21d34801cc..63bede3ee5 100644 --- a/src/session.c +++ b/src/session.c @@ -1,7 +1,7 @@ /* * Server management functions. * - * Copyright 2000-2006 Willy Tarreau + * Copyright 2000-2007 Willy Tarreau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,7 +26,7 @@ #include -void **pool_session = NULL; +struct pool_head *pool2_session; /* * frees the context associated to a session. It must have been removed first. @@ -69,7 +69,15 @@ void session_free(struct session *s) if (txn->srv_cookie) pool_free(capture, txn->srv_cookie); - pool_free(session, s); + pool_free2(pool2_session, s); +} + + +/* perform minimal intializations, report 0 in case of error, 1 if OK. */ +int init_session() +{ + pool2_session = create_pool("session", sizeof(struct session), MEM_F_SHARED); + return pool2_session != NULL; } diff --git a/src/task.c b/src/task.c index 41c0b2a2b3..182de2508c 100644 --- a/src/task.c +++ b/src/task.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -23,15 +24,22 @@ #include #include - -void **pool_task= NULL; -void **pool_tree64 = NULL; static struct ultree *stack[LLONGBITS]; +struct pool_head *pool2_task, *pool2_tree64; + UL2TREE_HEAD(timer_wq); void *eternity_queue = NULL; void *run_queue = NULL; +/* perform minimal intializations, report 0 in case of error, 1 if OK. */ +int init_task() +{ + pool2_task = create_pool("task", sizeof(struct task), MEM_F_SHARED); + pool2_tree64 = create_pool("tree64", sizeof(struct tree64), MEM_F_SHARED); + return pool2_task && pool2_tree64; +} + struct ultree *ul2tree_insert(struct ultree *root, unsigned long h, unsigned long l) { return __ul2tree_insert(root, h, l); -- 2.39.5