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.mzph.cn/bicheng/9367.shtml

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

相关文章

快速了解Vuex

Vuex Vuex使用Vuex Vuex &#x1f4cc;vuex 是一个专为 Vue.js 应用程序开发的状态管理库 &#x1f4cc;vuex 可以在多个组件之间共享数据&#xff0c;并且共享的数据是响应式的&#xff0c;即数据的变更能及时渲染到模板 &#x1f4cc;vuex 采用集中式存储管理所有组件的状态…

C++ 70. 爬楼梯

文章目录 一、题目描述二、参考代码 一、题目描述 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1 阶 1 阶2 阶 示例 2&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;3 解释&#xff1a;有三种方法可以爬到…

发表博客之:gemm/threadblock/threadblock_swizzle.h 文件夹讲解,cutlass深入讲解

文章目录 [发表博客之&#xff1a;gemm/threadblock/threadblock_swizzle.h 文件夹讲解&#xff0c;cutlass深入讲解](https://cyj666.blog.csdn.net/article/details/138514145)先来看一下最简单的struct GemmIdentityThreadblockSwizzle结构体 发表博客之&#xff1a;gemm/th…

InfiniGate自研网关实现四

13.服务发现组件搭建和注册网关连接 以封装 api-gateway-core 为目的&#xff0c;搭建 SpringBoot Starter 组件&#xff0c;用于服务注册发现的相关内容处理。 这里最大的目的在于搭建起用于封装网关算力服务的 api-gateway-core 系统&#xff0c;提供网关服务注册发现能力。…

【Python技术】使用akshare、pandas高效复盘每日涨停板行业分析

作为一个程序员宝爸&#xff0c;每天的时间很宝贵&#xff0c;工作之余除了辅导孩子作业&#xff0c;就是补充睡眠。 怎么快速高效的进行当天A股涨停板的复盘&#xff0c;便于第二天的跟踪。这里简单写个示例&#xff0c; 获取当天连涨数排序&#xff0c;以及所属行业排序。 …

ICode国际青少年编程竞赛- Python-2级训练场-迷宫

ICode国际青少年编程竞赛- Python-2级训练场-迷宫 1、 Dev.step(3) Dev.turnLeft() for i in range(2):Dev.step(4)Dev.turnRight() for i in range(2):Dev.step(2)Dev.turnLeft() Dev.step(3) Dev.step(-9)2、 Dev.step(3) Dev.turnRight() Dev.step(2) Dev.turnLeft() for i …

TCP及IP协议

TCP协议的传输是可靠的&#xff0c;而UDP协议的传输“尽力而为” TCP传输可靠性———确认&#xff0c;重传&#xff0c;排序&#xff0c;流控。 流控&#xff1a;滑动窗口机制 TTL--- 数据包每经过一个路由器的转发&#xff0c;他的TTL值将减1&#xff0c;当一个数据包中的T…

01-01-11

1、day11作业 使用的代码 #include<stdio.h> #include<stdlib.h> int main() {int i;//申请多大的空间scanf("%d", &i);char* p (char*)malloc(i);//不进行强制类型转换&#xff0c;会产生警告char c;scanf("%c", &c);//清空上面申请…

AutoDL服务器远程桌面

文章目录 1.安装VNC和必要的一些图形显式库:2.SSH隧道2.1.本地安装openssh服务器2.2.服务开启2.3.显示当前安装的 SSH 版本信息2.3.设置一个 SSH 隧道 注意3.VNC Viewer客户端登录4.测试5.参考 VNC&#xff08;Virtual Network Computing &#xff09;是一种图形化的桌面共享协…

【Vue3】新组件

Vue3新组件 Teleport 什么是Teleport&#xff1f;—— Teleport 是一种能够将我们的组件html结构移动到指定位置的技术。 <teleport tobody ><div class"modal" v-show"isShow"><h2>我是一个弹窗</h2><p>我是弹窗中的一些…

python实现背单词程序

欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.代码 三.使用 四.分析 一.前言 背单词是学习英语的一个重要环节,它有很多好处,以下是其中一些主要的好处: 提高词汇量

机器学习各个算法的优缺点!(下篇) 建议收藏。

上篇地址&#xff1a;机器学习各个算法的优缺点&#xff01;&#xff08;上篇&#xff09; 建议收藏。-CSDN博客 直接进入主题。 目录 6.降维算法 7.聚类算法 8.贝叶斯算法 9.人工神经网络 10.深度学习 谢谢观看。 6.降维算法 降维算法是一类用于减少数据维度的技术。 …

设计模式学习1

设计模式是什么&#xff1f; 设计模式是指在软件开发过程中&#xff0c;经过验证的&#xff0c;用于解决特定环境下&#xff0c;重复出现的&#xff0c;特定问题的解决方案。 也就是解决问题的固定套路&#xff0c;但也要慎用设计模式。 设计模式解决了什么问题&#xff1f;…

【C++风云录】重塑三维世界:植物学与生态系统建模

物理世界的模拟&#xff1a;植物科学的新工具 前言 在本文中&#xff0c;我们深入探讨了各种强大的库&#xff0c;包括PlantGL、ED2-Ent、Ogre3D、CGAL、Bullet Physics和OpenCV。这些库提供了一系列丰富的功能&#xff0c;从植物形态建模和生态系统研究&#xff0c;到三维图…

C++容器——stack

stack容器 C的std::stack容器是一个基于适配器模板类实现的容器适配器&#xff0c;它提供了一种后进先出的数据结构&#xff0c;即栈。 特点&#xff1a; 1.后进先出&#xff1a;元素在栈容器中按照后进先出的顺序管理&#xff0c;最后放入的元素将会最先被取出。 2.只能从栈…

10. hive中随机抽样数据:order by limit 对比 distribute by rand limit

文章目录 1. ORDER BY LIMIT2. DISTRIBUTE BY RAND() 配合 LIMIT考虑因素&#xff1a; 在Hive中随机抽取一部分数据时&#xff0c;选择使用 ORDER BY LIMIT 还是 DISTRIBUTE BY RAND() 配合 LIMIT 取决于具体的应用场景和需求。下面是两种方法的比较&#xff1a; 1. ORDER BY …

#01【面试问题整理】嵌入式软件工程师

前言 本系列文章预计应该也许可能大概会持续更新一段时间。笔者将整理网络上各个面试题目,在此系列中。如有错误可以私信、评论指正,多多包涵~谢谢~ 本期参考文章如下: 【八股文】嵌入式软件工程师-2025校招必备-详细整理_嵌入式软件开发八股-CSDN博客 1、 volatil…

面试前的刷题,要有充分的准备

大家面试前都会刷题背题,你是怎么背的?网上随便找找,背一背?找个大佬的博客或者视频,看一看,记一记?还是整理整理,发布到某个笔记上?又或者是自己写个博客,或者记录个印象笔记?这一节,我分享一些面试前刷题的心得体会。 目录 1 离职前的数据准备 2 离职前的面试题…

盲盒一番赏小程序:探索未知,开启神秘宝藏之旅

开启神秘之门&#xff0c;探索未知的乐趣 在繁忙的生活中&#xff0c;我们渴望一丝丝未知带来的惊喜与乐趣。盲盒一番赏小程序&#xff0c;正是为了满足您这种探索未知的欲望而诞生。它不仅仅是一个购物平台&#xff0c;更是一个充满神秘与惊喜的宝藏世界。 精选好物&#xf…

诊所医院超常规运营管理思维课程

本课程旨在引领医疗机构管理者超越传统思维&#xff0c;探索创新运营管理策略。学员将学习领先的医疗管理理念、创新的运营模式&#xff0c;以及如何应对挑战和变革。课程内容涵盖战略规划、资源优化、服务创新等&#xff0c;帮助管理者提升运营效率&#xff0c;提供更优质的医…