提交 c783f297 编写于 作者: D Dmitry Kozlov

memory usage optimization

上级 56762d95
......@@ -12,7 +12,7 @@ IF (NOT HAVE_SSL)
MESSAGE(FATAL_ERROR "openssl headers not found")
ENDIF (NOT HAVE_SSL)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fno-strict-aliasing -D_GNU_SOURCE -DPTHREAD_SPINLOCK -DMEMDEBUG -fPIC")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fno-strict-aliasing -D_GNU_SOURCE -DPTHREAD_SPINLOCK -fPIC")
IF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git)
EXECUTE_PROCESS(
......@@ -40,9 +40,12 @@ IF (RADIUS)
ADD_SUBDIRECTORY(radius)
ENDIF (RADIUS)
IF (VALGRIND)
ADD_DEFINITIONS(-DVALGRIND)
ENDIF (VALGRIND)
IF (MEMDEBUG)
ADD_DEFINITIONS(-DMEMDEBUG)
IF (VALGRIND)
ADD_DEFINITIONS(-DVALGRIND)
ENDIF (VALGRIND)
ENDIF (MEMDEBUG)
ADD_SUBDIRECTORY(triton)
ADD_SUBDIRECTORY(ctrl)
......
......@@ -384,9 +384,9 @@ static struct ppp_auth_handler_t chap=
static void chap_recv(struct ppp_handler_t *h)
{
struct chap_auth_data_t *d = container_of(h, typeof(*d), h);
struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->chan_buf;
struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf;
if (d->ppp->chan_buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->chan_buf_size - 2) {
if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) {
log_ppp_warn("chap-md5: short packet received\n");
return;
}
......
......@@ -469,9 +469,9 @@ static struct ppp_auth_handler_t chap = {
static void chap_recv(struct ppp_handler_t *h)
{
struct chap_auth_data_t *d = container_of(h, typeof(*d), h);
struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->chan_buf;
struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf;
if (d->ppp->chan_buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->chan_buf_size - 2) {
if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) {
log_ppp_warn("mschap-v1: short packet received\n");
return;
}
......
......@@ -609,9 +609,9 @@ static struct ppp_auth_handler_t chap=
static void chap_recv(struct ppp_handler_t *h)
{
struct chap_auth_data_t *d = container_of(h, typeof(*d), h);
struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->chan_buf;
struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf;
if (d->ppp->chan_buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->chan_buf_size - 2) {
if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) {
log_ppp_warn("mschap-v2: short packet received\n");
return;
}
......
......@@ -242,9 +242,9 @@ static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr)
static void pap_recv(struct ppp_handler_t *h)
{
struct pap_auth_data_t *d = container_of(h, typeof(*d), h);
struct pap_hdr_t *hdr = (struct pap_hdr_t *)d->ppp->chan_buf;
struct pap_hdr_t *hdr = (struct pap_hdr_t *)d->ppp->buf;
if (d->ppp->chan_buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->chan_buf_size - 2) {
if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) {
log_ppp_warn("PAP: short packet received\n");
return;
}
......
......@@ -3,6 +3,7 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <malloc.h>
#include <arpa/inet.h>
#include "triton.h"
......@@ -21,6 +22,9 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
FILE *f;
unsigned long vmsize = 0, vmrss = 0;
unsigned long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
#ifdef MEMDEBUG
struct mallinfo mi = mallinfo();
#endif
sprintf(statm_fname, "/proc/%i/statm", getpid());
f = fopen(statm_fname, "r");
......@@ -38,7 +42,16 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
cli_sendv(client, "uptime: %i.%02i:%02i:%02i\r\n", day, hour, dt / 60, dt % 60);
cli_sendv(client, "cpu: %i%%\r\n", triton_stat.cpu);
#ifdef MEMDEBUG
cli_send(client, "memory:\r\n");
cli_sendv(client, " rss/virt: %lu/%lu kB\r\n", vmrss * page_size_kb, vmsize * page_size_kb);
cli_sendv(client, " arena: %lu kB\r\n", mi.arena / 1024);
cli_sendv(client, " mmaped: %lu kB\r\n", mi.hblkhd / 1024);
cli_sendv(client, " uordblks: %lu kB\r\n", mi.uordblks / 1024);
cli_sendv(client, " fordblks: %lu kB\r\n", mi.fordblks / 1024);
#else
cli_sendv(client, "mem(rss/virt): %lu/%lu kB\r\n", vmrss * page_size_kb, vmsize * page_size_kb);
#endif
cli_send(client, "core:\r\n");
cli_sendv(client, " mempool_allocated: %u\r\n", triton_stat.mempool_allocated);
cli_sendv(client, " mempool_available: %u\r\n", triton_stat.mempool_available);
......
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
......
......@@ -30,7 +30,7 @@
struct mem_t
{
struct list_head entry;
char fname[PATH_MAX];
const char *fname;
int line;
size_t size;
uint64_t magic2;
......@@ -48,7 +48,7 @@ struct mem_t *_md_malloc(size_t size, const char *fname, int line)
if (size > 4096)
line = 0;
strcpy(mem->fname, fname);
mem->fname = fname;
mem->line = line;
mem->size = size;
mem->magic1 = MAGIC1;
......
......@@ -22,6 +22,8 @@ void md_check(void *ptr);
#define _malloc(size) malloc(size)
#define _realloc(ptr, size) realloc(ptr, size)
#define _free(ptr) free(ptr)
#define _strdup(str) strdup(str)
#define _strndup(str, size) strndup(str, size)
#endif
#endif
......
......@@ -20,6 +20,7 @@
#include "ppp_fsm.h"
#include "log.h"
#include "spinlock.h"
#include "mempool.h"
#include "memdebug.h"
......@@ -29,17 +30,19 @@ static int conf_sid_ucase;
pthread_rwlock_t __export ppp_lock = PTHREAD_RWLOCK_INITIALIZER;
__export LIST_HEAD(ppp_list);
static LIST_HEAD(layers);
int __export sock_fd;
int __export ppp_shutdown;
static mempool_t buf_pool;
static LIST_HEAD(layers);
static unsigned long long seq;
#if __WORDSIZE == 32
static spinlock_t seq_lock;
#endif
struct ppp_stat_t ppp_stat;
struct layer_node_t
......@@ -64,16 +67,6 @@ void __export ppp_init(struct ppp_t *ppp)
INIT_LIST_HEAD(&ppp->pd_list);
}
static void _free_ppp(struct ppp_t *ppp)
{
if (ppp->chan_buf)
free(ppp->chan_buf);
if (ppp->unit_buf)
_free(ppp->unit_buf);
if (ppp->username)
_free(ppp->username);
}
static void generate_sessionid(struct ppp_t *ppp)
{
unsigned long long sid;
......@@ -151,8 +144,7 @@ int __export establish_ppp(struct ppp_t *ppp)
goto exit_close_unit;
}
ppp->chan_buf = _malloc(PPP_MRU);
ppp->unit_buf = _malloc(PPP_MRU);
ppp->buf = mempool_alloc(buf_pool);
ppp->chan_hnd.fd = ppp->chan_fd;
ppp->chan_hnd.read = ppp_chan_read;
......@@ -184,7 +176,8 @@ exit_close_unit:
exit_close_chan:
close(ppp->chan_fd);
_free_ppp(ppp);
if (ppp->buf)
mempool_free(ppp->buf);
return -1;
}
......@@ -218,9 +211,6 @@ static void destablish_ppp(struct ppp_t *ppp)
ppp->chan_fd = -1;
ppp->fd = -1;
_free(ppp->unit_buf);
_free(ppp->chan_buf);
_free_layers(ppp);
ppp->terminated = 1;
......@@ -230,6 +220,8 @@ static void destablish_ppp(struct ppp_t *ppp)
triton_event_fire(EV_PPP_FINISHED, ppp);
ppp->ctrl->finished(ppp);
mempool_free(ppp->buf);
if (ppp->username) {
_free(ppp->username);
ppp->username = NULL;
......@@ -281,8 +273,8 @@ static int ppp_chan_read(struct triton_md_handler_t *h)
while(1) {
cont:
ppp->chan_buf_size = read(h->fd, ppp->chan_buf, PPP_MRU);
if (ppp->chan_buf_size < 0) {
ppp->buf_size = read(h->fd, ppp->buf, PPP_MRU);
if (ppp->buf_size < 0) {
if (errno == EAGAIN)
return 0;
log_ppp_error("ppp_chan_read: %s\n", strerror(errno));
......@@ -290,18 +282,18 @@ cont:
}
//printf("ppp_chan_read: ");
//print_buf(ppp->chan_buf,ppp->chan_buf_size);
if (ppp->chan_buf_size == 0) {
//print_buf(ppp->buf,ppp->buf_size);
if (ppp->buf_size == 0) {
ppp_terminate(ppp, 1, TERM_NAS_ERROR);
return 1;
}
if (ppp->chan_buf_size < 2) {
log_ppp_error("ppp_chan_read: short read %i\n", ppp->chan_buf_size);
if (ppp->buf_size < 2) {
log_ppp_error("ppp_chan_read: short read %i\n", ppp->buf_size);
continue;
}
proto = ntohs(*(uint16_t*)ppp->chan_buf);
proto = ntohs(*(uint16_t*)ppp->buf);
list_for_each_entry(ppp_h, &ppp->chan_handlers, entry) {
if (ppp_h->proto == proto) {
ppp_h->recv(ppp_h);
......@@ -326,29 +318,28 @@ static int ppp_unit_read(struct triton_md_handler_t *h)
while (1) {
cont:
ppp->unit_buf_size = read(h->fd, ppp->unit_buf, PPP_MRU);
if (ppp->unit_buf_size < 0) {
ppp->buf_size = read(h->fd, ppp->buf, PPP_MRU);
if (ppp->buf_size < 0) {
if (errno == EAGAIN)
return 0;
log_ppp_error("ppp_unit_read: %s\n",strerror(errno));
return 0;
}
md_check(ppp->unit_buf);
//printf("ppp_unit_read: ");
//print_buf(ppp->unit_buf,ppp->unit_buf_size);
//print_buf(ppp->buf,ppp->buf_size);
if (ppp->unit_buf_size == 0) {
if (ppp->buf_size == 0) {
ppp_terminate(ppp, 1, TERM_NAS_ERROR);
return 1;
}
if (ppp->unit_buf_size < 2) {
log_ppp_error("ppp_unit_read: short read %i\n", ppp->unit_buf_size);
if (ppp->buf_size < 2) {
log_ppp_error("ppp_unit_read: short read %i\n", ppp->buf_size);
continue;
}
proto=ntohs(*(uint16_t*)ppp->unit_buf);
proto=ntohs(*(uint16_t*)ppp->buf);
list_for_each_entry(ppp_h, &ppp->unit_handlers, entry) {
if (ppp_h->proto == proto) {
ppp_h->recv(ppp_h);
......@@ -656,6 +647,8 @@ static void __init init(void)
char *opt;
FILE *f;
buf_pool = mempool_create(PPP_MRU);
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (sock_fd < 0) {
perror("socket");
......
......@@ -103,10 +103,8 @@ struct ppp_t
int terminated:1;
int terminate_cause;
void *chan_buf;
int chan_buf_size;
void *unit_buf;
int unit_buf_size;
void *buf;
int buf_size;
struct list_head chan_handlers;
struct list_head unit_handlers;
......
......@@ -271,7 +271,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm)
static void send_conf_ack(struct ppp_fsm_t *fsm)
{
struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm);
struct ccp_hdr_t *hdr = (struct ccp_hdr_t*)ccp->ppp->unit_buf;
struct ccp_hdr_t *hdr = (struct ccp_hdr_t*)ccp->ppp->buf;
hdr->code = CONFACK;
......@@ -619,12 +619,12 @@ static void ccp_recv(struct ppp_handler_t*h)
return;
}
if (ccp->ppp->unit_buf_size < PPP_HEADERLEN + 2) {
if (ccp->ppp->buf_size < PPP_HEADERLEN + 2) {
log_ppp_warn("CCP: short packet received\n");
return;
}
hdr = (struct ccp_hdr_t *)ccp->ppp->unit_buf;
hdr = (struct ccp_hdr_t *)ccp->ppp->buf;
if (ntohs(hdr->len) < PPP_HEADERLEN) {
log_ppp_warn("CCP: short packet received\n");
return;
......
......@@ -219,7 +219,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm)
static void send_conf_ack(struct ppp_fsm_t *fsm)
{
struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm);
struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->unit_buf;
struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->buf;
hdr->code = CONFACK;
......@@ -564,12 +564,12 @@ static void ipcp_recv(struct ppp_handler_t*h)
return;
}
if (ipcp->ppp->unit_buf_size < PPP_HEADERLEN + 2) {
if (ipcp->ppp->buf_size < PPP_HEADERLEN + 2) {
log_ppp_warn("IPCP: short packet received\n");
return;
}
hdr = (struct ipcp_hdr_t *)ipcp->ppp->unit_buf;
hdr = (struct ipcp_hdr_t *)ipcp->ppp->buf;
if (ntohs(hdr->len) < PPP_HEADERLEN) {
log_ppp_warn("IPCP: short packet received\n");
return;
......
......@@ -252,7 +252,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm)
static void send_conf_ack(struct ppp_fsm_t *fsm)
{
struct ppp_lcp_t *lcp = container_of(fsm, typeof(*lcp), fsm);
struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->chan_buf;
struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->buf;
hdr->code = CONFACK;
......@@ -265,7 +265,7 @@ static void send_conf_ack(struct ppp_fsm_t *fsm)
static void send_code_rej(struct ppp_fsm_t *fsm)
{
struct ppp_lcp_t *lcp = container_of(fsm, typeof(*lcp), fsm);
struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->chan_buf;
struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->buf;
hdr->code = CONFACK;
......@@ -586,7 +586,7 @@ static void lcp_recv_echo_repl(struct ppp_lcp_t *lcp, uint8_t *data, int size)
static void send_echo_reply(struct ppp_lcp_t *lcp)
{
struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->chan_buf;
struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->buf;
uint32_t magic = *(uint32_t *)(hdr + 1);
hdr->code = ECHOREP;
......@@ -706,12 +706,12 @@ static void lcp_recv(struct ppp_handler_t*h)
return;
}
if (lcp->ppp->chan_buf_size < PPP_HEADERLEN + 2) {
if (lcp->ppp->buf_size < PPP_HEADERLEN + 2) {
log_ppp_warn("LCP: short packet received\n");
return;
}
hdr = (struct lcp_hdr_t *)lcp->ppp->chan_buf;
hdr = (struct lcp_hdr_t *)lcp->ppp->buf;
if (ntohs(hdr->len) < PPP_HEADERLEN) {
log_ppp_warn("LCP: short packet received\n");
return;
......
......@@ -5,6 +5,8 @@
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/mman.h>
#include "log.h"
#include "mempool.h"
......@@ -48,17 +50,18 @@ int rad_packet_build(struct rad_packet_t *pack, uint8_t *RA)
struct rad_attr_t *attr;
uint8_t *ptr;
if (pack->buf)
ptr = _realloc(pack->buf, pack->len);
else
ptr = _malloc(pack->len);
if (!pack->buf) {
ptr = mmap(NULL, REQ_LENGTH_MAX, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (ptr == MAP_FAILED) {
log_emerg("radius:packet: out of memory\n");
return -1;
}
pack->buf = ptr;
} else
ptr = pack->buf;
if (!ptr) {
log_emerg("radius:packet: out of memory\n");
return -1;
}
pack->buf = ptr;
*ptr = pack->code; ptr++;
*ptr = pack->id; ptr++;
*(uint16_t*)ptr = htons(pack->len); ptr+= 2;
......@@ -113,11 +116,13 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
if (!pack)
return 0;
pack->buf = _malloc(REQ_LENGTH_MAX);
if (!pack->buf) {
ptr = mmap(NULL, REQ_LENGTH_MAX, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (ptr == MAP_FAILED) {
log_emerg("radius:packet: out of memory\n");
goto out_err;
}
pack->buf = ptr;
while (1) {
if (addr)
......@@ -141,8 +146,6 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
goto out_err;
}
ptr = (uint8_t *)pack->buf;
pack->code = *ptr; ptr++;
pack->id = *ptr; ptr++;
pack->len = ntohs(*(uint16_t*)ptr); ptr += 2;
......@@ -224,6 +227,9 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
n -= 2 + len;
}
munmap(pack->buf, REQ_LENGTH_MAX);
pack->buf = NULL;
*p = pack;
return 0;
......@@ -238,7 +244,7 @@ void rad_packet_free(struct rad_packet_t *pack)
struct rad_attr_t *attr;
if (pack->buf)
_free(pack->buf);
munmap(pack->buf, REQ_LENGTH_MAX);
while(!list_empty(&pack->attrs)) {
attr = list_entry(pack->attrs.next, typeof(*attr), entry);
......
......@@ -18,6 +18,7 @@
//#define MEMPOOL_DISABLE
#define MAGIC1 0x2233445566778899llu
#define PAGE_ORDER 5
struct _mempool_t
{
......@@ -50,6 +51,11 @@ struct _item_t
static LIST_HEAD(pools);
static spinlock_t pools_lock = SPINLOCK_INITIALIZER;
static spinlock_t mmap_lock = SPINLOCK_INITIALIZER;
static void *mmap_ptr;
static void *mmap_endptr;
static int mmap_grow(void);
mempool_t __export *mempool_create(int size)
{
......@@ -63,6 +69,7 @@ mempool_t __export *mempool_create(int size)
spinlock_init(&p->lock);
p->size = size;
p->magic = (uint64_t)random() * (uint64_t)random();
p->mmap = 1;
spin_lock(&pools_lock);
list_add_tail(&p->entry, &pools);
......@@ -92,41 +99,51 @@ void __export *mempool_alloc(mempool_t *pool)
it = list_entry(p->items.next, typeof(*it), entry);
list_del(&it->entry);
spin_unlock(&p->lock);
__sync_sub_and_fetch(&triton_stat.mempool_available, size);
it->magic1 = MAGIC1;
return it->ptr;
#ifdef VALGRIND
}
#endif
}
spin_unlock(&p->lock);
if (p->mmap)
it = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_32BIT, -1, 0);
else
if (p->mmap) {
spin_lock(&mmap_lock);
if (mmap_ptr + size >= mmap_endptr) {
if (mmap_grow())
return NULL;
}
it = (struct _item_t *)mmap_ptr;
mmap_ptr += size;
spin_unlock(&mmap_lock);
__sync_sub_and_fetch(&triton_stat.mempool_available, size);
} else {
it = _malloc(size);
__sync_add_and_fetch(&triton_stat.mempool_allocated, size);
}
if (!it) {
triton_log_error("mempool: out of memory\n");
return NULL;
}
it->owner = p;
it->magic1 = MAGIC1;
it->magic2 = p->magic;
*(uint64_t*)(it->data + p->size) = it->magic2;
__sync_add_and_fetch(&triton_stat.mempool_allocated, size);
it->magic1 = MAGIC1;
*(uint64_t*)(it->ptr + p->size) = it->magic2;
return it->ptr;
}
#endif
#else
void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line)
{
struct _mempool_t *p = (struct _mempool_t *)pool;
struct _item_t *it;
uint32_t size = sizeof(*it) + p->size + 8;
int i, n;
spin_lock(&p->lock);
if (!list_empty(&p->items)) {
......@@ -155,29 +172,17 @@ void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line)
spin_unlock(&p->lock);
if (p->mmap) {
n = (sysconf(_SC_PAGE_SIZE) - 1) / size + 1;
it = mmap(NULL, n * size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_32BIT, -1, 0);
__sync_add_and_fetch(&triton_stat.mempool_allocated, size * (n - 1));
__sync_add_and_fetch(&triton_stat.mempool_available, size * (n - 1));
spin_lock(&p->lock);
for (i = 0; i < n - 1; i++, it) {
it->owner = p;
it->magic2 = p->magic;
it->magic1 = MAGIC1;
*(uint64_t*)(it->ptr + p->size) = it->magic2;
list_add_tail(&it->entry,&p->items);
#ifdef VALGRIND
it->timestamp = 0;
VALGRIND_MAKE_MEM_NOACCESS(&it->owner, size - sizeof(it->entry) - sizeof(it->timestamp));
#endif
it = (struct _item_t *)((char *)it + size);
}
spin_unlock(&p->lock);
#ifdef VALGRIND
VALGRIND_MAKE_MEM_UNDEFINED(it, size);
#endif
} else
spin_lock(&mmap_lock);
if (mmap_ptr + size >= mmap_endptr)
mmap_grow();
it = (struct _item_t *)mmap_ptr;
mmap_ptr += size;
spin_unlock(&mmap_lock);
__sync_sub_and_fetch(&triton_stat.mempool_available, size);
} else {
it = md_malloc(size, fname, line);
__sync_add_and_fetch(&triton_stat.mempool_allocated, size);
}
if (!it) {
triton_log_error("mempool: out of memory\n");
......@@ -194,11 +199,9 @@ void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line)
list_add(&it->entry, &p->ditems);
spin_unlock(&p->lock);
__sync_add_and_fetch(&triton_stat.mempool_allocated, size);
return it->ptr;
}
#endif
void __export mempool_free(void *ptr)
{
......@@ -323,6 +326,35 @@ void sigclean(int num)
spin_unlock(&pools_lock);
}
static int mmap_grow(void)
{
int size = sysconf(_SC_PAGE_SIZE) * (1 << PAGE_ORDER);
void *ptr;
if (mmap_endptr) {
ptr = mmap(mmap_endptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (ptr == MAP_FAILED)
goto oom;
if (ptr != mmap_endptr)
mmap_ptr = ptr;
} else {
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (ptr == MAP_FAILED)
goto oom;
mmap_ptr = ptr;
}
mmap_endptr = ptr + size;
__sync_add_and_fetch(&triton_stat.mempool_allocated, size);
__sync_add_and_fetch(&triton_stat.mempool_available, size);
return 0;
oom:
triton_log_error("mempool: out of memory\n");
return -1;
}
static void __init init(void)
{
sigset_t set;
......@@ -334,5 +366,7 @@ static void __init init(void)
};
sigaction(35, &sa, NULL);
mmap_grow();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册