linux高性能服务器--Ngix内存池简单实现

文章目录

      • 内存模型:
      • 流程图
      • 内存对齐
      • code

内存模型:

在这里插入图片描述

流程图

在这里插入图片描述

内存对齐

对齐计算
要分配一个以指定大小对齐的内存,可以使用如下公式:
假设要分配大小为n,对齐方式为x,那么 size=(n+(x-1)) & (~(x-1))。
举个例子:
n=17,x=4。即申请大小为17,对齐为4。则计算出对齐后的大小应该为
(17+4-1)&(~(4-1))=20;

code

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>#include <fcntl.h>#define MP_ALIGNMENT       		32
#define MP_PAGE_SIZE			4096
#define MP_MAX_ALLOC_FROM_POOL	(MP_PAGE_SIZE-1)// 对齐
#define mp_align(n, alignment) (((n)+(alignment-1)) & ~(alignment-1))
#define mp_align_ptr(p, alignment) (void *)((((size_t)p)+(alignment-1)) & ~(alignment-1))typedef struct mp_large_s {struct mp_large_s *next;void *alloc;}mp_large_t;typedef struct mp_node_s {unsigned char *last; // last之前为已使用的内存unsigned char *end; // last到end之间为可分配内存struct mp_node_s *next;size_t failed;
}mp_node_t;typedef struct mp_pool_s {size_t max;mp_node_t* current;mp_large_t* large;mp_node_t head[0];}mp_pool_t;mp_pool_t *mp_create_pool(size_t size)
{mp_pool_t *p;// malloc无法分配超过4k的内存,size + sizeof(mp_pool_t) + sizeof(mp_node_s)保证有size大小可用int ret = posix_memalign((void*)&p, MP_ALIGNMENT, size + sizeof(mp_pool_t) + sizeof(mp_node_t));if (ret)return NULL;p->max = size;p->current = p->head;p->large = NULL;//(unsigned char*)(p + 1)// (unsigned char*)p + sizeof(mp_pool_t)p->head->last = (unsigned char*)p + sizeof(mp_pool_t)+sizeof(mp_node_t);p->head->end = p->head->last + size;p->head->failed = 0;return p;
}
void mp_destory_pool(mp_pool_t *pool) 
{mp_node_t *h, *n;mp_large_t *l;for (l = pool->large; l; l = l->next) {if (l->alloc) {free(l->alloc);}}h = pool->head->next;while (h) {n = h->next;free(h);h = n;}free(pool);
}void *mp_alloc_small(mp_pool_t *pool, size_t size)
{unsigned char *m;struct mp_node_s *h = pool->head;size_t psize = (size_t)(h->end - (unsigned char *)h);int ret = posix_memalign((void*)&m, MP_ALIGNMENT, psize);if (ret)return NULL;mp_node_t *p, *new_node, *current;new_node = (mp_node_t *)m;new_node->next = NULL;new_node->end = m + psize;new_node->failed = 0;m += sizeof(mp_node_t);m = mp_align_ptr(m, MP_ALIGNMENT);new_node->last += size;current = pool->current;for (p = current; p->next; p = p->next){// 如存在多次分配失败,current不再指向此nodeif (p->failed++ > 4){current = p->next;}}p->next = new_node;pool->current = current ? current : new_node;return m;
}static void *mp_alloc_large(mp_pool_t *pool, size_t size) 
{void *p = NULL;int ret = posix_memalign((void*)&p, MP_ALIGNMENT, size);if (ret)return NULL;mp_large_t *large;// 查找是否有已经释放的large,在large list里面找到一个 null的节点size_t n = 0;for (large = pool->large; large; large = large->next){if (large->alloc == NULL){large->alloc = p;return p;}// 避免遍历链条太长if (n++ > 3)break;}// 大内存块的头作为小块保存在small中large = mp_alloc_small(pool, sizeof(mp_large_t));// 头插法large->alloc = p;large->next = pool->large;pool->large = large;
}void *mp_malloc(mp_pool_t *pool, size_t size)
{if (size > pool->max)return mp_alloc_large(pool, size);mp_node_t *p = pool->current;while (p){if (p->end - p->last < size){p = p->next;continue;}unsigned char *m = mp_align_ptr(p->last, MP_ALIGNMENT);p->last = m + size;return m;}return mp_alloc_small(pool, size);
}void *mp_calloc(mp_pool_t *pool, size_t size) 
{void *p = mp_malloc(pool, size);if (p) {memset(p, 0, size);}return p;}
void mp_free(mp_pool_t *pool, void *p)
{mp_large_t *l;for (l = pool->large; l; l = l->next){if (p == l->alloc){free(l->alloc);l->alloc = NULL;return;}}
}void mp_reset_pool(mp_pool_t *pool) 
{mp_node_t *h;mp_large_t *l;for (l = pool->large; l; l = l->next) {if (l->alloc) {free(l->alloc);}}pool->large = NULL;for (h = pool->head; h; h = h->next) {h->last = (unsigned char *)h + sizeof(mp_node_t);}}/******************* TEST *********************/
int main(int argc, char *argv[]) {int size = 1 << 12;mp_pool_t *p = mp_create_pool(size);int i = 0;for (i = 0; i < 10; i++) {void *mp = mp_malloc(p, 512);//		mp_free(mp);}printf("mp_align(123, 32): %d, mp_align(17, 32): %d\n", mp_align(24, 32), mp_align(17, 32));int j = 0;for (i = 0; i < 5; i++) {char *pp = mp_calloc(p, 32);for (j = 0; j < 32; j++) {if (pp[j]) {printf("calloc wrong\n");}printf("calloc success\n");}}//printf("mp_reset_pool\n");for (i = 0; i < 5; i++) {void *l = mp_malloc(p, 8192);mp_free(p, l);}mp_reset_pool(p);//printf("mp_destory_pool\n");for (i = 0; i < 58; i++) {mp_malloc(p, 256);}mp_destory_pool(p);return 0;}

参考:
https://blog.csdn.net/Long_xu/article/details/126887578

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/317353.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【分布式通信】NPKit,NCCL的Profiling工具

NPKit介绍 NPKit (Networking Profiling Kit) is a profiling framework designed for popular collective communication libraries (CCLs), including Microsoft MSCCL, NVIDIA NCCL and AMD RCCL. It enables users to insert customized profiling events into different C…

26.统一网关Gateway

网关的功能 1.身份认证&#xff0c;权限的校验。 2.服务的路由&#xff0c;负载均衡。用户请求被分配到哪一个微服务。一个微服务可以有多个实例&#xff0c;所以使用负载均衡。 3.请求限流。 springcloud网关实现有两种&#xff1a;gateway, zuul zuul是基于servlet实现的…

随笔Ubuntu上的的一些使用

Ubuntu简易使用 常用指令 cdlsmkdirrf -rm 路径 换源 备份镜像 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak编辑文件设置 sudo gedit /etc/apt/sources.list清华源 # 阿里源 deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe mul…

数据仓库Data Warehouse

数据仓库Data Warehouse 数仓是一种思想,数仓是一种规范,数仓是一种解决方案 1. 数据处理方式 数据处理大致可以分成两大类: 联机事务处理OLTP(on-line transaction processing)联机分析处理OLAP(On-Line Analytical Processing)1.1. OLTP OLTP的全称是On-line Transa…

YOLO系列改进,自研模块助力涨点

目录 一、原理 二、代码 三、添加到YOLOv5中 一、原理 论文地址:

手机空号过滤,提高工作效率

手机空号过滤在多个方面都具有重要的作用。 首先&#xff0c;它对于短信群发商和电话营销商来说至关重要。通过空号过滤&#xff0c;他们可以确保手机号码数据库的准确性和有效性。由于每天都有大量人群因各种原因更换手机号码&#xff0c;导致每个号段中的空号率和手机状态都…

蓝桥杯如何准备国赛?

目录 一、赛前准备 1、如何刷题&#xff0c;刷哪些题&#xff1f; 2、记录&#xff08;主要看个人习惯&#xff09; CSDN博客 写注释 3、暴力骗分 4、从出题人的角度出发&#xff0c;应该如何骗分 二、赛中注意事项 一、赛前准备 1、如何刷题&#xff0c;刷哪些题&…

【算法刷题 | 贪心算法05】4.27(K次取反后最大化的数组和、加油站)

文章目录 8.K次取反后最大化的数组和8.1题目8.2解法&#xff1a;贪心8.2.1贪心思路8.2.2代码实现 9.加油站9.1题目9.2解法&#xff1a;贪心9.2.1贪心思路9.2.2代码实现 8.K次取反后最大化的数组和 8.1题目 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数…

制作github.io学术个人主页

制作如图的学术个人主页。About me - Xianwen Ling’s Blog 学术个人主页是一个学者展示个人学术成果和研究方向的重要工具。个人主页可以集中展示学者的研究论文、出版物、演讲和发布的项目等学术成果&#xff0c;这样其他人可以更方便地了解和评估学者的研究贡献。个人主页可…

Python | Leetcode Python题解之第60题排列序列

题目&#xff1a; 题解&#xff1a; class Solution:def getPermutation(self, n: int, k: int) -> str:factorial [1]for i in range(1, n):factorial.append(factorial[-1] * i)k - 1ans list()valid [1] * (n 1)for i in range(1, n 1):order k // factorial[n - …

c#数据库: 4.修改学生成绩

将4年级的学生成绩全部修改为100分,。修改前的学生信息表如图所示: using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks;namespace StudentUpdate {internal class Program{s…

Web后端开发中对三层架构解耦之控制反转与依赖注入

内聚与耦合 内聚 比如说我们刚刚书写的员工的实现类 在这里我们仅仅书写的是和员工相关的代码 而与员工无关的代码都没有放到这里 说明内聚程度较高 耦合 以后软件开发要高内聚 低耦合 提高程序灵活性 扩拓展性 分析代码 如何解耦 创建容器 提供一个容器 存储东西 存储E…

【图论】图论基础

图论不同地方讲的不太一样&#xff0c;本文仅限作者的理解 定义 图一般由点集 V V V 和边集 E E E 组成。 对于 v ∈ V v\in V v∈V&#xff0c;称 v v v 为该图的一个节点。 对于 e ∈ E e\in E e∈E&#xff0c;一般用二元组 ( u , v ) (u,v) (u,v) 表示 e e e&…

VS2022 .Net6.0 无法打开窗体设计器

拿Vs2022 建了个Demo&#xff0c;运行环境是net6.0-windows&#xff0c;无论双击或是右键都打不开窗体设计器 打开项目目录下的*.csproj.user <?xml version"1.0" encoding"utf-8"?> <Project ToolsVersion"Current" xmlns"htt…

2024年第二十一届 五一杯 (B题)大学生数学建模挑战赛 | 最大流问题,深度学习分析 | 数学建模完整代码解析

DeepVisionary 每日深度学习前沿科技推送&顶会论文&数学建模与科技信息前沿资讯分享&#xff0c;与你一起了解前沿科技知识&#xff01; 本次DeepVisionary带来的是五一杯的详细解读&#xff1a; 完整内容可以在文章末尾全文免费领取&阅读&#xff01; 第一个问题…

[高质量]2024五一数学建模A题保奖思路+代码(后续会更新)

你的点赞收藏是我继续更新的最大动力&#xff0c;可点击文末卡片获取更多资料 你是否在寻找数学建模比赛的突破点&#xff1f; 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024 年华东杯&#xff08;A题&#xff09;的全面解析包。这个解决方案包不仅包括完整的代…

实习面试算法准备之图论

这里写目录标题 1 基础内容1.1 图的表示1.2图的遍历 2 例题2.1 所有可能的路径2.2 课程表&#xff08;环检测算法&#xff09;2.2.1 环检测算法 DFS版2.2.2 环检测算法 BFS版 2.3 课程表 II &#xff08;拓扑排序算法&#xff09;2.3.1 拓扑排序 DFS版 1 基础内容 图没啥高深的…

百度安全多篇议题入选Blackhat Asia以硬技术发现“芯”问题

Blackhat Asia 2024于4月中旬在新加坡隆重举行。此次大会聚集了业界最杰出的信息安全专业人士和研究者&#xff0c;为参会人员提供了安全领域最新的研究成果和发展趋势。在本次大会上&#xff0c;百度安全共有三篇技术议题被大会收录&#xff0c;主要围绕自动驾驶控制器安全、跨…

IDEA实现Springboot项目自动热部署

每当我们在修改代码时&#xff0c;往往需要重新启动项目&#xff0c;这样不仅浪费时间而且很麻烦&#xff0c;我们可以通过IDEA的热部署来提高效率 1、首先点file >> settings >> Build Excution >> Compire&#xff0c;选择Build project auto matically 2.…

有关CSS中排版常见问题(清除默认样式问题 + 元素居中问题 + 元素之间的空白问题 + 行内块的幽灵空白问题)

前言&#xff1a;在练习CSS排版的时候&#xff0c;我们经常会遇到一些排版上的问题&#xff0c;那么我们如何去解决这些问题呢&#xff1f;本篇文章给出了一些新手在练习排版时候可能会遇到的问题的解决方案。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我…