水平有限,描述不当之处还请指出,转载请注明出处http://blog.csdn.net/vanbreaker/article/details/7705792

slob释放对象由函数slob_free()来完成,分为三种情况进行处理:

  • slob中已有的空闲单元加上释放对象块的空闲单元正好等于一个空闲的page,那么将直接将该page释放回伙伴系统
  • slob中已无空闲单元,那么这次释放将更新slob的信息
  • 普通情况,即slob处于部分满状态,那么更新slob的信息的同时还要将释放的块插入到相应的位置,要注意插入后是否能和相邻块进行合并!

下面来看具体的代码

[cpp] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 12px">/*
  2. * slob_free: entry point into the slob allocator.
  3. */
  4. static void slob_free(void *block, int size)
  5. {
  6. struct slob_page *sp;
  7. slob_t *prev, *next, *b = (slob_t *)block;
  8. slobidx_t units;
  9. unsigned long flags;
  10. if (unlikely(ZERO_OR_NULL_PTR(block)))
  11. return;
  12. BUG_ON(!size);
  13. sp = slob_page(block);//获取slob地址
  14. units = SLOB_UNITS(size);//计算释放的单元数
  15. spin_lock_irqsave(&slob_lock, flags);
  16. /*slob剩余的单元数加上待释放的单元数正好等于一个slob本有的总单元数,
  17. 直接将slob占用的页框释放回伙伴系统*/
  18. if (sp->units + units == SLOB_UNITS(PAGE_SIZE)) {
  19. /* Go directly to page allocator. Do not pass slob allocator */
  20. if (slob_page_free(sp))
  21. clear_slob_page_free(sp);
  22. spin_unlock_irqrestore(&slob_lock, flags);
  23. clear_slob_page(sp);
  24. free_slob_page(sp);
  25. slob_free_pages(b, 0);
  26. return;
  27. }
  28. if (!slob_page_free(sp)) {//slob没有空闲块
  29. /* This slob page is about to become partially free. Easy! */
  30. sp->units = units;//设置slob的单元数为释放对象的单元数
  31. sp->free = b;//设置首对象为释放对象
  32. set_slob(b, units,//最后一个对象的空闲对象设置为下一个页的首个单元
  33. (void *)((unsigned long)(b +
  34. SLOB_UNITS(PAGE_SIZE)) & PAGE_MASK));
  35. set_slob_page_free(sp, &free_slob_small);//将slob链入free_slob_small链表
  36. goto out;
  37. }
  38. /*
  39. * Otherwise the page is already partially free, so find reinsertion
  40. * point.
  41. */
  42. sp->units += units;//空闲单元总数增加units
  43. if (b < sp->free) {//待释放块的地址小于sp->free
  44. if (b + units == sp->free) {//可以合并
  45. units += slob_units(sp->free);
  46. sp->free = slob_next(sp->free);//取free的下一个空闲对象作为free
  47. }
  48. /*将释放块插入在free前面,并将其作为首个空闲块赋给free*/
  49. set_slob(b, units, sp->free);
  50. sp->free = b;
  51. else {
  52. prev = sp->free;//取首个空闲块
  53. next = slob_next(prev);//取第二个空闲块
  54. while (b > next) {//扫描至待释放块处
  55. prev = next;
  56. next = slob_next(prev);
  57. }
  58. /*将b插在prev和next中间,prev-->b-->next,要考虑是否能够合并*/
  59. /*如果prev不是最后一个空闲块并且b可以和next合并,则进行合并*/
  60. if (!slob_last(prev) && b + units == next) {
  61. units += slob_units(next);
  62. set_slob(b, units, slob_next(next));
  63. else//否则将b插入在next前面
  64. set_slob(b, units, next);
  65. if (prev + slob_units(prev) == b) {//如果prev可以和b合并,则进行合并
  66. units = slob_units(b) + slob_units(prev);
  67. set_slob(prev, units, slob_next(b));
  68. else//否则,将b插在prev后面
  69. set_slob(prev, slob_units(prev), b);
  70. }
  71. out:
  72. spin_unlock_irqrestore(&slob_lock, flags);
  73. }
  74. </SPAN>
<span style="font-size:12px;">/*
* slob_free: entry point into the slob allocator.
*/
static void slob_free(void *block, int size)
{
struct slob_page *sp;
slob_t *prev, *next, *b = (slob_t *)block;
slobidx_t units;
unsigned long flags;
if (unlikely(ZERO_OR_NULL_PTR(block)))
return;
BUG_ON(!size);
sp = slob_page(block);//获取slob地址
units = SLOB_UNITS(size);//计算释放的单元数
spin_lock_irqsave(&slob_lock, flags);
/*slob剩余的单元数加上待释放的单元数正好等于一个slob本有的总单元数,
直接将slob占用的页框释放回伙伴系统*/
if (sp->units + units == SLOB_UNITS(PAGE_SIZE)) {
/* Go directly to page allocator. Do not pass slob allocator */
if (slob_page_free(sp))
clear_slob_page_free(sp);
spin_unlock_irqrestore(&slob_lock, flags);
clear_slob_page(sp);
free_slob_page(sp);
slob_free_pages(b, 0);
return;
}
if (!slob_page_free(sp)) {//slob没有空闲块
/* This slob page is about to become partially free. Easy! */
sp->units = units;//设置slob的单元数为释放对象的单元数
sp->free = b;//设置首对象为释放对象
set_slob(b, units,//最后一个对象的空闲对象设置为下一个页的首个单元
(void *)((unsigned long)(b +
SLOB_UNITS(PAGE_SIZE)) & PAGE_MASK));
set_slob_page_free(sp, &free_slob_small);//将slob链入free_slob_small链表
goto out;
}
/*
* Otherwise the page is already partially free, so find reinsertion
* point.
*/
sp->units += units;//空闲单元总数增加units
if (b < sp->free) {//待释放块的地址小于sp->free
if (b + units == sp->free) {//可以合并
units += slob_units(sp->free);
sp->free = slob_next(sp->free);//取free的下一个空闲对象作为free
}
/*将释放块插入在free前面,并将其作为首个空闲块赋给free*/
set_slob(b, units, sp->free);
sp->free = b;
} else {
prev = sp->free;//取首个空闲块
next = slob_next(prev);//取第二个空闲块
while (b > next) {//扫描至待释放块处
prev = next;
next = slob_next(prev);
}
/*将b插在prev和next中间,prev-->b-->next,要考虑是否能够合并*/
/*如果prev不是最后一个空闲块并且b可以和next合并,则进行合并*/
if (!slob_last(prev) && b + units == next) {
units += slob_units(next);
set_slob(b, units, slob_next(next));
} else//否则将b插入在next前面
set_slob(b, units, next);
if (prev + slob_units(prev) == b) {//如果prev可以和b合并,则进行合并
units = slob_units(b) + slob_units(prev);
set_slob(prev, units, slob_next(b));
} else//否则,将b插在prev后面
set_slob(prev, slob_units(prev), b);
}
out:
spin_unlock_irqrestore(&slob_lock, flags);
}
</span>

Linux Slob分配器(三)--释放对象相关推荐

  1. Linux Slob分配器(二)--分配对象

    each 水平有限,描述不当之处还请指出,转载请注明出处http://blog.csdn.net/vanbreaker/article/details/7705559 上节介绍了Slob分配器的相关概 ...

  2. Linux Slob分配器(一)--概述

    水平有限,描述不当之处还请指出,转载请注明出处 http://blog.csdn.net/vanbreaker/article/details/7705202 Slob分配器相较Slab和Slub分配 ...

  3. LINUX内核狂想曲之SLOB分配器

    LINUX内核狂想曲 @CopyLeft by ICANTH,I Can do ANy THing that I CAN THink!~ Author: WenHui, WuHan Universit ...

  4. Linux slab 分配器剖析

    简介: 良好的操作系统性能部分依赖于操作系统有效管理资源的能力.在过去,堆内存管理器是实际的规范,但是其性能会 受到内存碎片和内存回收需求的影响.现在,Linux® 内核使用了源自于 Solaris ...

  5. linux slub分配器浅析

    在<linux内存管理浅析>中提到内核管理自己使用的内存时,使用了SLAB对象池.SLAB确实是比较复杂,所以一直以来都没有深入看一看. 不过现在,linux内核中,SLAB已经被它的简化 ...

  6. (转)Linux SLUB 分配器详解

    原文网址:https://www.ibm.com/developerworks/cn/linux/l-cn-slub/ 多年以来,Linux 内核使用一种称为 SLAB 的内核对象缓冲区分配器.但是, ...

  7. linux slub分配器,slub分配器

    原标题:slub分配器 概述: Linux的物理内存管理采用了以页为单位的buddy system(伙伴系统),但是很多情况下,内核仅仅需要一个较小的对象空间,而且这些小块的空间对于不同对象又是变化的 ...

  8. Linux设备驱动程序 三 字符设备驱动

    Linux设备驱动程序 三 字符设备驱动 笔记 第三章 字符驱动设备 本章会编写一个完整的字符设备,字符设备简单,易于理解, 名字是scull:Simple Caracter Utility for ...

  9. linux Slob内存管理小析

    Slob分配对象大小是从三个链中选择的 static LIST_HEAD(free_slob_small); static LIST_HEAD(free_slob_medium); static LI ...

最新文章

  1. 敏捷开发中Scrum方法
  2. 项目视频光盘项目中所学概览-html5+批处理+bat转exe
  3. UA MATH563 概率论的数学基础 鞅论初步6 鞅的性质 鞅差序列
  4. JVM的垃圾回收与内存分配
  5. [android网络有效性检测] NetworkMonitor代码造成内存泄漏
  6. 对数据可视化的理解_使数据可视化更容易理解
  7. [vue] 你有使用过JSX吗?说说你对JSX的理解
  8. Gentoo Linux: /var/db/pkg 这个文件夹很重要![转]推荐阅读
  9. linux mysql优化_Linux上跑MySQL优化技巧
  10. 《重构 改善既有代码的设计》笔记
  11. 计算机命令秒退,win10打开命令提示符闪退怎么办-解决win10命令提示符闪退的方法 - 河东软件园...
  12. 财务软件服务器装什么系统,财务软件用哪种云服务器
  13. python for ArcGIS 绘制武汉市板块地图
  14. 解决Iphonex 底部按钮fixed,bottom:0 底部留白问题
  15. 损失函数MSE和MAE的区别以及如何选择
  16. 如何用计算机计算概率,概率计算器与阶乘方程
  17. 不要随便借出你的帐号
  18. Java中带有T Z格式(UTC是世界标准时间)的时间转换为date,string,long类型
  19. 用python写爬虫(一)初识爬虫
  20. 水瓶座名人既水瓶座概论

热门文章

  1. 【论文】RAPiD: Rotation-Aware People Detection in Overhead Fisheye Images
  2. 统计各个部门员工薪水总和 Hadoop
  3. 微擎支付提示下单用户不一致,授权快照移除
  4. 基于STM32按键的防抖和松开处理:状态机
  5. 树莓派接手机屏幕_视频详解树莓派如何外接Kindle显示器
  6. [CISCN 2019华东南]Double Secret
  7. iOS国际化之app内切换语言
  8. android 手机网络设置,手机网络怎么设置 史上最详细的手机网络设置教程
  9. 小程序实现购物车商品飞入效果-贝塞尔曲线动画
  10. 中证快讯实时更新提醒以及按关键词过滤的实现