Nginx内存池--pool代码抽取(链表套路)

本文探讨了Nginx内存池中的ngx_palloc_large_hm实现,对比了与原版ngx_palloc_large的差异,并揭示了nginx在链表操作上的独特之处,包括前插和后插两种插入方式的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ngx_palloc.c文件

ngx_palloc_large_hm是自己写的代码没有nginx原版的ngx_palloc_large写的好,细节要品味才会发现nginx的美


nginx链表的套路,正好是两种插入“从前插”和“从后插”,有些许差别


#include <stdio.h>
#include <stdlib.h>

#define ITEM 20

#define u_char unsigned char
#define ngx_free          free

typedef struct ngx_pool_s        ngx_pool_t;
typedef intptr_t        ngx_int_t;
typedef uintptr_t       ngx_uint_t;
typedef struct ngx_pool_large_s  ngx_pool_large_t;

struct ngx_pool_large_s {
    ngx_pool_large_t     *next;
    void                 *alloc;
};

typedef struct {
	u_char *last;
	u_char *end;
	ngx_pool_t *next;
	ngx_uint_t   failed;
}ngx_pool_data_t;

struct ngx_pool_s{
	ngx_pool_data_t d;
	size_t max;
	ngx_pool_t *current;
	ngx_pool_large_t     *large;
};

typedef struct  
{  
    int a[10];  
} data_t; 
typedef struct  
{  
    int a[200];  
} data_s; 

ngx_pool_t *ngx_create_pool(size_t size);
void *ngx_palloc(ngx_pool_t *pool,size_t size);
static void *ngx_palloc_block(ngx_pool_t *pool,size_t size);
static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
static void *ngx_palloc_large_hm(ngx_pool_t *pool, size_t size);
ngx_pool_t *ngx_create_pool(size_t size)
{
	ngx_pool_t *p;
	p=(ngx_pool_t*)malloc(size);
	p->d.last=(u_char *)p+sizeof(ngx_pool_t);
	p->d.end=(u_char *)p+size;
	p->d.next = NULL;
	p->d.failed = 0;

	size = size - sizeof(ngx_pool_t);
	p->max =size;
	p->current = p;
	p->large = NULL;
	return p;
}

void *ngx_palloc(ngx_pool_t *pool,size_t size)
{
	u_char      *m;
    ngx_pool_t  *p;
	if (size <= pool->max){
		p = pool->current;
		do{
			m = p->d.last;
			if ((size_t) (p->d.end - m) >= size) {
				p->d.last=m+size;
				return m;
			}
			p = p->d.next;
		}while(p);
		return ngx_palloc_block(pool,size);
	}
	return ngx_palloc_large(pool,size);
}

static void* ngx_palloc_block(ngx_pool_t *pool,size_t size)
{
	u_char     *m;
	size_t       psize;
	ngx_pool_t *p,*neww, *current;

	psize = (size_t)(pool->d.end - (u_char *) pool);
	m=(u_char*)malloc(psize);
	neww=(ngx_pool_t *)m;

	neww->d.end=m+psize;
	neww->d.next = NULL;
	neww->d.failed = 0;
	m += sizeof(ngx_pool_data_t);
	neww->d.last=m+size;
	current = pool->current;
	for (p = current; p->d.next; p = p->d.next) {
        if (p->d.failed++ > 4) {
            current = p->d.next;
        }
    }
	p->d.next = neww;
	pool->current = current ? current : neww;
	return m;
}

//自己写的ngx_palloc_large  感觉没有nginx原版写的好 nginx写的是 新分配的大内存是紧挨着pool的
static void* ngx_palloc_large_hm(ngx_pool_t *pool, size_t size){
	ngx_pool_large_t *large,*neww;
	void     *m;
	
	large=pool->large;
	if(!large){
	large=malloc(sizeof(ngx_pool_large_t)+size);

	large->alloc=large+sizeof(ngx_pool_large_t);
	large->next=NULL;
	m=large->alloc;
	pool->large = large;
	return m;
	}
	while(large->next)
	{
		large=large->next;
	}

	neww=malloc(sizeof(ngx_pool_large_t)+size);
	neww->alloc=neww+sizeof(ngx_pool_large_t);
	neww->next=NULL;
	m=neww->alloc;
	large->next=neww;
	return m;
}

static void *
ngx_palloc_large(ngx_pool_t *pool, size_t size)
{
    void              *p;
    ngx_uint_t         n;
    ngx_pool_large_t  *large;

    p = malloc(size);
    if (p == NULL) {
        return NULL;
    }

    n = 0;

    for (large = pool->large; large; large = large->next) {
        if (large->alloc == NULL) {
            large->alloc = p;
            return p;
        }

        if (n++ > 3) {
            break;
        }
    }

    large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
    if (large == NULL) {
        ngx_free(p);
        return NULL;
    }

    large->alloc = p;
    large->next = pool->large;
    pool->large = large;

    return p;
}
int main()  {   
	data_t *p[ITEM]; 
	data_s *big1,*big2,*big3;
	ngx_pool_t *pool;
	int i;
	int k=257;
	pool=ngx_create_pool(128);

	for(i = 0; i < ITEM ;i++){
		p[i]=ngx_palloc(pool,sizeof(data_t));
		p[i]->a[0] = i; 
	}
	big1=ngx_palloc(pool,sizeof(data_s));
	big1->a[1]=1;
	big2=ngx_palloc(pool,sizeof(data_s));
	big2->a[2]=2;
	big3=ngx_palloc(pool,sizeof(data_s));
	big3->a[3]=3;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值